diff --git a/CHANGELOG b/CHANGELOG index c426be0e5..370ef07ac 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,15 +1,25 @@ -------------------------------------------------------------------------------- Changes in version 6.1.0 -------------------------------------------------------------------------------- -- merge changes up to 6.0.9 +- merge changes up to 6.0.10 - add attribute groups and selective output of attributes - add support for WebAuthn - do not use md5 password hashing anymore, hashes will be updated automatically when passwords are reset +-------------------------------------------------------------------------------- + Changes in version 6.0.10 +-------------------------------------------------------------------------------- +- merge changes up to 5.1.17 +- fix list of previous document versions (Closes: #471) +- fix uploading files with fine uploader (Closes: #472) +- clear revision date when all revisors have been deleted +- improve scheduler task management, tasks can be deleted, fix setting parameters + -------------------------------------------------------------------------------- Changes in version 6.0.9 -------------------------------------------------------------------------------- +- merge changes up to 5.1.16 - fix removal of roles (Closes: #465) - fix password forgotten process - fix setting role of new user and retrieving role of existing user @@ -147,6 +157,19 @@ - add document list which can be exported as an archive - search results can be exported +-------------------------------------------------------------------------------- + Changes in version 5.1.17 +-------------------------------------------------------------------------------- +- new version 5.16.2 of fine uploader +- obey max_upload_size whenever a file is uploaded +- do not list documents in task list, if a previous version is still in workflow. + Take only the lastest version into account (Closes: #405) +- fix moving documents in clipboard into folder by drag&drop +- clipboard can be pinned to fixed position +- use standard output for document rows on MyDocuments page +- new seeddms logo +- fix moving clipboard (Closes: #473) + -------------------------------------------------------------------------------- Changes in version 5.1.16 -------------------------------------------------------------------------------- diff --git a/SeedDMS_Core/Core/inc.ClassDMS.php b/SeedDMS_Core/Core/inc.ClassDMS.php index 9c0f9bbc4..343093bb4 100644 --- a/SeedDMS_Core/Core/inc.ClassDMS.php +++ b/SeedDMS_Core/Core/inc.ClassDMS.php @@ -906,7 +906,7 @@ class SeedDMS_Core_DMS { foreach($tmp as $group) $groups[] = $group->getID(); } - $selectStr = "SELECT count(*) c "; + $selectStr = "count(distinct ttcontentid.document) c "; $queryStr = "FROM `ttcontentid` ". "LEFT JOIN `tblDocumentStatus` ON `tblDocumentStatus`.`documentID`=`ttcontentid`.`document` AND `tblDocumentStatus`.`version`=`ttcontentid`.`maxVersion` ". @@ -938,10 +938,12 @@ class SeedDMS_Core_DMS { "LEFT JOIN `ttapproveid` ON `ttapproveid`.`approveID` = `tblDocumentApprovers`.`approveID` ". "LEFT JOIN `tblDocumentApproveLog` ON `tblDocumentApproveLog`.`approveLogID`=`ttapproveid`.`maxLogID` "; - $queryStr .= "WHERE (`tblDocumentApprovers`.`type` = 0 AND `tblDocumentApprovers`.`required` = ".$user->getID()." "; - if($groups) - $queryStr .= "OR `tblDocumentApprovers`.`type` = 1 AND `tblDocumentApprovers`.`required` IN (".implode(',', $groups).") "; - $queryStr .= ") "; + if($user) { + $queryStr .= "WHERE (`tblDocumentApprovers`.`type` = 0 AND `tblDocumentApprovers`.`required` = ".$user->getID()." "; + if($groups) + $queryStr .= "OR `tblDocumentApprovers`.`type` = 1 AND `tblDocumentApprovers`.`required` IN (".implode(',', $groups).") "; + $queryStr .= ") "; + } $queryStr .= "AND `tblDocumentApproveLog`.`status` = 0 "; $queryStr .= "AND `tblDocumentStatusLog`.`status` IN (".S_DRAFT_APP.", ".S_EXPIRED.") "; break; /* }}} */ @@ -954,10 +956,12 @@ class SeedDMS_Core_DMS { "LEFT JOIN `ttreceiptid` ON `ttreceiptid`.`receiptID` = `tblDocumentRecipients`.`receiptID` ". "LEFT JOIN `tblDocumentReceiptLog` ON `tblDocumentReceiptLog`.`receiptLogID`=`ttreceiptid`.`maxLogID` "; - $queryStr .= "WHERE (`tblDocumentRecipients`.`type` = 0 AND `tblDocumentRecipients`.`required` = ".$user->getID()." "; - if($groups) - $queryStr .= "OR `tblDocumentRecipients`.`type` = 1 AND `tblDocumentRecipients`.`required` IN (".implode(',', $groups).") "; - $queryStr .= ") "; + if($user) { + $queryStr .= "WHERE (`tblDocumentRecipients`.`type` = 0 AND `tblDocumentRecipients`.`required` = ".$user->getID()." "; + if($groups) + $queryStr .= "OR `tblDocumentRecipients`.`type` = 1 AND `tblDocumentRecipients`.`required` IN (".implode(',', $groups).") "; + $queryStr .= ") "; + } $queryStr .= "AND `tblDocumentReceiptLog`.`status` = 0 "; $queryStr .= "AND `tblDocumentStatusLog`.`status` IN (".S_RELEASED.") "; break; /* }}} */ @@ -970,51 +974,40 @@ class SeedDMS_Core_DMS { "LEFT JOIN `ttrevisionid` ON `ttrevisionid`.`revisionID` = `tblDocumentRevisors`.`revisionID` ". "LEFT JOIN `tblDocumentRevisionLog` ON `tblDocumentRevisionLog`.`revisionLogID`=`ttrevisionid`.`maxLogID` "; - $queryStr .= "WHERE (`tblDocumentRevisors`.`type` = 0 AND `tblDocumentRevisors`.`required` = ".$user->getID()." "; - if($groups) - $queryStr .= "OR `tblDocumentRevisors`.`type` = 1 AND `tblDocumentRevisors`.`required` IN (".implode(',', $groups).") "; - $queryStr .= ") "; + if($user) { + $queryStr .= "WHERE (`tblDocumentRevisors`.`type` = 0 AND `tblDocumentRevisors`.`required` = ".$user->getID()." "; + if($groups) + $queryStr .= "OR `tblDocumentRevisors`.`type` = 1 AND `tblDocumentRevisors`.`required` IN (".implode(',', $groups).") "; + $queryStr .= ") "; + } $queryStr .= "AND `tblDocumentRevisionLog`.`status` = 0 "; $queryStr .= "AND `tblDocumentStatusLog`.`status` IN (".S_IN_REVISION.") "; break; /* }}} */ - case 'NeedsCorrectionOwner': + case 'NeedsCorrectionOwner': // Documents that need to be corrected {{{ $queryStr .= "LEFT JOIN `tblDocuments` ON `tblDocuments`.`id` = `ttcontentid`.`document` "; $queryStr .= "WHERE `tblDocuments`.`owner` = '".$user->getID()."' ". "AND `tblDocumentStatusLog`.`status` IN (".S_NEEDS_CORRECTION.") "; break; /* }}} */ - case 'WorkflowByMe': - // Get document list for the current user. - $workflowStatus = $user->getWorkflowStatus(); + case 'WorkflowByMe': // Documents which need my workflow action {{{ - // Create a comma separated list of all the documentIDs whose information is - // required. - $dList = array(); - foreach ($workflowStatus["u"] as $st) { - if (!in_array($st["document"], $dList)) { - $dList[] = $st["document"]; - } - } - foreach ($workflowStatus["g"] as $st) { - if (!in_array($st["document"], $dList)) { - $dList[] = $st["document"]; - } - } - $docCSV = ""; - foreach ($dList as $d) { - $docCSV .= (strlen($docCSV)==0 ? "" : ", ")."'".$d."'"; - } + $queryStr .= + "LEFT JOIN `tblWorkflowDocumentContent` on `ttcontentid`.`document`=`tblWorkflowDocumentContent`.`document` AND `ttcontentid`.`maxVersion`=`tblWorkflowDocumentContent`.`version` ". + "LEFT JOIN `tblWorkflowTransitions` on `tblWorkflowDocumentContent`.`workflow`=`tblWorkflowTransitions`.`workflow` AND `tblWorkflowDocumentContent`.`state`=`tblWorkflowTransitions`.`state` ". + "LEFT JOIN `tblWorkflowTransitionUsers` on `tblWorkflowTransitionUsers`.`transition` = `tblWorkflowTransitions`.`id` ". + "LEFT JOIN `tblWorkflowTransitionGroups` on `tblWorkflowTransitionGroups`.`transition` = `tblWorkflowTransitions`.`id` "; - if ($dList) { - $queryStr .= - "WHERE `ttcontentid`.`document` IN (" . implode(',', $dList) . ")"; - } else { - $queryStr = ''; + if($user) { + $queryStr .= "WHERE (`tblWorkflowTransitionUsers`.`userid` = ".$user->getID()." "; + if($groups) + $queryStr .= "OR `tblWorkflowTransitionGroups`.`groupid` IN (".implode(',', $groups).")"; + $queryStr .= ") "; } - break; + $queryStr .= "AND `tblDocumentStatusLog`.`status` = ".S_IN_WORKFLOW." "; + break; // }}} } if($queryStr) { - $resArr = $this->db->getResultArray($selectStr.$queryStr); + $resArr = $this->db->getResultArray('SELECT '.$selectStr.$queryStr); if (is_bool($resArr) && !$resArr) { return false; } @@ -1064,8 +1057,8 @@ class SeedDMS_Core_DMS { * 'AppRevOwner', 'ReceiptByMe', 'ReviseByMe', 'LockedByMe', 'MyDocs' * @param SeedDMS_Core_User $param1 user * @param bool $param2 set to true - * if 'AppRevByMe', 'ReviseByMe', 'ReceiptByMe' shall return even documents - * І have already taken care of. + * if 'ReviewByMe', 'ApproveByMe', 'AppRevByMe', 'ReviseByMe', 'ReceiptByMe' + * shall return even documents І have already taken care of. * @param string $param3 sort list by this field * @param string $param4 order direction * @return array|bool @@ -1103,7 +1096,7 @@ class SeedDMS_Core_DMS { * It doesn't need the where clause anymore. Hence the statement could be * extended with further left joins. */ - $selectStr = "SELECT `tblDocuments`.*, `tblDocumentLocks`.`userID` as `lockUser`, ". + $selectStr = "`tblDocuments`.*, `tblDocumentLocks`.`userID` as `lockUser`, ". "`tblDocumentContent`.`version`, `tblDocumentStatus`.*, `tblDocumentStatusLog`.`status`, ". "`tblDocumentStatusLog`.`comment` AS `statusComment`, `tblDocumentStatusLog`.`date` as `statusDate`, ". "`tblDocumentStatusLog`.`userID`, `oTbl`.`fullName` AS `ownerName`, `sTbl`.`fullName` AS `statusName` "; @@ -1178,9 +1171,11 @@ class SeedDMS_Core_DMS { $orderdir = 'ASC'; $groups = array(); - $tmp = $user->getGroups(); - foreach($tmp as $group) - $groups[] = $group->getID(); + if($user) { + $tmp = $user->getGroups(); + foreach($tmp as $group) + $groups[] = $group->getID(); + } $selectStr .= ", `tblDocumentReviewLog`.`date` as `duedate` "; $queryStr .= @@ -1189,10 +1184,12 @@ class SeedDMS_Core_DMS { "LEFT JOIN `tblDocumentReviewLog` ON `tblDocumentReviewLog`.`reviewLogID`=`ttreviewid`.`maxLogID` "; if(1) { - $queryStr .= "WHERE (`tblDocumentReviewers`.`type` = 0 AND `tblDocumentReviewers`.`required` = ".$user->getID()." "; - if($groups) - $queryStr .= "OR `tblDocumentReviewers`.`type` = 1 AND `tblDocumentReviewers`.`required` IN (".implode(',', $groups).") "; - $queryStr .= ") "; + if($user) { + $queryStr .= "WHERE (`tblDocumentReviewers`.`type` = 0 AND `tblDocumentReviewers`.`required` = ".$user->getID()." "; + if($groups) + $queryStr .= "OR `tblDocumentReviewers`.`type` = 1 AND `tblDocumentReviewers`.`required` IN (".implode(',', $groups).") "; + $queryStr .= ") "; + } $queryStr .= "AND `tblDocumentStatusLog`.`status` IN (".S_DRAFT_REV.", ".S_EXPIRED.") "; if(!$param2) $queryStr .= " AND `tblDocumentReviewLog`.`status` = 0 "; @@ -1253,9 +1250,11 @@ class SeedDMS_Core_DMS { $orderdir = 'ASC'; $groups = array(); - $tmp = $user->getGroups(); - foreach($tmp as $group) - $groups[] = $group->getID(); + if($user) { + $tmp = $user->getGroups(); + foreach($tmp as $group) + $groups[] = $group->getID(); + } $selectStr .= ", `tblDocumentApproveLog`.`date` as `duedate` "; $queryStr .= @@ -1264,10 +1263,12 @@ class SeedDMS_Core_DMS { "LEFT JOIN `tblDocumentApproveLog` ON `tblDocumentApproveLog`.`approveLogID`=`ttapproveid`.`maxLogID` "; if(1) { + if($user) { $queryStr .= "WHERE (`tblDocumentApprovers`.`type` = 0 AND `tblDocumentApprovers`.`required` = ".$user->getID()." "; if($groups) $queryStr .= "OR `tblDocumentApprovers`.`type` = 1 AND `tblDocumentApprovers`.`required` IN (".implode(',', $groups).")"; $queryStr .= ") "; + } $queryStr .= "AND `tblDocumentStatusLog`.`status` IN (".S_DRAFT_APP.", ".S_EXPIRED.") "; if(!$param2) $queryStr .= " AND `tblDocumentApproveLog`.`status` = 0 "; @@ -1485,9 +1486,40 @@ class SeedDMS_Core_DMS { $queryStr .= ", `tblDocumentContent`.`revisiondate` ASC"; break; // }}} case 'WorkflowByMe': // Documents I to trigger in Worklflow {{{ - $queryStr .= "WHERE 1=1 "; - $user = $param1; + $orderby = $param3; + if($param4 == 'desc') + $orderdir = 'DESC'; + else + $orderdir = 'ASC'; + + if(1) { + $groups = array(); + if($user) { + $tmp = $user->getGroups(); + foreach($tmp as $group) + $groups[] = $group->getID(); + } + $selectStr = 'distinct '.$selectStr; + $queryStr .= + "LEFT JOIN `tblWorkflowDocumentContent` on `ttcontentid`.`document`=`tblWorkflowDocumentContent`.`document` AND `ttcontentid`.`maxVersion`=`tblWorkflowDocumentContent`.`version` ". + "LEFT JOIN `tblWorkflowTransitions` on `tblWorkflowDocumentContent`.`workflow`=`tblWorkflowTransitions`.`workflow` AND `tblWorkflowDocumentContent`.`state`=`tblWorkflowTransitions`.`state` ". + "LEFT JOIN `tblWorkflowTransitionUsers` on `tblWorkflowTransitionUsers`.`transition` = `tblWorkflowTransitions`.`id` ". + "LEFT JOIN `tblWorkflowTransitionGroups` on `tblWorkflowTransitionGroups`.`transition` = `tblWorkflowTransitions`.`id` "; + + if($user) { + $queryStr .= "WHERE (`tblWorkflowTransitionUsers`.`userid` = ".$user->getID()." "; + if($groups) + $queryStr .= "OR `tblWorkflowTransitionGroups`.`groupid` IN (".implode(',', $groups).")"; + $queryStr .= ") "; + } + $queryStr .= "AND `tblDocumentStatusLog`.`status` = ".S_IN_WORKFLOW." "; +// echo 'SELECT '.$selectStr." ".$queryStr; + if ($orderby=='e') $queryStr .= "ORDER BY `expires`"; + else if ($orderby=='u') $queryStr .= "ORDER BY `statusDate`"; + else $queryStr .= "ORDER BY `name`"; + } else { + $queryStr .= "WHERE 1=1 "; // Get document list for the current user. $workflowStatus = $user->getWorkflowStatus(); @@ -1517,6 +1549,7 @@ class SeedDMS_Core_DMS { } else { $queryStr = ''; } + } break; // }}} case 'AppRevOwner': // Documents waiting for review/approval/revision I'm owning {{{ $queryStr .= "WHERE 1=1 "; @@ -1806,7 +1839,7 @@ class SeedDMS_Core_DMS { } if($queryStr) { - $resArr = $this->db->getResultArray($selectStr.$queryStr); + $resArr = $this->db->getResultArray('SELECT '.$selectStr.$queryStr); if (is_bool($resArr) && !$resArr) { return false; } diff --git a/SeedDMS_Core/Core/inc.ClassDocument.php b/SeedDMS_Core/Core/inc.ClassDocument.php index 025018690..3f05be2e0 100644 --- a/SeedDMS_Core/Core/inc.ClassDocument.php +++ b/SeedDMS_Core/Core/inc.ClassDocument.php @@ -879,10 +879,13 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ * Check if latest content of the document has a scheduled * revision workflow. * The method will update the document status log database table - * if needed. + * if needed and set the revisiondate of the content to $next. * * FIXME: This method does not check if there are any revisors left. Even * if all revisors have been removed, it will still start the revision workflow! + * NOTE: This seems not the case anymore. The status of each revision is + * checked. Only if at least one status is S_LOG_SLEEPING the revision will be + * started. This wouldn't be the case if all revisors had been removed. * * @param object $user user requesting the possible automatic change * @param string $next next date for review @@ -3321,7 +3324,10 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ else $this->setStatus($initialstatus,$msg,$user); } elseif($st["status"]==S_IN_REVISION) { if($needsCorrection) $this->setStatus(S_NEEDS_CORRECTION,$msg,$user); - else $this->setStatus(S_RELEASED,$msg,$user); + else { + $this->finishRevision($user, S_RELEASED, 'Finished revision workflow', $msg); + // $this->setStatus(S_RELEASED,$msg,$user); + } } elseif($st["status"]==S_EXPIRED) { $this->setStatus(S_RELEASED,$msg,$user); } @@ -3670,21 +3676,31 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ $ddate = $db->qstr($date); else $ddate = $db->getCurrentDatetime(); + $db->startTransaction(); $queryStr = "INSERT INTO `tblDocumentStatusLog` (`statusID`, `status`, `comment`, `date`, `userID`) ". "VALUES ('". $this->_status["statusID"] ."', '". (int) $status ."', ".$db->qstr($comment).", ".$ddate.", '". $updateUser->getID() ."')"; $res = $db->getResult($queryStr); - if (is_bool($res) && !$res) + if (is_bool($res) && !$res) { + $db->rollbackTransaction(); return false; + } /* Check if 'onSetStatus' callback is set */ if(isset($this->_dms->callbacks['onSetStatus'])) { foreach($this->_dms->callbacks['onSetStatus'] as $callback) { - $ret = call_user_func($callback[0], $callback[1], $this, $this->_status["status"], $status); - if(is_bool($ret)) + $ret = call_user_func($callback[0], $callback[1], $this, $updateUser, $this->_status["status"], $status); + if(is_bool($ret)) { + unset($this->_status); + if($ret) + $db->commitTransaction(); + else + $db->rollbackTransaction(); return $ret; + } } } + $db->commitTransaction(); unset($this->_status); return true; } /* }}} */ @@ -5495,7 +5511,10 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ if ($indstatus["status"] != S_LOG_WAITING && $indstatus["status"] != S_LOG_SLEEPING) { // User has already submitted a revision or has already been deleted; // return an error. - return -3; + if($indstatus["status"] == S_LOG_USER_REMOVED) + return -3; + else + return -4; } $queryStr = "INSERT INTO `tblDocumentRevisionLog` (`revisionID`, `status`, `comment`, `date`, `userID`) ". diff --git a/SeedDMS_Core/package.xml b/SeedDMS_Core/package.xml index 7b44c5935..0340e9a8d 100644 --- a/SeedDMS_Core/package.xml +++ b/SeedDMS_Core/package.xml @@ -12,11 +12,11 @@ uwe@steinmann.cx yes - 2020-04-14 + 2020-05-14 09:43:12 - 6.0.9 - 6.0.9 + 6.0.10 + 6.0.10 stable @@ -24,7 +24,7 @@ GPL License -- no changes, just keep same version as seeddms application +SeedDMS_Core_DocumentContent::delRevisor() returns -4 if user has already made a revision @@ -1748,7 +1748,7 @@ add method SeedDMS_Core_DatabaseAccess::setLogFp() - 2020-04-02 + 2020-04-14 09:43:12 5.1.16 @@ -1797,6 +1797,22 @@ log entry first - add new method SeedDMS_Core_DMS::getDocumentsExpired() + + 2020-05-14 + 09:43:12 + + 5.1.17 + 5.1.17 + + + stable + stable + + GPL License + +- add new callback onSetStatus + + 2017-05-28 06:34:50 @@ -1949,6 +1965,22 @@ remove a user from all its process can also be used to set a new user GPL License +- no changes, just keep same version as seeddms application + + + + 2020-05-14 + 09:43:12 + + 6.0.9 + 6.0.9 + + + stable + stable + + GPL License + - no changes, just keep same version as seeddms application diff --git a/ext/example/class.example.php b/ext/example/class.example.php index 5ae864f1e..c2dc22964 100644 --- a/ext/example/class.example.php +++ b/ext/example/class.example.php @@ -186,7 +186,7 @@ class SeedDMS_ExtExample_Task extends SeedDMS_SchedulerTaskBase { * @param $dms dms * @return boolean true if task was executed succesfully, otherwise false */ - public function execute($task, $dms) { + public function execute($task, $dms, $user) { $taskparams = $task->getParameter(); return true; } diff --git a/inc/inc.ClassExtensionMgr.php b/inc/inc.ClassExtensionMgr.php index 010d88eae..7a56771b0 100644 --- a/inc/inc.ClassExtensionMgr.php +++ b/inc/inc.ClassExtensionMgr.php @@ -583,7 +583,7 @@ class SeedDMS_Extension_Mgr { public function updateExtensionList($version='', $force=false) { /* {{{ */ if($this->reposurl) { if(!file_exists($this->cachedir."/".self::repos_list_file) || $force) { - if($file = @file_get_contents($this->reposurl.($version ? '?seeddms_version='.$version : ''), false, $this->getStreamContext())) { + if(false !== ($file = @file_get_contents($this->reposurl.($version ? '?seeddms_version='.$version : ''), false, $this->getStreamContext()))) { if(is_array($http_response_header)) { $parts=explode(' ',$http_response_header[0]); if(count($parts)>1) //HTTP/1.0 @@ -592,6 +592,10 @@ class SeedDMS_Extension_Mgr { return false; } } + if(!$file) { + $this->errmsgs[] = 'Extension list is empty'; + return false; + } file_put_contents($this->cachedir."/".self::repos_list_file, $file); } else { return false; diff --git a/inc/inc.ClassSchedulerTask.php b/inc/inc.ClassSchedulerTask.php index 45017dbc3..f9caf2af2 100644 --- a/inc/inc.ClassSchedulerTask.php +++ b/inc/inc.ClassSchedulerTask.php @@ -232,14 +232,14 @@ class SeedDMS_SchedulerTask { if (!$res) return false; - $this->_disabled = $newDisable; + $this->_disabled = $newDisabled; return true; } /* }}} */ public function setParameter($newParams) { /* {{{ */ $db = $this->db; - $queryStr = "UPDATE `tblSchedulerTask` SET `parameter` =".json_encode($newParams)." WHERE `id` = " . $this->_id; + $queryStr = "UPDATE `tblSchedulerTask` SET `params` =".$db->qstr(json_encode($newParams))." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -248,7 +248,9 @@ class SeedDMS_SchedulerTask { return true; } /* }}} */ - public function getParameter() { + public function getParameter($name = '') { + if($name) + return isset($this->_params[$name]) ? $this->_params[$name] : null; return $this->_params; } @@ -275,4 +277,21 @@ class SeedDMS_SchedulerTask { $this->_lastrun = $lastrun; $this->_nextrun = $nextrun; } + + /** + * Delete task + * + * @return boolean true on success or false in case of an error + */ + function remove() { /* {{{ */ + $db = $this->db; + + $queryStr = "DELETE FROM `tblSchedulerTask` WHERE `id` = " . $this->_id; + if (!$db->getResult($queryStr)) { + return false; + } + + return true; + } /* }}} */ + } diff --git a/inc/inc.ClassSchedulerTaskBase.php b/inc/inc.ClassSchedulerTaskBase.php index c190096a9..c51c0c0e7 100644 --- a/inc/inc.ClassSchedulerTaskBase.php +++ b/inc/inc.ClassSchedulerTaskBase.php @@ -29,7 +29,7 @@ * @package SeedDMS */ class SeedDMS_SchedulerTaskBase { - public function execute($task, $dms) { + public function execute($task, $dms, $user) { return true; } } diff --git a/inc/inc.ClassSession.php b/inc/inc.ClassSession.php index 8dcc92283..78f796a0b 100644 --- a/inc/inc.ClassSession.php +++ b/inc/inc.ClassSession.php @@ -294,7 +294,7 @@ class SeedDMS_Session { function addToClipboard($object) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $dms = $object->_dms; + $dms = $object->getDMS(); if($object->isType('document')) { if(!in_array($object->getID(), $this->data['clipboard']['docs'])) array_push($this->data['clipboard']['docs'], $object->getID()); @@ -317,7 +317,7 @@ class SeedDMS_Session { function removeFromClipboard($object) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $dms = $object->_dms; + $dms = $object->getDMS(); if($object->isType('document')) { $key = array_search($object->getID(), $this->data['clipboard']['docs']); if($key !== false) diff --git a/inc/inc.ClassUI.php b/inc/inc.ClassUI.php index 13abf3274..7beab4283 100644 --- a/inc/inc.ClassUI.php +++ b/inc/inc.ClassUI.php @@ -137,8 +137,8 @@ class UI extends UI_Default { $view->setParam('enablesessionlist', $settings->_enableSessionList); $view->setParam('workflowmode', $settings->_workflowMode); $view->setParam('checkoutdir', $settings->_checkOutDir); - $view->setParam('partitionsize', (int) $settings->_partitionSize); - $view->setParam('maxuploadsize', (int) $settings->_maxUploadSize); + $view->setParam('partitionsize', SeedDMS_Core_File::parse_filesize( $settings->_partitionSize)); + $view->setParam('maxuploadsize', SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize)); $view->setParam('showmissingtranslations', $settings->_showMissingTranslations); $view->setParam('defaultsearchmethod', $settings->_defaultSearchMethod); $view->setParam('cachedir', $settings->_cacheDir); diff --git a/inc/inc.ClassViewCommon.php b/inc/inc.ClassViewCommon.php index a63c9d770..cee14544c 100644 --- a/inc/inc.ClassViewCommon.php +++ b/inc/inc.ClassViewCommon.php @@ -69,6 +69,16 @@ class SeedDMS_View_Common { return null; } + /** + * Check if the view has a parameter with the given name + * + * @param string $name name of parameter + * @return boolean true if parameter exists otherwise false + */ + function hasParam($name) { + return isset($this->params[$name]) ? true : false; + } + public function unsetParam($name) { if(isset($this->params[$name])) unset($this->params[$name]); diff --git a/languages/de_DE/lang.inc b/languages/de_DE/lang.inc index e823dbd9a..5fef65ae3 100644 --- a/languages/de_DE/lang.inc +++ b/languages/de_DE/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (2765), dgrutsch (22) +// Translators: Admin (2767), dgrutsch (22) $text = array( '2_factor_auth' => '2-Faktor Authentifizierung', diff --git a/languages/el_GR/lang.inc b/languages/el_GR/lang.inc index cc5eec81a..7edaf768d 100644 --- a/languages/el_GR/lang.inc +++ b/languages/el_GR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (311) +// Translators: Admin (322) $text = array( '2_factor_auth' => '', @@ -347,7 +347,7 @@ $text = array( 'document_is_checked_out' => '', 'document_is_not_locked' => '', 'document_link_by' => '', -'document_link_public' => '', +'document_link_public' => 'Δημόσιο', 'document_moved_email' => 'Το έγγραφα μετακινήθηκε', 'document_moved_email_body' => '', 'document_moved_email_subject' => '', @@ -364,7 +364,7 @@ $text = array( 'document_updated_email' => '', 'document_updated_email_body' => '', 'document_updated_email_subject' => '', -'does_not_expire' => '', +'does_not_expire' => 'Δεν λήγει', 'does_not_inherit_access_msg' => '', 'download' => 'Λήψη', 'download_extension' => '', @@ -467,7 +467,7 @@ $text = array( 'expired_at_date' => '', 'expired_documents' => '', 'expires' => 'Λήγει', -'expire_by_date' => '', +'expire_by_date' => 'Λήγει στην ημερομηνία', 'expire_in_1d' => '', 'expire_in_1h' => '', 'expire_in_1m' => 'Λήγει σε 1 μήνα', @@ -660,7 +660,7 @@ $text = array( 'list_contains_no_access_docs' => '', 'list_hooks' => '', 'list_tasks' => '', -'local_file' => '', +'local_file' => 'Τοπικό αρχείο', 'locked_by' => '', 'lock_document' => 'Κλείδωμα', 'lock_message' => '', @@ -689,7 +689,7 @@ $text = array( 'mandatory_reviewers' => '', 'mandatory_reviewer_no_access' => '', 'march' => 'Μάρτιος', -'max_upload_size' => '', +'max_upload_size' => 'Μέγιστο μέγεθος μεταφόρτωσης', 'may' => 'Μάϊος', 'menu_dropfolder' => '', 'menu_upload_from_dropfolder' => '', @@ -715,7 +715,7 @@ $text = array( 'my_documents' => 'Τα έγγραφα μου', 'my_transmittals' => '', 'name' => 'Όνομα', -'nb_NO' => '', +'nb_NO' => 'Νορβηγικά', 'needs_correction' => '', 'needs_workflow_action' => '', 'network_drive' => '', @@ -833,7 +833,7 @@ URL: [url]', 'personal_default_keywords' => '', 'pl_PL' => 'Πολωνικά', 'possible_substitutes' => '', -'preset_expires' => '', +'preset_expires' => 'Λήξη προκαθορισμένης τιμής', 'preview' => 'προεπισκόπηση', 'preview_converters' => '', 'preview_images' => '', @@ -1014,7 +1014,7 @@ URL: [url]', 'select_attrdefgrp_show' => '', 'select_attribute_value' => '', 'select_category' => 'Επιλογή κατηγορίας', -'select_group' => '', +'select_group' => 'Επιλογή ομάδας', 'select_groups' => '', 'select_grp_approvers' => '', 'select_grp_ind_approvers' => '', @@ -1420,7 +1420,7 @@ URL: [url]', 'settings_workflowMode_valtraditional_only_approval' => '', 'settings_zendframework' => '', 'set_expiry' => '', -'set_owner' => '', +'set_owner' => 'Θέσε Ιδιοκτήτη', 'set_owner_error' => '', 'set_password' => '', 'set_workflow' => '', @@ -1672,9 +1672,9 @@ URL: [url]', 'user_login' => '', 'user_management' => 'Διαχείριση χρηστών', 'user_name' => 'Πλήρες Όνομα', -'use_comment_of_document' => '', +'use_comment_of_document' => 'Χρήση σχολίου εγγράφου', 'use_default_categories' => '', -'use_default_keywords' => '', +'use_default_keywords' => 'Χρήση προκαθορισμένων λέξεων κλειδιών', 'valid_till' => '', 'version' => 'Έκδοση', 'versioning_file_creation' => '', diff --git a/languages/en_GB/lang.inc b/languages/en_GB/lang.inc index 5afcc7c00..0f12104da 100644 --- a/languages/en_GB/lang.inc +++ b/languages/en_GB/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1871), archonwang (3), dgrutsch (9), netixw (14) +// Translators: Admin (1873), archonwang (3), dgrutsch (9), netixw (14) $text = array( '2_factor_auth' => '2-factor authentication', diff --git a/languages/es_ES/lang.inc b/languages/es_ES/lang.inc index 5f357848e..896e23399 100644 --- a/languages/es_ES/lang.inc +++ b/languages/es_ES/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: acabello (20), Admin (1151), angel (123), francisco (2), jaimem (14) +// Translators: acabello (20), Admin (1171), angel (123), francisco (2), jaimem (14) $text = array( '2_factor_auth' => '', @@ -68,11 +68,11 @@ URL: [url]', 'add_receipt' => '', 'add_review' => 'Enviar revisión', 'add_revision' => '', -'add_role' => '', +'add_role' => 'Agregar Usuario', 'add_subfolder' => 'Añadir subcarpeta', 'add_task' => '', 'add_to_clipboard' => 'Añadir al portapapeles', -'add_to_transmittal' => '', +'add_to_transmittal' => 'Añadir a transmisión', 'add_transmittal' => '', 'add_user' => 'Añadir nuevo usuario', 'add_user_to_group' => 'Añadir usuario a grupo', @@ -136,7 +136,7 @@ URL: [url]', 'archive_creation_warning' => 'Con esta operación usted puede crear un archivo que contenga los ficheros de las carpetas del DMS completo. Después de crearlo el archivo se guardará en la carpeta de datos de su servidor.CUIDADO: un fichero creado como legible por humanos no podrá usarse como copia de seguridad del servidor.', 'ar_EG' => 'Arabe', 'assign_approvers' => 'Asignar aprobadores', -'assign_recipients' => '', +'assign_recipients' => 'Asignar Receptores', 'assign_reviewers' => 'Asignar revisores', 'assign_user_property_to' => 'Asignar propiedades de usuario a', 'assumed_released' => 'Supuestamente publicado', @@ -231,8 +231,8 @@ URL: [url]', 'change_assignments' => 'cambiar asignaciones', 'change_password' => 'cambiar contraseña', 'change_password_message' => 'Su contraseña se ha modificado.', -'change_recipients' => '', -'change_revisors' => '', +'change_recipients' => 'Definir destinatarios', +'change_revisors' => 'Definir revisores', 'change_status' => 'cambiar estado', 'charts' => 'Gráficos', 'chart_docsaccumulated_title' => 'Cantidad de documentos', @@ -254,7 +254,7 @@ URL: [url]', 'choose_attrdefgroup' => '', 'choose_category' => 'Seleccione categoría', 'choose_group' => 'Seleccione grupo', -'choose_role' => '', +'choose_role' => 'Seleccione Usuario', 'choose_target_category' => 'Seleccione categoría', 'choose_target_document' => 'Seleccione documento', 'choose_target_file' => 'Seleccione fichero destino', @@ -442,7 +442,7 @@ URL: [url]', 'do_object_setfilesize' => 'Asignar tamaño de fichero', 'do_object_setfiletype' => '', 'do_object_unlink' => 'Borrar versión del documento', -'draft' => '', +'draft' => 'Borrador', 'draft_pending_approval' => 'Borador - pendiente de aprobación', 'draft_pending_review' => 'Borrador - pendiente de revisión', 'drag_icon_here' => 'Arrastre carpeta o documento aquí!', @@ -656,7 +656,7 @@ URL: [url]', 'index_pending' => '', 'index_waiting' => 'Esperando', 'individuals' => 'Individuales', -'individuals_in_groups' => '', +'individuals_in_groups' => 'Miembros del grupo', 'info_recipients_tab_not_released' => '', 'inherited' => 'heredado', 'inherits_access_copy_msg' => 'Copiar lista de acceso heredado', @@ -686,7 +686,7 @@ URL: [url]', 'invalid_user_id' => 'ID de usuario no válido', 'invalid_version' => 'Versión de documento no válida', 'in_folder' => 'En el directorio', -'in_revision' => '', +'in_revision' => 'En revisión', 'in_workflow' => 'En flujo de trabajo', 'is_disabled' => 'Deshabilitar cuenta', 'is_hidden' => 'Ocultar de la lista de usuarios', @@ -794,7 +794,7 @@ URL: [url]', 'my_transmittals' => 'Mi transmision', 'name' => 'Nombre', 'nb_NO' => 'Noruego (Bokmål)', -'needs_correction' => '', +'needs_correction' => 'Necesita corrección', 'needs_workflow_action' => 'Este documento requiere su atención. Por favor chequee la pestaña de flujo de trabajo.', 'network_drive' => '', 'never' => 'nunca', @@ -855,7 +855,7 @@ URL: [url]', 'no_action' => 'No es necesaria ninguna acción', 'no_approval_needed' => 'No hay aprobaciones pendientes.', 'no_attached_files' => 'No hay ficheros adjuntos', -'no_backup_dir' => '', +'no_backup_dir' => 'El directorio de backup no está definido', 'no_current_version' => 'Está utilizando una versión desactualizada de este producto. La última versión disponible es [latestversion].', 'no_default_keywords' => 'No hay palabras clave disponibles', 'no_docs_checked_out' => '', @@ -971,7 +971,7 @@ Si continua teniendo problemas de acceso, por favor contacte con el administrado 'receipt_summary' => 'Resumen de recepción', 'receipt_update_failed' => '', 'recent_uploads' => 'Subidas recientes', -'reception' => '', +'reception' => 'Recepción', 'reception_acknowleged' => '', 'reception_noaction' => '', 'reception_rejected' => '', @@ -1052,7 +1052,7 @@ URL: [url]', 'review_submit_email_subject' => '[sitename]: [name] - Revisión enviada', 'review_summary' => 'Resumen de revisión', 'review_update_failed' => 'Error actualizando el estado de la revisión. La actualización ha fallado.', -'revise_document' => '', +'revise_document' => 'Revisar documento', 'revise_document_on' => '', 'revisions_accepted' => '', 'revisions_accepted_latest' => '', @@ -1065,14 +1065,14 @@ URL: [url]', 'revisions_without_group' => '', 'revisions_without_user' => '', 'revision_date' => '', -'revision_log' => '', +'revision_log' => 'Histórico de revisiones', 'revision_request_email_body' => '', 'revision_request_email_subject' => '', 'revision_status' => '', 'revision_submit_email_body' => '', 'revision_submit_email_subject' => '', 'revision_summary' => 'Resumen de revisión', -'revisors' => '', +'revisors' => 'Revisores', 'revisor_already_assigned' => '', 'revisor_already_removed' => '', 'rewind_workflow' => 'Retroceso del flujo de trabajo', @@ -1160,16 +1160,16 @@ URL: [url]', 'select_grp_approvers' => 'Haga Click para seleccionar grupo de aprobadores', 'select_grp_ind_approvers' => '', 'select_grp_ind_notification' => '', -'select_grp_ind_recipients' => '', -'select_grp_ind_reviewers' => '', +'select_grp_ind_recipients' => 'Seleccione grupo', +'select_grp_ind_reviewers' => 'Dar click para seleccionar el grupo', 'select_grp_ind_revisors' => '', 'select_grp_notification' => 'Clic para seleccionar la notificación grupal', -'select_grp_recipients' => '', +'select_grp_recipients' => 'Dar click para selecionar el grupo', 'select_grp_reviewers' => 'Haga Click para seleccionar grupo de revisores', 'select_grp_revisors' => '', 'select_ind_approvers' => 'Haga Click para seleccionar aprobador individual', 'select_ind_notification' => 'Clic para seleccionar la notificación individual', -'select_ind_recipients' => '', +'select_ind_recipients' => 'Dar click para asignar los receptores', 'select_ind_reviewers' => 'Haga Click para seleccionar revisor individual', 'select_ind_revisors' => '', 'select_one' => 'Seleccionar uno', @@ -1660,7 +1660,7 @@ URL: [url]', 'status_not_approved' => 'Sin aprobar', 'status_not_receipted' => '', 'status_not_reviewed' => 'Sin revisar', -'status_not_revised' => '', +'status_not_revised' => 'No revisado', 'status_receipted' => '', 'status_receipt_rejected' => '', 'status_recipient_removed' => '', diff --git a/languages/fr_FR/lang.inc b/languages/fr_FR/lang.inc index c02f80626..9948dad7d 100644 --- a/languages/fr_FR/lang.inc +++ b/languages/fr_FR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1102), jeromerobert (50), lonnnew (9), Oudiceval (922) +// Translators: Admin (1102), jeromerobert (50), lonnnew (9), Oudiceval (929) $text = array( '2_factor_auth' => 'Authentification forte', @@ -1666,7 +1666,7 @@ Nom : [username] 'splash_error_add_to_transmittal' => 'Erreur lors de l’ajout du document à la transmission', 'splash_error_rm_download_link' => 'Erreur lors de la suppression du lien de téléchargement', 'splash_error_send_download_link' => 'Erreur lors de l’envoi du lien de téléchargement', -'splash_extension_getlist' => 'Liste des extensions mises à jour depuis le dépôt', +'splash_extension_getlist' => 'Liste des extensions du dépôt actualisée', 'splash_extension_import' => 'Extension installée', 'splash_extension_refresh' => 'Liste des extensions actualisée', 'splash_extension_upload' => 'Extension installée', @@ -1743,8 +1743,8 @@ Nom : [username] 'submit_review' => 'Soumettre la vérification', 'submit_revision' => 'Soumettre la révision', 'submit_userinfo' => 'Soumettre info', -'submit_webauthn_login' => '', -'submit_webauthn_register' => '', +'submit_webauthn_login' => 'Identification', +'submit_webauthn_register' => 'Inscription', 'subsribe_timelinefeed' => 'S’abonner au flux RSS', 'substitute_to_user' => 'Basculer sur \'[username]\'', 'substitute_user' => 'Utilisateur de substitution', @@ -1904,10 +1904,10 @@ URL: [url]', 'view' => 'Aperçu', 'view_online' => 'Aperçu en ligne', 'warning' => 'Avertissement', -'webauthn_auth' => '', -'webauthn_crossplatform_info' => '', -'webauthn_info' => '', -'webauth_crossplatform' => '', +'webauthn_auth' => 'Authentification WebAuthn', +'webauthn_crossplatform_info' => 'Choisissez « Oui » lorsque vous avez un périphérique amovible, comme une clé Yubico, que vous souhaitez utiliser pour vous connecter sur différents ordinateurs ; choisissez « Non » lorsque votre appareil est connecté à l\'ordinateur. Le choix affecte le ou les appareils proposés par le navigateur et / ou le système de sécurité informatique.', +'webauthn_info' => 'WebAuthn est une authentification sans mot de passe utilisant la cryptographie à clé publique. Une paire de clés privée-publique (connue sous le nom de certificat) est créée pour un site Web. La clé privée est stockée en toute sécurité sur l’appareil de l’utilisateur ; une clé publique et un identifiant généré de manière aléatoire sont envoyés au serveur pour stockage. Le serveur peut ensuite utiliser cette clé publique pour prouver l’identité de l’utilisateur. La clé privée est généralement stockée sur un jeton matériel. Le jeton doit être enregistré avant de pouvoir être utilisé pour l’authentification.', +'webauth_crossplatform' => 'Multiplateforme', 'wednesday' => 'Mercredi', 'wednesday_abbr' => 'Mer.', 'weeks' => 'semaines', diff --git a/languages/hu_HU/lang.inc b/languages/hu_HU/lang.inc index 90326a8c9..5e1e21ee4 100644 --- a/languages/hu_HU/lang.inc +++ b/languages/hu_HU/lang.inc @@ -23,11 +23,11 @@ $text = array( '2_factor_auth' => 'Kétfaktoros azonosítás', -'2_factor_auth_info' => '', +'2_factor_auth_info' => 'A rendszernek két faktoros hitelesítése van. Szükséged lesz a Google Authenticator-ra a mobil telefonodon. Lejebb látható két QR kód. A jobb oldali a saját jelszavát, a baloldali egy új titkos jelszót tartalmaz. Ha új jelszót szeretne beállítani, szkennelje be újra a Goolge Authenticator-al.', '2_fact_auth_secret' => 'Titkos', 'accept' => 'Elfogad', -'access_control' => '', -'access_control_is_off' => '', +'access_control' => 'Hozzáférés vezérlés', +'access_control_is_off' => 'A speciális vezérlés hozzáférése ki van kapcsolva', 'access_denied' => 'Hozzáférés megtagadva.', 'access_inheritance' => 'Hozzáférés öröklés', 'access_mode' => 'Hozzáférési mód', @@ -54,7 +54,7 @@ URL: [url]', 'action_revise' => 'Felülvizsgálat', 'add' => 'Hozzáad', 'add_approval' => 'Jóváhagyás küldése', -'add_attrdefgroup' => '', +'add_attrdefgroup' => 'Új tulajdonságcsoport hozzáadása', 'add_document' => 'Dokumentum hozzáadása', 'add_document_link' => 'Hivatkozás hozzáadása', 'add_document_notify' => 'Hozzárendelés értesítés', @@ -67,7 +67,7 @@ URL: [url]', 'add_multiple_files' => 'Több állomány hozzáadása (az állomány nevét használja dokumentum névként)', 'add_receipt' => '', 'add_review' => 'Felülvizsgálat küldése', -'add_revision' => '', +'add_revision' => 'Felülvizsgálat hozzáadása', 'add_role' => 'szerepkör hozzáadása', 'add_subfolder' => 'Alkönyvtár hozzáadása', 'add_task' => 'Feladat hozzáadása', @@ -103,7 +103,7 @@ URL: [url]', 'approval_deletion_email' => 'Jóváhagyási kérelem törölve', 'approval_deletion_email_body' => '', 'approval_deletion_email_subject' => '', -'approval_file' => '', +'approval_file' => 'Fájl', 'approval_group' => 'Jóváhagyó csoport', 'approval_log' => 'Jóváhagyási napló', 'approval_request_email' => 'Jóváhagyási kérelem', @@ -115,7 +115,7 @@ Felhasználó: [username] URL: [url]', 'approval_request_email_subject' => '[sitename]: [name] - Jóváhagyási kérelem', 'approval_status' => 'Jóváhagyási állapot', -'approval_submit_email' => '', +'approval_submit_email' => 'Fordítás hiányzik', 'approval_submit_email_body' => 'Dokumentum jóváhagyása Documentum: [name] Verzió: [version] @@ -143,10 +143,10 @@ URL: [url]', 'attrdefgroup_management' => '', 'attrdefgrp_show_detail' => '', 'attrdefgrp_show_list' => '', -'attrdefgrp_show_search' => '', +'attrdefgrp_show_search' => 'Keresés', 'attrdefgrp_show_searchlist' => '', 'attrdef_exists' => 'Jellemző meghatározás már létezik', -'attrdef_info' => '', +'attrdef_info' => 'Információ', 'attrdef_in_use' => 'Jellemző meghatározás még használatban van', 'attrdef_management' => 'Jellemző meghatározás kezelése', 'attrdef_maxvalues' => 'Legnagyobb érték', @@ -162,11 +162,11 @@ URL: [url]', 'attrdef_type' => 'Típus', 'attrdef_type_boolean' => 'Logikai', 'attrdef_type_date' => 'Dátum', -'attrdef_type_email' => '', +'attrdef_type_email' => 'Email', 'attrdef_type_float' => 'Szám tizedesjeggyel', 'attrdef_type_int' => 'Egész szám', 'attrdef_type_string' => 'Szöveg', -'attrdef_type_url' => '', +'attrdef_type_url' => 'URL', 'attrdef_valueset' => 'Értékek beállítása', 'attributes' => 'Jellemzők', 'attribute_changed_email_body' => 'Jellemző módosult @@ -223,7 +223,7 @@ URL: [url]', 'category' => 'Kategória', 'category_exists' => 'Kategória már létezik', 'category_filter' => 'Kizárólag kategóriák', -'category_info' => '', +'category_info' => 'Információk', 'category_in_use' => 'Dokumentumok használják ezt a kategóriát', 'category_noname' => 'Nem adott meg kategória nevet.', 'ca_ES' => 'Katalán', @@ -299,8 +299,8 @@ URL: [url]', 'confirm_update_transmittalitem' => '', 'content' => 'Tartalom', 'continue' => 'Folytatás', -'converter_new_cmd' => '', -'converter_new_mimetype' => '', +'converter_new_cmd' => 'Új parancs', +'converter_new_mimetype' => 'Új mime típus', 'copied_to_checkout_as' => '', 'create_download_link' => '', 'create_fulltext_index' => 'Teljes szöveg index létrehozása', @@ -366,7 +366,7 @@ Szülő mappa: [folder_path] Felhasználó: [username] URL: [url]', 'document_comment_changed_email_subject' => '[sitename]: [name] - Megjegyzés módosult', -'document_count' => '', +'document_count' => 'Dokumentumok száma', 'document_deleted' => 'Dokumentum törölve', 'document_deleted_email' => 'Dokumentum törölve', 'document_deleted_email_body' => 'Dokumentum törölve @@ -457,7 +457,7 @@ URL: [url]', 'dump_list' => 'Meglévő adatbázis metések', 'dump_remove' => 'Adatbázis mentés eltávolítása', 'duplicates' => '', -'duplicate_content' => '', +'duplicate_content' => 'Duplikált tartalom', 'edit' => 'Szerkesztés', 'edit_attributes' => 'Jellemzők szerkesztése', 'edit_comment' => 'Megjegyzés szerkesztése', @@ -539,7 +539,7 @@ Felhasználó: [username] URL: [url]', 'expiry_changed_email_subject' => '[sitename]: [name] - Lejárati dátum módosítva', 'export' => 'exportálás', -'extension_archive' => '', +'extension_archive' => 'Bővítmények', 'extension_changelog' => 'Változásnapló', 'extension_loading' => 'Kiterjesztések betöltése ...', 'extension_manager' => 'Bővítmények kezelése', @@ -630,7 +630,7 @@ URL: [url]', 'guest_login_disabled' => 'Vendég bejelentkezés letiltva.', 'hash' => 'hash', 'help' => 'Segítség', -'home_folder' => '', +'home_folder' => 'Saját mappa', 'hook_name' => '', 'hourly' => 'Óra', 'hours' => 'óra', @@ -641,14 +641,14 @@ URL: [url]', 'identical_version' => 'Az új verzió megegyezik az eredetivel.', 'import' => 'Import', 'importfs' => '', -'import_extension' => '', +'import_extension' => 'Kiterjesztés import', 'import_fs' => 'Importálás fájlrendszerből', 'import_fs_warning' => '', 'include_content' => '', 'include_documents' => 'Tartalmazó dokumentumok', 'include_subdirectories' => 'Tartalmazó alkönyvtárak', 'indexing_tasks_in_queue' => 'Indexelés folyamatban', -'index_converters' => '', +'index_converters' => 'Index konvertáló', 'index_done' => '', 'index_error' => '', 'index_folder' => 'Mappa indexelése', @@ -784,7 +784,7 @@ URL: [url]', 'monday_abbr' => 'Hé', 'monthly' => 'Havi', 'month_view' => 'Havi nézet', -'more_objects_loading' => '', +'more_objects_loading' => 'További sorok betöltése...', 'move' => 'Áthelyez', 'move_clipboard' => 'Vágólapra helyez', 'move_document' => 'Dokumentum áthelyezése', @@ -929,10 +929,10 @@ Amennyiben problémákba ütközik a bejelentkezés során, kérjük vegye fel a 'password_strength' => 'Jelszó erősség', 'password_strength_insuffient' => 'Jelszó erőssége elégtelen', 'password_wrong' => 'Hibás jelszó', -'pdf_converters' => '', -'pending_approvals' => '', +'pdf_converters' => 'PDF konvertáló', +'pending_approvals' => 'Függőben lévő jóváhagyások', 'pending_receipt' => '', -'pending_reviews' => '', +'pending_reviews' => 'Függőben lévő feladatok', 'pending_revision' => '', 'pending_workflows' => '', 'personal_default_keywords' => 'Személyes kulcsszó lista', @@ -940,7 +940,7 @@ Amennyiben problémákba ütközik a bejelentkezés során, kérjük vegye fel a 'possible_substitutes' => '', 'preset_expires' => 'Érvényesség beállítása', 'preview' => 'Előnézet', -'preview_converters' => '', +'preview_converters' => 'A dokumentum átalakításának előnézete', 'preview_images' => 'előnézeti képek', 'preview_markdown' => '', 'preview_pdf' => '', @@ -948,7 +948,7 @@ Amennyiben problémákba ütközik a bejelentkezés során, kérjük vegye fel a 'previous_state' => 'Előző állapot', 'previous_versions' => 'Előző változatok', 'process' => 'Folyamat', -'process_without_user_group' => '', +'process_without_user_group' => 'Felhasználó / csoport nélküli folyamatok', 'pt_BR' => 'Portugál (BR)', 'quota' => 'Kvóta', 'quota_exceeded' => 'Túllépte a lemezterület korlátot [bytes].', @@ -1171,7 +1171,7 @@ URL: [url]', 'select_ind_recipients' => '', 'select_ind_reviewers' => 'Kattintson az önálló felülvizsgáló kijelöléséhez', 'select_ind_revisors' => '', -'select_one' => 'Vßlasszon egyet', +'select_one' => 'Válasszon egyet', 'select_user' => 'Felhasználó kiválasztása', 'select_users' => 'Kattintson a felhasználó kiválasztásához', 'select_value' => 'Érték kiválasztása', @@ -1180,13 +1180,13 @@ URL: [url]', 'send_login_data' => '', 'send_login_data_body' => '', 'send_login_data_subject' => '', -'send_test_mail' => 'teszt email küldése', +'send_test_mail' => 'Teszt e-mail küldése', 'september' => 'September', 'sequence' => 'Sorrend', 'seq_after' => '"[prevname]" utßn', 'seq_end' => 'Vgre', 'seq_keep' => 'Pozci megtartßsa', -'seq_start' => 'Elejre', +'seq_start' => 'Elejére', 'sessions' => '', 'setDateFromFile' => '', 'setDateFromFolder' => '', @@ -1200,16 +1200,16 @@ URL: [url]', 'settings_advancedAcl_desc' => '', 'settings_allowChangeRevAppInProcess' => '', 'settings_allowChangeRevAppInProcess_desc' => '', -'settings_allowReviewerOnly' => '', -'settings_allowReviewerOnly_desc' => '', +'settings_allowReviewerOnly' => 'Engedélyezi, hogy csak az ellenört állítsa be', +'settings_allowReviewerOnly_desc' => 'Ha ezt engedélyez, akkor lehetővé válik, hogy a hagyományos munkafolyamat módban csak ellenört állítson be, ne jóváhagyót.', 'settings_apache_mod_rewrite' => 'Apache - Rewrite modul', 'settings_Authentication' => 'Hitelesítési beállítások', -'settings_autoLoginUser' => '', -'settings_autoLoginUser_desc' => '', +'settings_autoLoginUser' => 'Automatikus bejelentkezés', +'settings_autoLoginUser_desc' => 'Használja ezt a felhasználói azonosítót a hozzáférésekhez, ha a felhasználó még nincs bejelentkezve. Az ilyen hozzáférés nem hoz létre munkamenetet.', 'settings_available_languages' => 'Elérhető nyelvek', 'settings_available_languages_desc' => '', -'settings_backupDir' => '', -'settings_backupDir_desc' => '', +'settings_backupDir' => 'Mentés könyvtára', +'settings_backupDir_desc' => 'Könyvtár, ahol a biztonsági mentési eszköz mentéseket készít. Ha ez a könyvtár nincs beállítva vagy nem érhető el, akkor a biztonsági másolatot a tartalom könyvtárba menti.', 'settings_cacheDir' => 'Átmeneti állományok könyvtára', 'settings_cacheDir_desc' => 'Ahol az előnézeti képek tárolódnak (legjobb olyan könyvtárat választani, amit a web-kiszolgálón keresztül nem lehet elérni)', 'settings_Calendar' => 'Naptár beállítások', @@ -1218,14 +1218,14 @@ URL: [url]', 'settings_cannot_disable' => 'ENABLE_INSTALL_TOOL állomány nem került törlésre', 'settings_checkOutDir' => '', 'settings_checkOutDir_desc' => '', -'settings_cmdTimeout' => '', -'settings_cmdTimeout_desc' => '', +'settings_cmdTimeout' => 'Külső parancsok időtúllépése', +'settings_cmdTimeout_desc' => 'Ez az időtartam másodpercben határozza meg, hogy mikor fejezik be a külső parancsot (például a teljes szöveg index létrehozásához).', 'settings_contentDir' => 'Tartalom könyvtár', 'settings_contentDir_desc' => 'Feltöltött állományok tárolási helye (olyan könyvtárat érdemes választani, amelyhez nem lehet a webszerveren keresztül hozzáférni)', 'settings_contentOffsetDir' => 'Tartalom eltérési könyvtár', 'settings_contentOffsetDir_desc' => 'Az alapul szolgáló fájlrendszer korlátozásainak kikerülésére új könyvtár struktúra került kialakításra amely úgy lett tervezve, hogy létezzen a tároló könyvtárban (Content Directory). Ehhez szükséges egy alap könyvtár ahonnan indul. Általában meg lehet hagyni az alapértelmezett értéket ami 1048576, de megadható bármilyen szám vagy karaktersorozat amely nem létezik a tartalom könyvtárban (Content Directory)', -'settings_convertToPdf' => '', -'settings_convertToPdf_desc' => '', +'settings_convertToPdf' => 'A dokumentum konvertálása PDF-be előnézet céljából', +'settings_convertToPdf_desc' => 'Ha a dokumentumot nem tudja megjeleníteni a böngészőben, akkor megjelenik egy pdf-formátumra konvertált változat.', 'settings_cookieLifetime' => 'Süti élettartam', 'settings_cookieLifetime_desc' => 'A süti élettartama másodpercben. Ha az értéke 0 akkor a süti a böngésző bezárásakor lesz törölve.', 'settings_coreDir' => 'Alap SeedDMS könyvtár', @@ -1247,12 +1247,12 @@ URL: [url]', 'settings_dbUser' => 'Felhasználónév', 'settings_dbUser_desc' => 'Az adatbázis eléréséhez tartozó felhasználónevet a telepítési eljárás során kell megadni. Ne szerkessze ezt a mezőt, csak ha nagyon szükséges, például, ha az adatbázist át kell helyezni egy másik gépre.', 'settings_dbVersion' => 'Adatbázis séma túl régi', -'settings_defaultAccessDocs' => '', -'settings_defaultAccessDocs_desc' => '', -'settings_defaultDocPosition' => '', -'settings_defaultDocPosition_desc' => '', -'settings_defaultDocPosition_val_end' => '', -'settings_defaultDocPosition_val_start' => '', +'settings_defaultAccessDocs' => 'Alapértelmezett hozzáférés az új dokumentumokhoz', +'settings_defaultAccessDocs_desc' => 'Új dokumentum létrehozásakor ez lesz az alapértelmezett hozzáférési jog.', +'settings_defaultDocPosition' => 'A dokumentum elhelyezése létrehozáskor', +'settings_defaultDocPosition_desc' => 'Ez az alapértelmezett hely egy mappában egy dokumentum létrehozásakor.', +'settings_defaultDocPosition_val_end' => 'vége', +'settings_defaultDocPosition_val_start' => 'eleje', 'settings_defaultSearchMethod' => 'Alapértelmezett keresési módszer', 'settings_defaultSearchMethod_desc' => '', 'settings_defaultSearchMethod_valdatabase' => 'adatbázis', @@ -1265,8 +1265,8 @@ URL: [url]', 'settings_dropFolderDir' => 'Drop mappa könyvtára', 'settings_dropFolderDir_desc' => 'Ez a könyvtár használható az importálandó állományok elhelyezésére a fájlrendszeren a böngészővel történő feltöltés helyett. A könyvtárnak tartalmaznia kell alkönyvtárakat minden felhasználóhoz akinek engedélyezett az állományok ilyen módon történő importálása.', 'settings_Edition' => 'Kiadás beállítások', -'settings_editOnlineFileTypes' => '', -'settings_editOnlineFileTypes_desc' => '', +'settings_editOnlineFileTypes' => 'Online fájltípusok szerkesztése', +'settings_editOnlineFileTypes_desc' => 'Az alábbi végződésekkel vagy mime-típusokkal rendelkező fájlok online szerkeszthetők (CSAK KISBETÜK HASZNÁLHTÓAK!)', 'settings_enable2FactorAuthentication' => '', 'settings_enable2FactorAuthentication_desc' => '', 'settings_enableAcknowledgeWorkflow' => '', @@ -1283,8 +1283,8 @@ URL: [url]', 'settings_enableConverting_desc' => 'Engedélyezi/tiltja az állományok konverzióját', 'settings_enableDebugMode' => '', 'settings_enableDebugMode_desc' => '', -'settings_enableDropFolderList' => '', -'settings_enableDropFolderList_desc' => '', +'settings_enableDropFolderList' => 'Engedélyezzi a fájlok listáját a drop mappa menüben', +'settings_enableDropFolderList_desc' => 'Kapcsolja be a Drop mappa-ban lévő fájlok listáját. A lista megjelenik a főmenüben.', 'settings_enableDropUpload' => 'Gyorsfeltöltés engedélyezése', 'settings_enableDropUpload_desc' => 'Be/Ki kapcsolja a \'Mappa nézet\' oldalon a fogd és vidd feltöltéshez tartozó területetet', 'settings_enableDuplicateDocNames' => 'Azonos dokumentum név engedélyezése', @@ -1299,8 +1299,8 @@ URL: [url]', 'settings_enableFolderTree_desc' => 'Hamis hogy ne jelenjen meg a mappa fastruktúra', 'settings_enableFullSearch' => 'Teljes szöveg keresés engedélyezése', 'settings_enableFullSearch_desc' => 'Engedélyezi a teljes szöveg keresést', -'settings_enableGuestAutoLogin' => '', -'settings_enableGuestAutoLogin_desc' => '', +'settings_enableGuestAutoLogin' => 'Engedélyezi az automatikus belépést a Vendég felhasználónak', +'settings_enableGuestAutoLogin_desc' => 'Ha a vendég bejelentkezés és az automatikus bejelentkezés engedélyezve van, a vendég automatikusan be lesz jelentkezve.', 'settings_enableGuestLogin' => 'Vendég belépésének engedélyezése', 'settings_enableGuestLogin_desc' => 'Ha azt szeretné, hogy bárki be tudjon jelentkezni vendégként, jelölje be ezt a lehetőséget. Megjegyzés: vendég bejelentkezés megbízható környezetben használható', 'settings_enableHelp' => 'Súgó engedélyezése', @@ -1309,10 +1309,10 @@ URL: [url]', 'settings_enableLanguageSelector_desc' => 'Megjelenít egy választást a felhasználói felületen a bejelentkezést követően.', 'settings_enableLargeFileUpload' => 'Nagy méretű állományok feltöltésének engedélyezése', 'settings_enableLargeFileUpload_desc' => 'Ha beállítja az állományok feltöltése elérhető lesz egy jumploadernek hívott java appleten keresztül a böngészőprogram állomány méret korlátja nélkül. Ez engedélyezi több állomány feltöltését egy lépésben.', -'settings_enableMenuTasks' => '', -'settings_enableMenuTasks_desc' => '', -'settings_enableMultiUpload' => '', -'settings_enableMultiUpload_desc' => '', +'settings_enableMenuTasks' => 'Feladatok menüpont engedélyezése', +'settings_enableMenuTasks_desc' => 'Engedélyezi / letiltja a menüelemet, amely a felhasználó összes feladatát tartalmazza. Ez olyan dokumentumokat tartalmaz, amelyeket felül kell vizsgálni, jóvá kell hagyni stb.', +'settings_enableMultiUpload' => 'Több fájl feltöltésének engedélyezése', +'settings_enableMultiUpload_desc' => 'Új dokumentum létrehozásakor több fájl feltölthető. Mindegyik létrehoz egy új dokumentumot.', 'settings_enableNotificationAppRev' => 'A felülvizsgáló/jóváhagyó értesítés engedélyezése', 'settings_enableNotificationAppRev_desc' => 'Ellenőrzi az értesítés küldését a felülvizsgálónak/jóváhagyónak új dokumentum változat hozzáadásakor', 'settings_enableNotificationWorkflow' => 'A felhasználó értesítése a következő munkafolyamatnál', @@ -1341,14 +1341,14 @@ URL: [url]', 'settings_enableSelfReceipt_desc' => '', 'settings_enableSelfRevApp' => 'Engedélyezi a felülvizsgálatot/jóváhagyást a bejelentkezett felhasználó számára', 'settings_enableSelfRevApp_desc' => 'Engedélyezze, a azt szeretné, hogy a bejelentkezett felhasználó listázásra kerüljön felülvizsgálóként/jóváhagyóként és a munkamenet átmeneteknél.', -'settings_enableSessionList' => '', -'settings_enableSessionList_desc' => '', +'settings_enableSessionList' => 'Engedélyezi a Felhasználók menüpont megjelenítését', +'settings_enableSessionList_desc' => 'Bejelentkezett felhasználók megjelenítése a főmenü / felhasználók menüjében.', 'settings_enableThemeSelector' => 'Téma választása', 'settings_enableThemeSelector_desc' => 'Kapcsolja be/ki a témaválasztót a bejelentkező oldalon', 'settings_enableUpdateReceipt' => '', 'settings_enableUpdateReceipt_desc' => '', 'settings_enableUpdateRevApp' => '', -'settings_enableUpdateRevApp_desc' => '', +'settings_enableUpdateRevApp_desc' => 'Engedélyezze ezt, ha a felülvizsgálatot / jóváhagyást megadó felhasználó megváltoztathatja a döntést, amíg a jelenlegi munkafolyamat még nem fejeződött be.', 'settings_enableUserImage' => 'Felhasználói kép engedélyezése', 'settings_enableUserImage_desc' => 'Engedélyezi a felhasználók képeit', 'settings_enableUsersView' => 'Felhasználók nézetének engedélyezése', @@ -1357,10 +1357,10 @@ URL: [url]', 'settings_enableVersionDeletion_desc' => 'Engedélyezi/tiltja a korábbi dokumentum verziók törlését az általános felhasználóknak. Adminisztrátor mindig törölheti a korábbi változatokat.', 'settings_enableVersionModification' => 'Engedélyezi a verziók módosítását', 'settings_enableVersionModification_desc' => 'Engedélyezi/tiltja a dokumentum verziók módosítását az általános felhasználóknak miután a verzió feltöltésre került. Adminisztrátor mindig módosíthatja a verziót feltöltés után.', -'settings_enableWebdavReplaceDoc' => '', -'settings_enableWebdavReplaceDoc_desc' => '', -'settings_enableXsendfile' => '', -'settings_enableXsendfile_desc' => '', +'settings_enableWebdavReplaceDoc' => 'Dokumentum cseréje mentés után', +'settings_enableWebdavReplaceDoc_desc' => 'Ha engedélyezve van, egy dokumentum új verziójának mentése az új verzió létrehozása helyett a régi dokumentumot váltja fel. Ez csak akkor lesz érvényes, ha a felhasználó, a típustípus és a fájlnév megegyezik az utolsó verzióval. Ez hasznos lehet, ha az alkalmazások automatikusan menti a dokumentumot meghatározott időközönként.', +'settings_enableXsendfile' => 'Apache xsendfile module használata', +'settings_enableXsendfile_desc' => 'Ha ez az opció be van állítva, és az xsendfile apache modul telepítve van, akkor a képeket továbbítja.', 'settings_encryptionKey' => 'Titkosító kulcs', 'settings_encryptionKey_desc' => 'Ez a karaktersorozat használható egyedi azonosító létrehozásához amely rejtett mezőként lesz hozzáadva az űrlapokhoz a CSRF támadások megelőzésére.', 'settings_error' => 'Hiba', @@ -1376,16 +1376,16 @@ URL: [url]', 'settings_firstDayOfWeek_desc' => 'A hét első napja', 'settings_footNote' => 'Lábjegyzet', 'settings_footNote_desc' => 'Minden oldal alján megjelenő üzenet', -'settings_fullSearchEngine' => '', -'settings_fullSearchEngine_desc' => '', -'settings_fullSearchEngine_vallucene' => 'Zend Lucene', -'settings_fullSearchEngine_valsqlitefts' => 'SQLiteFTS', +'settings_fullSearchEngine' => 'Szöveg keresési mód', +'settings_fullSearchEngine_desc' => 'Állítsa be a kereséséhez használt módot.', +'settings_fullSearchEngine_vallucene' => 'Dokumentum tartalom keresés', +'settings_fullSearchEngine_valsqlitefts' => 'Adatbázis keresés', 'settings_guestID' => 'Vendég azonosító', 'settings_guestID_desc' => 'A vendég felhasználó azonosítója ami a vendégként történő bejelentkezéskor lesz használva (általában nem szükséges módosítani)', 'settings_httpRoot' => 'Http gyökér', 'settings_httpRoot_desc' => 'A relatív elérési út az URL-ben a tartomány rész után. Ne tartalmazza a http:// előtagot vag a web szerver nevét. Pl.: ha a teljes URL http://www.example.com/seeddms/, adja meg \'/seeddms/\'. Ha az URL http://www.example.com/, adja meg \'/\'', -'settings_incItemsPerPage' => '', -'settings_incItemsPerPage_desc' => '', +'settings_incItemsPerPage' => 'Az oldal végén betöltött bejegyzések száma', +'settings_incItemsPerPage_desc' => 'Ha a mappák és a dokumentumok száma korlátozott, akkor ez beállítja a kiegészítőként betöltött tételek számát, amikor a nézetmappa oldal aljára görget. Ha ezt 0-ra állítja, akkor nincs megjelenítési korlátozás.', 'settings_initialDocumentStatus' => '', 'settings_initialDocumentStatus_desc' => '', 'settings_initialDocumentStatus_draft' => '', @@ -1416,14 +1416,14 @@ URL: [url]', 'settings_maxDirID_desc' => 'Szülő könyvtárban lévő alkönyvtárak maximális mennyisége, Alapérték: 0.', 'settings_maxExecutionTime' => 'Maximális végrehajtási idő (s)', 'settings_maxExecutionTime_desc' => 'Beállítja a szkript maximális engedélyezett futási idejét másodpercben mielőtt megszakítja az értelmező', -'settings_maxItemsPerPage' => '', -'settings_maxItemsPerPage_desc' => '', +'settings_maxItemsPerPage' => 'Egy oldalon megjeleníthető tételek maximális száma', +'settings_maxItemsPerPage_desc' => 'Korlátozza a nézetlistában megjelenő mappák és dokumentumok számát. További tételeket tölt be, amikor az oldal végére görgeti. 0-ra állítva az összes tétel mindig megjelenik.', 'settings_maxRecursiveCount' => 'Rekurzív dokumentum/mappa számláló legnagyobb értéke', 'settings_maxRecursiveCount_desc' => 'A dokumentumok és mappák maximális mennyisége amelyeken ellenőrizni fogják a hozzáférési jogokat, ha rekurzívan számláló tárgyakat. Ha ezt az értéket túllépik, a dokumentumok számát és mappák a Mappa nézetben is becsülhetők.', -'settings_maxSizeForFullText' => '', -'settings_maxSizeForFullText_desc' => '', -'settings_maxUploadSize' => '', -'settings_maxUploadSize_desc' => '', +'settings_maxSizeForFullText' => 'Maximális fájlméret az azonnali indexeléshez', +'settings_maxSizeForFullText_desc' => 'A beállított méretnél kisebb minden új dokumentum verziót a feltöltés után azonnal teljesen indexeli. Minden más esetben csak a metaadatok kerülnek indexelésre.', +'settings_maxUploadSize' => 'Feltölthető állományok maximális mérete', +'settings_maxUploadSize_desc' => 'Ez a feltöltött fájlok maximális mérete. A dokumentum verziókra és a mellékletekre is vonatkozik.', 'settings_more_settings' => 'További beállítások konfigurálása. Alapértelmezett bejelentkezés: admin/admin', 'settings_noDocumentFormFields' => '', 'settings_noDocumentFormFields_desc' => '', @@ -1433,8 +1433,8 @@ URL: [url]', 'settings_no_content_dir' => 'Tartalom könyvtár', 'settings_onePageMode' => '', 'settings_onePageMode_desc' => '', -'settings_overrideMimeType' => '', -'settings_overrideMimeType_desc' => '', +'settings_overrideMimeType' => 'A Mime típus felülbírálása', +'settings_overrideMimeType_desc' => 'A fájl feltöltése esetén felülbírálja a böngésző által szállított Mime típust. Az új Mime típust maga a SeedDMS határozza meg.', 'settings_partitionSize' => 'Részleges fájlméret', 'settings_partitionSize_desc' => 'A részleges állományok mérete, amelyek a jumploader segítségével lesznek feltöltve. Ne adjon meg magasabb értéket, mint a szerveren beállított legnagyobb feltölthető állomány méret.', 'settings_passwordExpiration' => 'Jelszó lejárat', @@ -1458,14 +1458,14 @@ URL: [url]', 'settings_presetExpirationDate_desc' => 'Minden feltöltött dokumentumhoz ezt a lejárati dátumot rendeli hozzá. A PHP strtotime() függvényének formátuma használható, pl.: +5 weeks.', 'settings_previewWidthDetail' => 'Előnézeti képek szélessége (részletek)', 'settings_previewWidthDetail_desc' => 'A részletek oldalon megjelenő előnézeti képek szélessége', -'settings_previewWidthDropFolderList' => '', -'settings_previewWidthDropFolderList_desc' => '', +'settings_previewWidthDropFolderList' => 'Az előnézeti képek szélessége (drop mappa listában)', +'settings_previewWidthDropFolderList_desc' => 'A listában szereplő előnézeti képek szélessége, amikor a fájlt kiválasztja a drop mappából.', 'settings_previewWidthList' => 'Előnézeti képek szélessége (lista)', 'settings_previewWidthList_desc' => 'A listában megjelenő előnézeti képek szélessége', -'settings_previewWidthMenuList' => '', -'settings_previewWidthMenuList_desc' => '', +'settings_previewWidthMenuList' => 'Az előnézeti képek szélessége (menülista)', +'settings_previewWidthMenuList_desc' => 'Az előnézeti képek szélessége, amelyeket tételekként jelennek meg a Drop mappa menüben.', 'settings_printDisclaimer' => 'Nyilatkozat nyomtatása', -'settings_printDisclaimer_desc' => 'Ha igaz a nyilatkozat üzenet a lang.inc állományok lesznek kiíratva a lap alján', +'settings_printDisclaimer_desc' => 'Ha igaz ez a beállítás, akkor s lang.inc-ben a Disclaimer tartalma kerül megjelenítésre a lap alján', 'settings_proxyUPassword' => '', 'settings_proxyUPassword_desc' => '', 'settings_proxyUrl' => '', @@ -1474,10 +1474,10 @@ URL: [url]', 'settings_proxyUser_desc' => '', 'settings_quota' => 'Felhasználói kvóta', 'settings_quota_desc' => 'A felhasználó által a lemezen használható bájtok legnagyobb száma. Állítsa 0-ra a korlátlan lemezterülethez. Ez az érték felülírható valamennyi felhasználó saját profiljában.', -'settings_removeFromDropFolder' => '', -'settings_removeFromDropFolder_desc' => '', -'settings_repositoryUrl' => '', -'settings_repositoryUrl_desc' => '', +'settings_removeFromDropFolder' => 'A sikeres feltöltés után távolítsa el a fájlt a drop mappából', +'settings_removeFromDropFolder_desc' => 'Engedélyezze ezt, ha a drop mappából vett fájlt a sikeres feltöltés után törölhető.', +'settings_repositoryUrl' => 'Bővítmények URL-je', +'settings_repositoryUrl_desc' => 'A bővítmények tárházának URL-je', 'settings_restricted' => 'Korlátozott hozzáférés', 'settings_restricted_desc' => 'Kizárólag azok a felhasználók jelentkezhetnek be, akik a helyi adatbázisban vannak (függetlenül a sikeres LDAP azonosítástól)', 'settings_rootDir' => 'Gyökérkönyvtár', @@ -1490,8 +1490,8 @@ URL: [url]', 'settings_showFullPreview_desc' => '', 'settings_showMissingTranslations' => 'Jelenítse meg a hiányzó fordításokat', 'settings_showMissingTranslations_desc' => 'Felsorolja az összes hiányzó fordítást a lap alján. A bejelentkezett felhasználó képes lesz arra, hogy javaslatot nyújtson be a hiányzó fordításokra, amelyek egy csv állományba kerülnek mentésre. Ne kapcsolja be ezt a funkciót élse környezetben!', -'settings_showSingleSearchHit' => '', -'settings_showSingleSearchHit_desc' => '', +'settings_showSingleSearchHit' => 'Ugrás egyenesen egyetlen keresési találatra', +'settings_showSingleSearchHit_desc' => 'Ha a keresésnek egy találata van, akkor ugorjon a dokumentum tartalmára.', 'settings_Site' => 'Webhely', 'settings_siteDefaultPage' => 'Webhely kezdőlap', 'settings_siteDefaultPage_desc' => 'Alapértelmezett oldal a bejelentkezést követően. Ha üres, akkor az alapértelmezett out/out.ViewFolder.php', @@ -1504,8 +1504,8 @@ URL: [url]', 'settings_smtpPort_desc' => 'SMTP kiszolgáló port, alapértelmezett 25', 'settings_smtpSendFrom' => 'Feladó', 'settings_smtpSendFrom_desc' => 'A levél feladója', -'settings_smtpSendTestMail' => '', -'settings_smtpSendTestMail_desc' => '', +'settings_smtpSendTestMail' => 'Teszt e-mail küldése', +'settings_smtpSendTestMail_desc' => 'Tesztlevelet küld az aktuális e-mail konfiguráció ellenőrzéséhez.', 'settings_smtpServer' => 'SMTP kiszolgáló gépnév', 'settings_smtpServer_desc' => 'SMTP kiszolgáló gépnév', 'settings_smtpUser' => 'SMTP kiszolgáló felhasználó', @@ -1551,7 +1551,7 @@ URL: [url]', 'settings_versiontolow' => 'túl alacsony verzió', 'settings_viewOnlineFileTypes' => 'Online állománytípus nézet', 'settings_viewOnlineFileTypes_desc' => 'A következő végződéssel rendelkező állományok megtekinthetők online (KIZÁRÓLAG KISBETŰS KARAKTEREKET HASZNÁLJON)', -'settings_webdav' => '', +'settings_webdav' => 'WebDAV', 'settings_workflowMode' => 'Munkafolyamat mód', 'settings_workflowMode_desc' => 'A részletes munkafolyamat engedélyezi saját kiadási munkafolyamat megadását a dokumentum változatokhoz.', 'settings_workflowMode_valadvanced' => 'részletes', @@ -1723,7 +1723,7 @@ URL: [url]', 'timeline_full_add_file' => '', 'timeline_full_add_version' => '', 'timeline_full_scheduled_revision' => '', -'timeline_full_status_change' => '', +'timeline_full_status_change' => '[document]Verzió [version]: [status]', 'timeline_scheduled_revision' => '', 'timeline_selected_item' => '', 'timeline_skip_add_file' => 'melléklet hozzáadva', @@ -1839,7 +1839,7 @@ Szülő mappa: [folder_path] Felhasználó: [username] URL: [url]', 'version_deleted_email_subject' => '[sitename]: [name] - Változat törölve', -'version_info' => 'Változat információ', +'version_info' => 'Verzió információ', 'view' => 'Nézet', 'view_online' => 'Online megtekintés', 'warning' => 'Figyelmeztetés', @@ -1878,7 +1878,7 @@ URL: [url]', 'workflow_transition_without_user_group' => '', 'workflow_user_summary' => 'Felhasználó áttekintés', 'wrong_filetype' => '', -'x_more_objects' => '', +'x_more_objects' => '[number] további tétel', 'year_view' => 'Éves nézet', 'yes' => 'Igen', 'zh_CN' => 'Kínai (CN)', diff --git a/languages/it_IT/lang.inc b/languages/it_IT/lang.inc index 1aa3c42c8..daf21b6b4 100644 --- a/languages/it_IT/lang.inc +++ b/languages/it_IT/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (2020), rickr (144), s.pnt (26) +// Translators: Admin (2021), rickr (144), s.pnt (26) $text = array( '2_factor_auth' => 'Autorizzazione a due fattori', @@ -803,7 +803,7 @@ URL: [url]', 'my_documents' => 'Documenti personali', 'my_transmittals' => 'Mie trasmissioni', 'name' => 'Nome', -'nb_NO' => 'Norvegese', +'nb_NO' => 'Norvegiese (Bokmål)', 'needs_correction' => 'Necessita correzioni', 'needs_workflow_action' => 'Il documento richiede attenzione. Prego controllare il flusso di lavoro.', 'network_drive' => 'Network drive', diff --git a/languages/nl_NL/lang.inc b/languages/nl_NL/lang.inc index 86f12a25b..e65db868f 100644 --- a/languages/nl_NL/lang.inc +++ b/languages/nl_NL/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (778), gijsbertush (651), pepijn (45), reinoutdijkstra@hotmail.com (270) +// Translators: Admin (779), gijsbertush (651), pepijn (45), reinoutdijkstra@hotmail.com (270) $text = array( '2_factor_auth' => '2-factor-authenticatie', @@ -1100,7 +1100,7 @@ URL: [url]', 'revision_status' => 'Status revisie', 'revision_submit_email_body' => '', 'revision_submit_email_subject' => '', -'revision_summary' => '', +'revision_summary' => 'Revisie samenvatting', 'revisors' => 'Herzieners', 'revisor_already_assigned' => 'Gebruiker is reeds herziener', 'revisor_already_removed' => 'Herziener reeds verwijderd', diff --git a/languages/pl_PL/lang.inc b/languages/pl_PL/lang.inc index afb7b95a5..12d9bebdb 100644 --- a/languages/pl_PL/lang.inc +++ b/languages/pl_PL/lang.inc @@ -19,14 +19,14 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (867), netixw (84), romi (93), uGn (112) +// Translators: Admin (871), netixw (84), romi (93), uGn (112) $text = array( '2_factor_auth' => '', '2_factor_auth_info' => '', '2_fact_auth_secret' => '', 'accept' => 'Akceptuj', -'access_control' => '', +'access_control' => 'Kontrola dostępu', 'access_control_is_off' => '', 'access_denied' => 'Dostęp zabroniony.', 'access_inheritance' => 'Dziedziczenie dostępu', @@ -1089,7 +1089,7 @@ URL: [url]', 'role_admin' => 'Administrator', 'role_guest' => 'Gość', 'role_info' => '', -'role_management' => '', +'role_management' => 'Zarządzanie rolam', 'role_name' => '', 'role_type' => '', 'role_user' => 'Użytkownik', @@ -1112,7 +1112,7 @@ URL: [url]', 'scheduler_class_description' => '', 'scheduler_class_parameter' => '', 'scheduler_class_tasks' => '', -'scheduler_task_mgr' => '', +'scheduler_task_mgr' => 'Zadania', 'search' => 'Szukaj', 'search_fulltext' => 'Przeszukaj całe teksty', 'search_in' => 'Szukaj w', @@ -1810,7 +1810,7 @@ URL: [url]', 'versioning_file_creation_warning' => 'Ta operacja utworzy plik zawierający informacje o wersjach plików z całego wskazanego folderu. Po utworzeniu, każdy plik będzie zapisany w folderze odpowiednim dla danego dokumentu.', 'versioning_info' => 'Informacje o wersjach', 'versiontolow' => 'Za niska wersja', -'version_comment' => '', +'version_comment' => 'Opis wersji', 'version_deleted_email' => 'Wersja usunięta', 'version_deleted_email_body' => 'Wersja została usunięta Dokument: [name] diff --git a/languages/ro_RO/lang.inc b/languages/ro_RO/lang.inc index be6d9d98a..d6d43ba4e 100644 --- a/languages/ro_RO/lang.inc +++ b/languages/ro_RO/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1097), balan (87) +// Translators: Admin (1099), balan (87) $text = array( '2_factor_auth' => '', @@ -798,7 +798,7 @@ URL: [url]', 'my_documents' => 'Documentele Mele', 'my_transmittals' => 'Trimiterile mele', 'name' => 'Nume', -'nb_NO' => '', +'nb_NO' => 'Norvegiana', 'needs_correction' => '', 'needs_workflow_action' => 'Acest document necesită atenția dumneavoastră. Vă rugăm să verificați tab-ul workflow.', 'network_drive' => '', @@ -1195,7 +1195,7 @@ URL: [url]', 'select_ind_reviewers' => 'Click pentru a selecta un revizuitor individual', 'select_ind_revisors' => 'Faceti click pentru a selecta retrimitori individuali', 'select_one' => 'Selectați unul', -'select_user' => '', +'select_user' => 'Selecteaza utilizator', 'select_users' => 'Click pentru a selecta utilizatori', 'select_value' => 'Valoare selectata', 'select_workflow' => 'Selectați workflow', diff --git a/languages/ru_RU/lang.inc b/languages/ru_RU/lang.inc index 67a762ac4..e5991b686 100644 --- a/languages/ru_RU/lang.inc +++ b/languages/ru_RU/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1678) +// Translators: Admin (1681) $text = array( '2_factor_auth' => 'Двухфакторная аутентификация', @@ -141,7 +141,7 @@ URL: [url]', 'archive_creation_warning' => 'Эта операция создаст архив, содержащий все каталоги. После создания архив будет сохранен в каталоге данных сервера.Внимание: архив созданный как понятный человеку, будет непригоден в качестве резервной копии для восстановления!', 'ar_EG' => 'Arabic', 'assign_approvers' => 'Назначить утверждающих', -'assign_recipients' => '', +'assign_recipients' => 'Указать получателей', 'assign_reviewers' => 'Назначить рецензентов', 'assign_user_property_to' => 'Назначить свойства пользователя', 'assumed_released' => 'Утверждён', @@ -799,7 +799,7 @@ URL: [url]', 'my_transmittals' => 'Мои пересылки', 'name' => 'Имя', 'nb_NO' => 'Норвежский', -'needs_correction' => '', +'needs_correction' => 'Нужны правки', 'needs_workflow_action' => 'Этот документ требует вашего внимания. См. вкладку «Процесс».', 'network_drive' => 'Сетевой диск', 'never' => 'никогда', @@ -1189,7 +1189,7 @@ URL: [url]', 'select_grp_approvers' => 'Выберите утверждающую группу', 'select_grp_ind_approvers' => 'Выберите группу', 'select_grp_ind_notification' => 'Выберите группу', -'select_grp_ind_recipients' => '', +'select_grp_ind_recipients' => 'Щелкните для выбора группы', 'select_grp_ind_reviewers' => 'Выберите группу', 'select_grp_ind_revisors' => '', 'select_grp_notification' => 'Выберите группу для уведомления', diff --git a/languages/sv_SE/lang.inc b/languages/sv_SE/lang.inc index fb92b16d4..fdf9e2f9e 100644 --- a/languages/sv_SE/lang.inc +++ b/languages/sv_SE/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1161), MagnusI (649), tmichelfelder (106) +// Translators: Admin (1162), MagnusI (649), tmichelfelder (106) $text = array( '2_factor_auth' => '2-faktors autentisering', @@ -804,7 +804,7 @@ URL: [url]', 'my_documents' => 'Mina dokument', 'my_transmittals' => 'Mina överföringar', 'name' => 'Namn', -'nb_NO' => '', +'nb_NO' => 'Norska (Bokmål)', 'needs_correction' => '', 'needs_workflow_action' => 'Detta dokument behöver din uppmärksamhet. Kontrollera inställningarna för arbetsflödet.', 'network_drive' => 'Nätverkslagring', diff --git a/languages/tr_TR/lang.inc b/languages/tr_TR/lang.inc index 3a1836370..43ffc5b9c 100644 --- a/languages/tr_TR/lang.inc +++ b/languages/tr_TR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1094), aydin (83) +// Translators: Admin (1095), aydin (83) $text = array( '2_factor_auth' => '', @@ -792,7 +792,7 @@ URL: [url]', 'my_documents' => 'Dokümanlarım', 'my_transmittals' => '', 'name' => 'İsim', -'nb_NO' => '', +'nb_NO' => 'Norveç Havayolları', 'needs_correction' => '', 'needs_workflow_action' => 'Bu doküman dikkatinizi gerektiriyor. Lütfen iş akış sekmesini kontrol ediniz.', 'network_drive' => '', diff --git a/languages/zh_CN/lang.inc b/languages/zh_CN/lang.inc index b04c861ed..7a888f5e7 100644 --- a/languages/zh_CN/lang.inc +++ b/languages/zh_CN/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (766), archonwang (469), fengjohn (5), yang86 (1) +// Translators: Admin (770), archonwang (469), fengjohn (5), yang86 (1) $text = array( '2_factor_auth' => '双重认证', @@ -517,7 +517,7 @@ URL: [url]', 'event_details' => '错误详情', 'exclude_items' => '排除项目', 'expired' => '过期', -'expired_at_date' => '', +'expired_at_date' => '过期时间', 'expired_documents' => '过期文档', 'expires' => '有效限期', 'expire_by_date' => '指定过期时间', @@ -786,9 +786,9 @@ URL: [url]', 'move_folder' => '移动文件夹', 'my_account' => '我的账户', 'my_documents' => '我的文档', -'my_transmittals' => '', +'my_transmittals' => '我的送达函', 'name' => '名称', -'nb_NO' => '', +'nb_NO' => '挪威语(书面挪威语)', 'needs_correction' => '', 'needs_workflow_action' => '', 'network_drive' => '网络驱动器', @@ -1125,7 +1125,7 @@ URL: [url]', 'scheduler_class_description' => '', 'scheduler_class_parameter' => '', 'scheduler_class_tasks' => '', -'scheduler_task_mgr' => '', +'scheduler_task_mgr' => '排程表', 'search' => '搜索', 'search_fulltext' => '全文检索', 'search_in' => '搜索于', diff --git a/op/op.AddDocument.php b/op/op.AddDocument.php index c8159b6fb..37804bc88 100644 --- a/op/op.AddDocument.php +++ b/op/op.AddDocument.php @@ -76,7 +76,7 @@ if ($accessop->check_controller_access($controller, array('action'=>'setOwner')) $owner = $user; } $comment = trim($_POST["comment"]); -$version_comment = trim($_POST["version_comment"]); +$version_comment = !empty($_POST["version_comment"]) ? trim($_POST["version_comment"]) : ''; if($version_comment == "" && isset($_POST["use_comment"])) $version_comment = $comment; @@ -408,10 +408,14 @@ if(!empty($_POST['notification_groups'])) { } /* Check files for Errors first */ +$maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); for ($file_num=0;$file_num $folder->getName())),getMLText("uploading_zerosize")); } + if ($maxuploadsize && $_FILES["userfile"]["size"][$file_num] > $maxuploadsize) { + UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("uploading_maxsize")); + } if (/* is_uploaded_file($_FILES["userfile"]["tmp_name"][$file_num]) && */$_FILES['userfile']['error'][$file_num]!=0){ UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("uploading_failed")); } diff --git a/op/op.AddFile.php b/op/op.AddFile.php index 8b3a8022a..3eb2d566f 100644 --- a/op/op.AddFile.php +++ b/op/op.AddFile.php @@ -62,10 +62,14 @@ if(isset($_POST[$prefix.'-fine-uploader-uuids']) && $_POST[$prefix.'-fine-upload } } +$maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); for ($file_num=0;$file_num $document->getName())),getMLText("uploading_zerosize")); } + if ($maxuploadsize && $_FILES["userfile"]["size"][$file_num] > $maxuploadsize) { + UI::exitError(getMLText("folder_title", array("documentname" => $document->getName())),getMLText("uploading_maxsize")); + } if (is_uploaded_file($_FILES["userfile"]["tmp_name"][$file_num]) && $_FILES['userfile']['error'][$file_num] != 0){ UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("uploading_failed")); } diff --git a/op/op.Ajax.php b/op/op.Ajax.php index 6c7774367..812eddf58 100644 --- a/op/op.Ajax.php +++ b/op/op.Ajax.php @@ -666,6 +666,13 @@ switch($command) { exit; } + $maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); + if ($maxuploadsize && $_FILES["userfile"]["size"] > $maxuploadsize) { + header('Content-Type: application/json'); + echo json_encode(array('success'=>false, 'message'=>getMLText("uploading_maxsize"))); + exit; + } + $userfiletmp = $_FILES["userfile"]["tmp_name"]; $userfiletype = $_FILES["userfile"]["type"]; $userfilename = $_FILES["userfile"]["name"]; diff --git a/op/op.SchedulerTaskMgr.php b/op/op.SchedulerTaskMgr.php index ca0ce4ea2..8b327b468 100644 --- a/op/op.SchedulerTaskMgr.php +++ b/op/op.SchedulerTaskMgr.php @@ -66,7 +66,7 @@ if ($action == "addtask") { /* {{{ */ add_log_line(".php&action=addtask&name=".$name); } /* }}} */ -// modify transmittal ---------------------------------------------------- +// modify task ---------------------------------------------------- else if ($action == "edittask") { /* {{{ */ /* Check if the form data comes for a trusted request */ @@ -90,7 +90,7 @@ else if ($action == "edittask") { /* {{{ */ $frequency = $_POST["frequency"]; $disabled = isset($_POST["disabled"]) ? $_POST["disabled"] : 0; $params = $_POST["params"]; - + if ($editedtask->getName() != $name) $editedtask->setName($name); if ($editedtask->getDescription() != $description) @@ -104,5 +104,40 @@ else if ($action == "edittask") { /* {{{ */ add_log_line(".php&action=edittask&taskid=".$taskid); } /* }}} */ +// delete task ------------------------------------------------------------- +else if ($action == "removetask") { /* {{{ */ + header('Content-Type: application/json'); + + /* Check if the form data comes from a trusted request */ + if(!checkFormKey('removetask')) { + echo json_encode(array('success'=>false, 'message'=>getMLText("invalid_request_token"))); + exit; + } + + if (!isset($_POST["taskid"]) || !is_numeric($_POST["taskid"]) || intval($_POST["taskid"])<1) { + echo json_encode(array('success'=>false, 'message'=>getMLText("invalid_task"))); + exit; + } + + $taskid=$_POST["taskid"]; + $task = $scheduler->getTask($taskid); + + if (!is_object($task)) { + echo json_encode(array('success'=>false, 'message'=>getMLText("invalid_task"))); + exit; + } + + if (!$task->remove()) { + echo json_encode(array('success'=>false, 'message'=>getMLText("error_occured"))); + exit; + } + + add_log_line("?taskid=".$_POST["taskid"]."&action=removetask"); + + echo json_encode(array('success'=>true, 'message'=>getMLText("task_removed"))); + exit; +} /* }}} */ + + header("Location:../out/out.SchedulerTaskMgr.php"); diff --git a/op/op.SetRevisors.php b/op/op.SetRevisors.php index 56cff04d6..8314c506c 100644 --- a/op/op.SetRevisors.php +++ b/op/op.SetRevisors.php @@ -212,7 +212,7 @@ if (count($revisionIndex["i"]) > 0) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("recipient_already_removed")); break; case -4: - // email error + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("recipient_was_active")); break; } } @@ -315,7 +315,7 @@ if (count($revisionIndex["g"]) > 0) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("recipient_already_removed")); break; case -4: - // email error + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("recipient_was_active")); break; } } @@ -323,6 +323,11 @@ if (count($revisionIndex["g"]) > 0) { } } +/* If all revisors has been removed, then clear the next revision date */ +if(!$pIndRev && !$pGrpRev) { + $content->setRevisionDate(false); +} + /* Recheck status, because all revisors could have been removed */ $content->verifyStatus(false, $user, getMLText('automatic_status_update'), $settings->_initialDocumentStatus); diff --git a/op/op.UpdateDocument.php b/op/op.UpdateDocument.php index 0006cb6c1..1081f30db 100644 --- a/op/op.UpdateDocument.php +++ b/op/op.UpdateDocument.php @@ -91,6 +91,11 @@ if (isset($_FILES['userfile']) && $_FILES['userfile']['error'] == 0) { if($_FILES["userfile"]["size"] == 0) UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("uploading_zerosize")); + $maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); + if ($maxuploadsize && $_FILES["userfile"]["size"] > $maxuploadsize) { + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("uploading_maxsize")); + } + $userfiletmp = $_FILES["userfile"]["tmp_name"]; $userfiletype = $_FILES["userfile"]["type"]; $userfilename = $_FILES["userfile"]["name"]; diff --git a/out/out.AddDocument.php b/out/out.AddDocument.php index d8c442a82..8351afc35 100644 --- a/out/out.AddDocument.php +++ b/out/out.AddDocument.php @@ -91,7 +91,6 @@ if($view) { $view->setParam('presetexpiration', $settings->_presetExpirationDate); $view->setParam('sortusersinlist', $settings->_sortUsersInList); $view->setParam('defaultposition', $settings->_defaultDocPosition); - $view->setParam('maxuploadsize', $settings->_maxUploadSize); $view->setParam('orderby', $settings->_sortFoldersDefault); $view->setParam('accessobject', $accessop); $view($_GET); diff --git a/out/out.TransmittalMgr.php b/out/out.TransmittalMgr.php index 2e7c789ff..3ce4fd276 100644 --- a/out/out.TransmittalMgr.php +++ b/out/out.TransmittalMgr.php @@ -47,6 +47,7 @@ if(isset($_GET['transmittalid']) && $_GET['transmittalid']) { if($view) { $view->setParam('seltransmittal', $seltransmittal); + $view->setParam('showtree', showtree()); $view->setParam('cachedir', $settings->_cacheDir); $view->setParam('timeout', $settings->_cmdTimeout); $view->setParam('previewWidthList', $settings->_previewWidthList); diff --git a/styles/bootstrap/application.css b/styles/bootstrap/application.css index 7427e89c7..aac713b83 100644 --- a/styles/bootstrap/application.css +++ b/styles/bootstrap/application.css @@ -60,6 +60,10 @@ ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover { font-weight: bold; } +legend > span { + float: right; +} + td.today { background-color: rgb(255, 200, 0); } @@ -158,6 +162,21 @@ div.splash { display: none; } +div.clipboard-container { + position: fixed; + left: 10px; + top: 40px; + width: 29.8%; + background: white; + border: 1px solid #d4d4d4; + border-radius: 5px; + padding: 10px; + height: 500px; + margin: 10px; + overflow-y: auto; + overflow-x: hidden; +} + div.statusbar-container { display: none; position: fixed; diff --git a/styles/bootstrap/application.js b/styles/bootstrap/application.js index 776c91b1e..134de9da2 100644 --- a/styles/bootstrap/application.js +++ b/styles/bootstrap/application.js @@ -166,6 +166,12 @@ $(document).ready( function() { } }); /* }}} */ + $('body').on('click', '#clipboard-float', function(ev) { /* {{{ */ + ev.preventDefault(); + ev.stopPropagation(); + $('#clipboard-container').toggleClass('clipboard-container'); + }); /* }}} */ + $('body').on('click', 'a.addtoclipboard', function(ev) { /* {{{ */ ev.preventDefault(); ev.stopPropagation(); @@ -178,7 +184,7 @@ $(document).ready( function() { function(data) { if(data.success) { $("#main-clipboard").html('Loading').load('../out/out.Clipboard.php?action=mainclipboard') - $("#menu-clipboard").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') + $("#menu-clipboard div").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') noty({ text: attr_msg, type: 'success', @@ -213,7 +219,7 @@ $(document).ready( function() { function(data) { if(data.success) { $("#main-clipboard").html('Loading').load('../out/out.Clipboard.php?action=mainclipboard') - $("#menu-clipboard").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') + $("#menu-clipboard div").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') noty({ text: attr_msg, type: 'success', @@ -451,7 +457,7 @@ $(document).ready( function() { if(data.success) { if(element.data('param1') == 'command=clearclipboard') { $("#main-clipboard").html('Loading').load('../out/out.Clipboard.php?action=mainclipboard') - $("#menu-clipboard").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') + $("#menu-clipboard div").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') } noty({ text: data.message, @@ -492,7 +498,7 @@ function onAddClipboard(ev) { /* {{{ */ function(data) { if(data.success) { $("#main-clipboard").html('Loading').load('../out/out.Clipboard.php?action=mainclipboard') - $("#menu-clipboard").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') + $("#menu-clipboard div").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') noty({ text: data.message, type: 'success', @@ -758,18 +764,18 @@ $(document).ready(function() { /* {{{ */ attr_rel = $(e.currentTarget).data('droptarget'); target_type = attr_rel.split("_")[0]; target_id = attr_rel.split("_")[1]; - target_name = $(e.currentTarget).data('name') + target_name = $(e.currentTarget).data('name')+''; // Force this to be a string if(target_type == 'folder') { var files = e.originalEvent.dataTransfer.files; if(files.length > 0) { - console.log('Drop '+files.length+' files on '+target_type+' '+target_id); +// console.log('Drop '+files.length+' files on '+target_type+' '+target_id); SeedDMSUpload.handleFileUpload(files,$(e.currentTarget),$('div.statusbar-container h1')/*$(e.currentTarget).find("span")*/); } else { var source_info = JSON.parse(e.originalEvent.dataTransfer.getData("text")); source_type = source_info.type; source_id = source_info.id; formtoken = source_info.formtoken; - console.log('Drop '+source_type+' '+source_id+' on '+target_type+' '+target_id); +// console.log('Drop '+source_type+' '+source_id+' on '+target_type+' '+target_id); if(source_type == 'document') { var bootbox_message = trans.confirm_move_document; if(source_info.name) @@ -863,14 +869,14 @@ $(document).ready(function() { /* {{{ */ } else if(target_type == 'document') { var files = e.originalEvent.dataTransfer.files; if(files.length > 0) { - console.log('Drop '+files.length+' files on '+target_type+' '+target_id); +// console.log('Drop '+files.length+' files on '+target_type+' '+target_id); SeedDMSUpload.handleFileUpload(files,$(e.currentTarget),$('div.statusbar-container h1')/*$(e.currentTarget).find("span")*/); } else { var source_info = JSON.parse(e.originalEvent.dataTransfer.getData("text")); source_type = source_info.type; source_id = source_info.id; formtoken = source_info.formtoken; - console.log('Drop '+source_type+' '+source_id+' on '+target_type+' '+target_id); +// console.log('Drop '+source_type+' '+source_id+' on '+target_type+' '+target_id); if(source_type == 'document') { if(source_id != target_id) { bootbox.dialog(trans.confirm_transfer_link_document, [{ @@ -956,7 +962,7 @@ $(document).ready(function() { /* {{{ */ id : attr_rel.split("_")[1], type : "folder", formtoken : $(e.target).attr('formtoken'), - name: $(e.target).data('name') + name: $(e.target).data('name')+'' }; /* Currently not used $.ajax({url: '../out/out.ViewFolder.php', @@ -982,7 +988,7 @@ $(document).ready(function() { /* {{{ */ id : attr_rel.split("_")[1], type : "document", formtoken : $(e.target).attr('formtoken'), - name: $(e.target).data('name') + name: $(e.target).data('name')+'' }; e.originalEvent.dataTransfer.setData("text", JSON.stringify(dragStartInfo)); }); diff --git a/styles/bootstrap/favicon.ico b/styles/bootstrap/favicon.ico index 890150f4c..7b4adcc9f 100644 Binary files a/styles/bootstrap/favicon.ico and b/styles/bootstrap/favicon.ico differ diff --git a/styles/bootstrap/fine-uploader/LICENSE b/styles/bootstrap/fine-uploader/LICENSE index 3814391a3..070caa60c 100644 --- a/styles/bootstrap/fine-uploader/LICENSE +++ b/styles/bootstrap/fine-uploader/LICENSE @@ -1,5 +1,7 @@ The MIT License (MIT) +Copyright (c) 2010-2012, Andrew Valums +Copyright (c) 2012-2013, Andrew Valums and Raymond S. Nicholus, III Copyright (c) 2013-present, Widen Enterprises, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/styles/bootstrap/fine-uploader/dnd.js b/styles/bootstrap/fine-uploader/dnd.js index 100061705..4beb73676 100644 --- a/styles/bootstrap/fine-uploader/dnd.js +++ b/styles/bootstrap/fine-uploader/dnd.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { var qq = function(element) { "use strict"; @@ -578,7 +578,7 @@ global.qq = qq; } })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -596,9 +596,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -636,7 +633,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -765,12 +766,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -798,6 +794,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -885,9 +889,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -927,8 +928,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -953,6 +956,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -1005,7 +1010,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -1088,6 +1093,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; })(window); //# sourceMappingURL=dnd.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.js.map b/styles/bootstrap/fine-uploader/dnd.js.map index dce774d90..853391d84 100644 --- a/styles/bootstrap/fine-uploader/dnd.js.map +++ b/styles/bootstrap/fine-uploader/dnd.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","options","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","disposeSupport","dropZoneElements","allowMultipleItems","classes","dropActive","callbacks","uploadDroppedFiles","files","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","fullPath","indexOfNameInFullPath","qqPath","fileError","code","isDirectory","getFilesInDirectory","allEntriesRead","entries","entriesLeft","readFailure","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","x","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","onLeave","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.indexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n file.qqPath = fullPath;\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","options","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","disposeSupport","dropZoneElements","allowMultipleItems","classes","dropActive","callbacks","uploadDroppedFiles","files","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","qqPath","extractDirectoryPath","fileError","fullPath","code","isDirectory","getFilesInDirectory","allEntriesRead","entries","entriesLeft","readFailure","indexOfNameInFullPath","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","x","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","_testing","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","onLeave","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n file.qqPath = extractDirectoryPath(entry);\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n function extractDirectoryPath(entry) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.lastIndexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n return fullPath;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.min.js b/styles/bootstrap/fine-uploader/dnd.min.js index 1841817de..bad4e2de0 100644 --- a/styles/bootstrap/fine-uploader/dnd.min.js +++ b/styles/bootstrap/fine-uploader/dnd.min.js @@ -1,3 +1,3 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(n,t){return e.addEventListener?e.addEventListener(n,t,!1):e.attachEvent&&e.attachEvent("on"+n,t),function(){qq(e).detach(n,t)}},detach:function(n,t){return e.removeEventListener?e.removeEventListener(n,t,!1):e.attachEvent&&e.detachEvent("on"+n,t),this},contains:function(n){return!!n&&(e===n||(e.contains?e.contains(n):!!(8&n.compareDocumentPosition(e))))},insertBefore:function(n){return n.parentNode.insertBefore(e,n),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(n){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=n.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(n.filter="alpha(opacity="+Math.round(100*n.opacity)+")"),qq.extend(e.style,n),this},hasClass:function(n,t){var r=new RegExp("(^| )"+n+"( |$)");return r.test(e.className)||!(!t||!r.test(e.parentNode.className))},addClass:function(n){return qq(e).hasClass(n)||(e.className+=" "+n),this},removeClass:function(n){var t=new RegExp("(^| )"+n+"( |$)");return e.className=e.className.replace(t," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(n,t){var r,o=[];return t&&e.querySelector?e.querySelector("."+n):e.querySelectorAll?e.querySelectorAll("."+n):(r=e.getElementsByTagName("*"),qq.each(r,function(e,t){qq(t).hasClass(n)&&o.push(t)}),t?o[0]:o)},getFirstByClass:function(n){return qq(e).getByClass(n,!0)},children:function(){for(var n=[],t=e.firstChild;t;)1===t.nodeType&&n.push(t),t=t.nextSibling;return n},setText:function(n){return e.innerText=n,e.textContent=n,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(n){var t;return e.hasAttribute?!!e.hasAttribute(n)&&null==/^false$/i.exec(e.getAttribute(n)):(t=e[n],void 0!==t&&null==/^false$/i.exec(t))}}};!function(){"use strict";qq.canvasToBlob=function(e,n,t){return qq.dataUriToBlob(e.toDataURL(n,t))},qq.dataUriToBlob=function(e){var n,t,r,o,i=function(e,n){var t=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,r=t&&new t;return r?(r.append(e),r.getBlob(n)):new Blob([e],{type:n})};return t=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],n=new ArrayBuffer(t.length),r=new Uint8Array(n),qq.each(t,function(e,n){r[e]=n.charCodeAt(0)}),i(n,o)},qq.log=function(e,n){window.console&&(n&&"info"!==n?window.console[n]?window.console[n](e):window.console.log("<"+n+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var n=Array.prototype.slice.call(arguments,1),t=e,r=t.indexOf("{}");return qq.each(n,function(e,n){var o=t.substring(0,r),i=t.substring(r+2);if(t=o+n+i,r=t.indexOf("{}",r+n.length),r<0)return!1}),t},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,n){var t=function(e){var t=e.toLowerCase();return n?"file"!==t:"file"===t};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&t(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&t(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,n,t){var r=e.slice||e.mozSlice||e.webkitSlice;return r.call(e,n,t)},qq.arrayBufferToHex=function(e){var n="",t=new Uint8Array(e);return qq.each(t,function(e,t){var r=t.toString(16);r.length<2&&(r="0"+r),n+=r}),n},qq.readBlobToHex=function(e,n,t){var r=qq.sliceBlob(e,n,n+t),o=new FileReader,i=new qq.Promise;return o.onload=function(){i.success(qq.arrayBufferToHex(o.result))},o.onerror=i.failure,o.readAsArrayBuffer(r),i},qq.extend=function(e,n,t){return qq.each(n,function(n,r){t&&qq.isObject(r)?(void 0===e[n]&&(e[n]={}),qq.extend(e[n],r,!0)):e[n]=r}),e},qq.override=function(e,n){var t={},r=n(t);return qq.each(r,function(n,r){void 0!==e[n]&&(t[n]=e[n]),e[n]=r}),e},qq.indexOf=function(e,n,t){if(e.indexOf)return e.indexOf(n,t);t=t||0;var r=e.length;for(t<0&&(t+=r);t=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(n){e.innerHTML=n;var t=e.firstChild;return e.removeChild(t),t}}(),qq.each=function(e,n){var t,r;if(e)if(window.Storage&&e.constructor===window.Storage)for(t=0;t0)return e.substr(n,e.length-n)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var n;do n=e.shift(),n&&n();while(n)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(n){e.push(n)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,n=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(n=!1)}catch(e){n=!1}return n}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function r(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function i(){return!!r()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function u(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function c(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var s,l,q,f,d,p,g,v,h,m,y,b,w,x,E;return s=e(),f=s&&qq.isXhrUploadSupported(),l=f&&!qq.androidStock(),q=f&&c(),d=q&&n(),p=f&&qq.isFileChunkingSupported(),g=f&&p&&u(),v=f&&t(),h=s&&(void 0!==window.postMessage||f),y=r(),m=o(),b=i(),w=a(),x=f&&void 0!==window.FileReader,E=function(){return!!f&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:f,blobUploading:l,canDetermineSize:f,chunking:p,deleteFileCors:b,deleteFileCorsXdr:m,deleteFileCorsXhr:y,dialogElement:!!window.HTMLDialogElement,fileDrop:q,folderDrop:d,folderSelection:w,imagePreviews:x,imageValidation:x,itemSizeValidation:f,pause:p,progressBar:E,resume:g,scaling:x&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:s,uploadCors:h,uploadCustomHeaders:f,uploadNonMultipart:f,uploadViaPaste:v}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,n,t=[],r=[],o=[],i=0;qq.extend(this,{then:function(o,a){return 0===i?(o&&t.push(o),a&&r.push(a)):i===-1?a&&a.apply(null,n):o&&o.apply(null,e),this},done:function(t){return 0===i?o.push(t):t.apply(null,void 0===n?e:n),this},success:function(){return i=1,e=arguments,t.length&&qq.each(t,function(n,t){t.apply(null,e)}),o.length&&qq.each(o,function(n,t){t.apply(null,e)}),this},failure:function(){return i=-1,n=arguments,r.length&&qq.each(r,function(e,t){t.apply(null,n)}),o.length&&qq.each(o,function(e,t){t.apply(null,n)}),this}})},qq.DragAndDrop=function(e){"use strict";function n(e,n){var t=Array.prototype.slice.call(e);s.callbacks.dropLog("Grabbed "+e.length+" dropped files."),n.dropDisabled(!1),s.callbacks.processingDroppedFilesComplete(t,n.getElement())}function t(e){var n=new qq.Promise;return e.isFile?e.file(function(t){var r=e.name,o=e.fullPath,i=o.indexOf(r);o=o.substr(0,i),"/"===o.charAt(0)&&(o=o.substr(1)),t.qqPath=o,d.push(t),n.success()},function(t){s.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+t.code+".","error"),n.failure()}):e.isDirectory&&r(e).then(function(e){var r=e.length;qq.each(e,function(e,o){t(o).done(function(){r-=1,0===r&&n.success()})}),e.length||n.success()},function(t){s.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+t.code+".","error"),n.failure()}),n}function r(e,n,t,o){var i=o||new qq.Promise,a=n||e.createReader();return a.readEntries(function(n){var o=t?t.concat(n):n;n.length?setTimeout(function(){r(e,a,o,i)},0):i.success(o)},i.failure),i}function o(e,n){var r=[],o=new qq.Promise;return s.callbacks.processingDroppedFiles(),n.dropDisabled(!0),e.files.length>1&&!s.allowMultipleItems?(s.callbacks.processingDroppedFilesComplete([]),s.callbacks.dropError("tooManyFilesError",""),n.dropDisabled(!1),o.failure()):(d=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,n){var i=n.webkitGetAsEntry();i&&(i.isFile?d.push(n.getAsFile()):r.push(t(i).done(function(){r.pop(),0===r.length&&o.success()})))}):d=e.files,0===r.length&&o.success()),o}function i(e){var t=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:l,element:e,onEnter:function(n){qq(e).addClass(s.classes.dropActive),n.stopPropagation()},onLeaveNotDescendants:function(n){qq(e).removeClass(s.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,t).then(function(){n(d,t)},function(){s.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return p.addDisposer(function(){t.dispose()}),qq(e).hasAttribute(q)&&qq(e).hide(),f.push(t),t}function a(e){var n;return qq.each(e.dataTransfer.types,function(e,t){if("Files"===t)return n=!0,!1}),n}function u(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function c(){var e=s.dropZoneElements,n=function(){setTimeout(function(){qq.each(e,function(e,n){qq(n).hasAttribute(q)&&qq(n).hide(),qq(n).removeClass(s.classes.dropActive)})},10)};qq.each(e,function(n,t){var r=i(t);e.length&&qq.supportedFeatures.fileDrop&&p.attach(document,"dragenter",function(n){!r.dropDisabled()&&a(n)&&qq.each(e,function(e,n){n instanceof HTMLElement&&qq(n).hasAttribute(q)&&qq(n).css({display:"block"})})})}),p.attach(document,"dragleave",function(e){u(e)&&n()}),p.attach(qq(document).children()[0],"mouseenter",function(e){n()}),p.attach(document,"drop",function(e){e.preventDefault(),n()}),p.attach(document,l,n)}var s,l="qq-hidezones",q="qq-hide-dropzone",f=[],d=[],p=new qq.DisposeSupport;s={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(s,e,!0),c(),qq.extend(this,{setupExtraDropzone:function(e){s.dropZoneElements.push(e),i(e)},removeDropzone:function(e){var n,t=s.dropZoneElements;for(n in t)if(t[n]===e)return t.splice(n,1)},dispose:function(){p.dispose(),qq.each(f,function(e,n){n.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,n){},dropError:function(e,n){qq.log("Drag & drop error code '"+e+" with these specifics: '"+n+"'","error")},dropLog:function(e,n){qq.log(e,n)}}},qq.UploadDropZone=function(e){"use strict";function n(){return qq.safari()||qq.firefox()&&qq.windows()}function t(e){l||(n?q.attach(document,"dragover",function(e){e.preventDefault()}):q.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),l=!0)}function r(e){if(!qq.supportedFeatures.fileDrop)return!1;var n,t=e.dataTransfer,r=qq.safari();return n=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==t.effectAllowed,t&&n&&(t.files||!r&&t.types.contains&&t.types.contains("Files"))}function o(e){return void 0!==e&&(s=e),s}function i(){function e(){n=document.createEvent("Event"),n.initEvent(u.HIDE_ZONES_EVENT_NAME,!0,!0)}var n;if(window.CustomEvent)try{n=new CustomEvent(u.HIDE_ZONES_EVENT_NAME)}catch(n){e()}else e();document.dispatchEvent(n)}function a(){q.attach(c,"dragover",function(e){if(r(e)){var n=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===n||"linkMove"===n?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),q.attach(c,"dragenter",function(e){if(!o()){if(!r(e))return;u.onEnter(e)}}),q.attach(c,"dragleave",function(e){if(r(e)){u.onLeave(e);var n=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(n)||u.onLeaveNotDescendants(e)}}),q.attach(c,"drop",function(e){if(!o()){if(!r(e))return;e.preventDefault(),e.stopPropagation(),u.onDrop(e),i()}})}var u,c,s,l,q=new qq.DisposeSupport;u={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(u,e),c=u.element,t(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){q.dispose()},getElement:function(){return c}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var r=new RegExp("(^| )"+t+"( |$)");return r.test(e.className)||!(!n||!r.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var r,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(r=e.getElementsByTagName("*"),qq.each(r,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,r,o,i=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,r=n&&new n;return r?(r.append(e),r.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),r=new Uint8Array(t),qq.each(n,function(e,t){r[e]=t.charCodeAt(0)}),i(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,r=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,r)+t+n.substring(r+2),r=n.indexOf("{}",r+t.length),r<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var r=n.toString(16);r.length<2&&(r="0"+r),t+=r}),t},qq.readBlobToHex=function(e,t,n){var r=qq.sliceBlob(e,t,t+n),o=new FileReader,i=new qq.Promise;return o.onload=function(){i.success(qq.arrayBufferToHex(o.result))},o.onerror=i.failure,o.readAsArrayBuffer(r),i},qq.extend=function(e,t,n){return qq.each(t,function(t,r){n&&qq.isObject(r)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],r,!0)):e[t]=r}),e},qq.override=function(e,t){var n={},r=t(n);return qq.each(r,function(t,r){void 0!==e[t]&&(n[t]=e[t]),e[t]=r}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var r=e.length;for(n<0&&(n+=r);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,r;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function r(){return void 0!==window.XDomainRequest}function o(){return!!n()||r()}function i(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function u(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var c,s,l,q,f,d,p,g,h,v,m,y,b,w,x;return c=e(),q=c&&qq.isXhrUploadSupported(),s=q&&!qq.androidStock(),l=q&&u(),f=l&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),d=q&&qq.isFileChunkingSupported(),p=q&&d&&a(),g=q&&t(),h=c&&(void 0!==window.postMessage||q),m=n(),v=r(),y=o(),b=i(),w=q&&void 0!==window.FileReader,x=function(){return!!q&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:q,blobUploading:s,canDetermineSize:q,chunking:d,deleteFileCors:y,deleteFileCorsXdr:v,deleteFileCorsXhr:m,dialogElement:!!window.HTMLDialogElement,fileDrop:l,folderDrop:f,folderSelection:b,imagePreviews:w,imageValidation:w,itemSizeValidation:q,pause:d,progressBar:x,resume:p,scaling:w&&s,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:c,uploadCors:h,uploadCustomHeaders:q,uploadNonMultipart:q,uploadViaPaste:g}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],r=[],o=[],i=0;qq.extend(this,{then:function(o,a){return 0===i?(o&&n.push(o),a&&r.push(a)):i===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===i?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return i=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return i=-1,t=arguments,r.length&&qq.each(r,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.DragAndDrop=function(e){"use strict";function t(e,t){var n=Array.prototype.slice.call(e);l.callbacks.dropLog("Grabbed "+e.length+" dropped files."),t.dropDisabled(!1),l.callbacks.processingDroppedFilesComplete(n,t.getElement())}function n(e){var t=new qq.Promise;return e.isFile?e.file(function(n){n.qqPath=r(e),f.push(n),t.success()},function(n){l.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+n.code+".","error"),t.failure()}):e.isDirectory&&o(e).then(function(e){var r=e.length;qq.each(e,function(e,o){n(o).done(function(){r-=1,0===r&&t.success()})}),e.length||t.success()},function(n){l.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+n.code+".","error"),t.failure()}),t}function r(e){var t=e.name,n=e.fullPath,r=n.lastIndexOf(t);return n=n.substr(0,r),"/"===n.charAt(0)&&(n=n.substr(1)),n}function o(e,t,n,r){var i=r||new qq.Promise,a=t||e.createReader();return a.readEntries(function(t){var r=n?n.concat(t):t;t.length?setTimeout(function(){o(e,a,r,i)},0):i.success(r)},i.failure),i}function i(e,t){var r=[],o=new qq.Promise;return l.callbacks.processingDroppedFiles(),t.dropDisabled(!0),e.files.length>1&&!l.allowMultipleItems?(l.callbacks.processingDroppedFilesComplete([]),l.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(f=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var i=t.webkitGetAsEntry();i&&(i.isFile?f.push(t.getAsFile()):r.push(n(i).done(function(){r.pop(),0===r.length&&o.success()})))}):f=e.files,0===r.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(l.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(l.classes.dropActive)},onDrop:function(e){i(e.dataTransfer,n).then(function(){t(f,n)},function(){l.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return d.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),q.push(n),n}function u(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function c(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function s(){var e=l.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(l.classes.dropActive)})},10)};qq.each(e,function(t,n){var r=a(n);e.length&&qq.supportedFeatures.fileDrop&&d.attach(document,"dragenter",function(t){!r.dropDisabled()&&u(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),d.attach(document,"dragleave",function(e){c(e)&&t()}),d.attach(qq(document).children()[0],"mouseenter",function(e){t()}),d.attach(document,"drop",function(e){u(e)&&(e.preventDefault(),t())}),d.attach(document,"qq-hidezones",t)}var l,q=[],f=[],d=new qq.DisposeSupport;l={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(l,e,!0),s(),qq.extend(this,{setupExtraDropzone:function(e){l.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=l.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){d.dispose(),qq.each(q,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=r},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){l||(t?q.attach(document,"dragover",function(e){e.preventDefault()}):q.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),l=!0)}function r(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,r=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!r&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(s=e),s}function i(){function e(){t=document.createEvent("Event"),t.initEvent(u.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(u.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){q.attach(c,"dragover",function(e){if(r(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),q.attach(c,"dragenter",function(e){if(!o()){if(!r(e))return;u.onEnter(e)}}),q.attach(c,"dragleave",function(e){if(r(e)){u.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||u.onLeaveNotDescendants(e)}}),q.attach(c,"drop",function(e){if(!o()){if(!r(e))return;e.preventDefault(),e.stopPropagation(),u.onDrop(e),i()}})}var u,c,s,l,q=new qq.DisposeSupport;u={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(u,e),c=u.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){q.dispose()},getElement:function(){return c}}),this._testing={},this._testing.isValidFileDrag=r}}(window); //# sourceMappingURL=dnd.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.min.js.map b/styles/bootstrap/fine-uploader/dnd.min.js.map index 09622593c..3927f6621 100644 --- a/styles/bootstrap/fine-uploader/dnd.min.js.map +++ b/styles/bootstrap/fine-uploader/dnd.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","uploadDroppedFiles","files","uploadDropZone","filesAsArray","options","callbacks","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","code","isDirectory","getFilesInDirectory","entries","entriesLeft","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","classes","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","disposeSupport","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","x","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","onLeave","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.indexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n file.qqPath = fullPath;\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","uploadDroppedFiles","files","uploadDropZone","filesAsArray","options","callbacks","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","code","isDirectory","getFilesInDirectory","entries","entriesLeft","indexOfNameInFullPath","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","classes","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","disposeSupport","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","x","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","_testing","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","onLeave","relatedTarget","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n file.qqPath = extractDirectoryPath(entry);\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n function extractDirectoryPath(entry) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.lastIndexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n return fullPath;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css index 4e3a3b075..ecdadfe0a 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css @@ -1 +1 @@ -.qq-gallery .qq-btn{float:right;border:none;padding:0;margin:0;box-shadow:none}.qq-gallery .qq-upload-button{display:inline;width:105px;padding:7px 10px;float:left;text-align:center;background:#00ABC7;color:#FFF;border-radius:2px;border:1px solid #37B7CC;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-gallery .qq-upload-button-hover{background:#33B6CC}.qq-gallery .qq-upload-button-focus{outline:#000 dotted 1px}.qq-gallery.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;border:1px dashed #CCC;background-color:#FAFAFA;padding:20px}.qq-gallery.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25;filter:alpha(opacity=25)}.qq-gallery .qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#F9F9F9;border-radius:4px;text-align:center}.qq-gallery .qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-gallery .qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-gallery .qq-upload-drop-area-active{background:#FDFDFD;border-radius:4px}.qq-gallery .qq-upload-list{margin:0;padding:10px 0 0;list-style:none;max-height:450px;overflow-y:auto;clear:both;box-shadow:none}.qq-gallery .qq-upload-list li{display:inline-block;position:relative;max-width:120px;margin:0 25px 25px 0;padding:0;line-height:16px;font-size:13px;color:#424242;background-color:#FFF;border-radius:2px;box-shadow:0 1px 1px 0 rgba(0,0,0,.22);vertical-align:top;height:186px}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-failed-text,.qq-gallery .qq-upload-pause,.qq-gallery .qq-upload-retry,.qq-gallery .qq-upload-size,.qq-gallery .qq-upload-spinner{display:inline}.qq-gallery .qq-upload-continue:hover,.qq-gallery .qq-upload-delete:hover,.qq-gallery .qq-upload-pause:hover,.qq-gallery .qq-upload-retry:hover{background-color:transparent}.qq-gallery .qq-upload-cancel,.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{cursor:pointer}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{border:none;background:0 0;color:#00A0BA;font-size:12px;padding:0}.qq-gallery .qq-upload-status-text{color:#333;font-size:12px;padding-left:3px;padding-top:2px;display:none;width:108px}.qq-gallery .qq-upload-fail .qq-upload-status-text{text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;display:block}.qq-gallery .qq-upload-retrying .qq-upload-status-text{display:inline-block}.qq-gallery .qq-upload-retrying .qq-progress-bar-container{display:none}.qq-gallery .qq-upload-cancel{background-color:#525252;color:#F7F7F7;font-weight:700;font-family:Arial,Helvetica,sans-serif;border-radius:12px;border:none;height:22px;width:22px;padding:4px;position:absolute;right:-5px;top:-6px;margin:0;line-height:17px}.qq-gallery .qq-upload-cancel:hover{background-color:#525252}.qq-gallery .qq-upload-retry{cursor:pointer;position:absolute;top:30px;left:50%;margin-left:-31px;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 4px 4px rgba(0,0,0,.5),0 -2px 12px rgba(0,0,0,.08) inset;padding:3px 4px;border:1px solid #d2ddc7;border-radius:2px;color:inherit;background-color:#EBF6E0;z-index:1}.qq-gallery .qq-upload-retry:hover{background-color:#f7ffec}.qq-gallery .qq-file-info{padding:10px 6px 4px;margin-top:-3px;border-radius:0 0 2px 2px;text-align:left;overflow:hidden}.qq-gallery .qq-file-info .qq-file-name{position:relative}.qq-gallery .qq-upload-file{display:block;margin-right:0;margin-bottom:3px;width:auto;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden}.qq-gallery .qq-upload-spinner{display:inline-block;background:url(loading.gif);position:absolute;left:50%;margin-left:-7px;top:53px;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-drop-processing{display:block}.qq-gallery .qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-gallery .qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-gallery .qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-upload-fail .qq-upload-failed-text,.qq-gallery .qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-gallery .qq-upload-list li.qq-upload-success{background-color:#F2F7ED}.qq-gallery .qq-upload-list li.qq-upload-fail{background-color:#F5EDED;box-shadow:0 0 1px 0 red;border:0}.qq-gallery .qq-progress-bar{display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-gallery .qq-total-progress-bar{height:25px;border-radius:9px}.qq-gallery .qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}.qq-gallery .qq-upload-size{float:left;font-size:11px;color:#929292;margin-bottom:3px;margin-right:0;display:inline-block}.qq-gallery INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-gallery .qq-upload-file.qq-editable{cursor:pointer;margin-right:20px}.qq-gallery .qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer;position:absolute;right:0;top:0}.qq-gallery INPUT.qq-edit-filename.qq-editing{position:static;height:28px;width:90px;width:-moz-available;padding:0 8px;margin-bottom:3px;border:1px solid #ccc;border-radius:2px;font-size:13px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-gallery .qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-continue-icon,.qq-gallery .qq-delete-icon,.qq-gallery .qq-pause-icon,.qq-gallery .qq-retry-icon{width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-delete-icon{background:url(trash.gif)}.qq-gallery .qq-retry-icon{background:url(retry.gif);float:none}.qq-gallery .qq-continue-icon{background:url(continue.gif)}.qq-gallery .qq-pause-icon{background:url(pause.gif)}.qq-gallery .qq-hide{display:none}.qq-gallery .qq-in-progress .qq-thumbnail-wrapper{opacity:.5;filter:alpha(opacity=50)}.qq-gallery .qq-thumbnail-wrapper{overflow:hidden;position:relative;height:120px;width:120px}.qq-gallery .qq-thumbnail-selector{border-radius:2px 2px 0 0;bottom:0;top:0;margin:auto;display:block}:root *>.qq-gallery .qq-thumbnail-selector{position:relative;top:50%;transform:translateY(-50%);-moz-transform:translateY(-50%);-ms-transform:translateY(-50%);-webkit-transform:translateY(-50%)}.qq-gallery.qq-uploader DIALOG{display:none}.qq-gallery.qq-uploader DIALOG[open]{display:block}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-gallery.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-gallery .qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-gallery.min.css.map */ \ No newline at end of file +.qq-gallery .qq-btn{float:right;border:none;padding:0;margin:0;box-shadow:none}.qq-gallery .qq-upload-button{display:inline;width:105px;padding:7px 10px;float:left;text-align:center;background:#00abc7;color:#fff;border-radius:2px;border:1px solid #37b7cc;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-gallery .qq-upload-button-hover{background:#33b6cc}.qq-gallery .qq-upload-button-focus{outline:1px dotted #000}.qq-gallery.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;border:1px dashed #ccc;background-color:#fafafa;padding:20px}.qq-gallery.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25}.qq-gallery .qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#f9f9f9;border-radius:4px;text-align:center}.qq-gallery .qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-gallery .qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-gallery .qq-upload-drop-area-active{background:#fdfdfd;border-radius:4px}.qq-gallery .qq-upload-list{margin:0;padding:10px 0 0;list-style:none;max-height:450px;overflow-y:auto;clear:both;box-shadow:none}.qq-gallery .qq-upload-list li{display:inline-block;position:relative;max-width:120px;margin:0 25px 25px 0;padding:0;line-height:16px;font-size:13px;color:#424242;background-color:#fff;border-radius:2px;box-shadow:0 1px 1px 0 rgba(0,0,0,.22);vertical-align:top;height:186px}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-failed-text,.qq-gallery .qq-upload-pause,.qq-gallery .qq-upload-retry,.qq-gallery .qq-upload-size,.qq-gallery .qq-upload-spinner{display:inline}.qq-gallery .qq-upload-continue:hover,.qq-gallery .qq-upload-delete:hover,.qq-gallery .qq-upload-pause:hover,.qq-gallery .qq-upload-retry:hover{background-color:transparent}.qq-gallery .qq-upload-cancel,.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{cursor:pointer}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{border:none;background:0 0;color:#00a0ba;font-size:12px;padding:0}.qq-gallery .qq-upload-status-text{color:#333;font-size:12px;padding-left:3px;padding-top:2px;width:inherit;display:none;width:108px}.qq-gallery .qq-upload-fail .qq-upload-status-text{text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;display:block}.qq-gallery .qq-upload-retrying .qq-upload-status-text{display:inline-block}.qq-gallery .qq-upload-retrying .qq-progress-bar-container{display:none}.qq-gallery .qq-upload-cancel{background-color:#525252;color:#f7f7f7;font-weight:700;font-family:Arial,Helvetica,sans-serif;border-radius:12px;border:none;height:22px;width:22px;padding:4px;position:absolute;right:-5px;top:-6px;margin:0;line-height:17px}.qq-gallery .qq-upload-cancel:hover{background-color:#525252}.qq-gallery .qq-upload-retry{cursor:pointer;position:absolute;top:30px;left:50%;margin-left:-31px;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 4px 4px rgba(0,0,0,.5),0 -2px 12px rgba(0,0,0,.08) inset;padding:3px 4px;border:1px solid #d2ddc7;border-radius:2px;color:inherit;background-color:#ebf6e0;z-index:1}.qq-gallery .qq-upload-retry:hover{background-color:#f7ffec}.qq-gallery .qq-file-info{padding:10px 6px 4px;margin-top:-3px;border-radius:0 0 2px 2px;text-align:left;overflow:hidden}.qq-gallery .qq-file-info .qq-file-name{position:relative}.qq-gallery .qq-upload-file{display:block;margin-right:0;margin-bottom:3px;width:auto;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden}.qq-gallery .qq-upload-spinner{display:inline-block;background:url(loading.gif);position:absolute;left:50%;margin-left:-7px;top:53px;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-drop-processing{display:block}.qq-gallery .qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-gallery .qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-gallery .qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-upload-fail .qq-upload-failed-text{display:inline}.qq-gallery .qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-gallery .qq-upload-list li.qq-upload-success{background-color:#f2f7ed}.qq-gallery .qq-upload-list li.qq-upload-fail{background-color:#f5eded;box-shadow:0 0 1px 0 red;border:0}.qq-gallery .qq-progress-bar{display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-gallery .qq-total-progress-bar{height:25px;border-radius:9px}.qq-gallery .qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}.qq-gallery .qq-upload-size{float:left;font-size:11px;color:#929292;margin-bottom:3px;margin-right:0;display:inline-block}.qq-gallery INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-gallery .qq-upload-file.qq-editable{cursor:pointer;margin-right:20px}.qq-gallery .qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer;position:absolute;right:0;top:0}.qq-gallery INPUT.qq-edit-filename.qq-editing{position:static;height:28px;width:90px;width:-moz-available;padding:0 8px;margin-bottom:3px;border:1px solid #ccc;border-radius:2px;font-size:13px;opacity:1}.qq-gallery .qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-delete-icon{background:url(trash.gif);width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-retry-icon{background:url(retry.gif);width:15px;height:15px;vertical-align:sub;display:inline-block;float:none}.qq-gallery .qq-continue-icon{background:url(continue.gif);width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-pause-icon{background:url(pause.gif);width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-hide{display:none}.qq-gallery .qq-in-progress .qq-thumbnail-wrapper{/* makes the spinner on top of the thumbnail more visible */opacity:.5}.qq-gallery .qq-thumbnail-wrapper{overflow:hidden;position:relative;height:120px;width:120px}.qq-gallery .qq-thumbnail-selector{border-radius:2px 2px 0 0;bottom:0;top:0;margin:auto;display:block}:root *>.qq-gallery .qq-thumbnail-selector{position:relative;top:50%;transform:translateY(-50%);-moz-transform:translateY(-50%);-ms-transform:translateY(-50%);-webkit-transform:translateY(-50%)}.qq-gallery.qq-uploader DIALOG{display:none}.qq-gallery.qq-uploader DIALOG[open]{display:block}.qq-gallery.qq-uploader DIALOG{display:none}.qq-gallery.qq-uploader DIALOG[open]{display:block}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-gallery.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-gallery .qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-gallery.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map index 41f0bbeb0..762454e29 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader-gallery.css"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader-gallery.css"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css index 58422f2f6..40bcea0a0 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css @@ -1 +1 @@ -.qq-btn,.qq-upload-button{box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-btn{padding:3px 4px;border:1px solid #CCC;border-radius:2px;color:inherit;background-color:#FFF}.qq-upload-delete{background-color:#e65c47;color:#FAFAFA;border-color:#dc523d;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-delete:hover{background-color:#f56b56}.qq-upload-cancel{background-color:#F5D7D7;border-color:#e6c8c8}.qq-upload-cancel:hover{background-color:#ffe1e1}.qq-upload-retry{background-color:#EBF6E0;border-color:#d2ddc7}.qq-upload-retry:hover{background-color:#f7ffec}.qq-upload-continue,.qq-upload-pause{background-color:#00ABC7;color:#FAFAFA;border-color:#2dadc2;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-continue:hover,.qq-upload-pause:hover{background-color:#0fbad6}.qq-upload-button{display:inline;width:105px;margin-bottom:10px;padding:7px 10px;text-align:center;float:left;background:#00ABC7;color:#FFF;border-radius:2px;border:1px solid #2dadc2}.qq-upload-button-hover{background:#33B6CC}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;background-color:#FDFDFD;border:1px dashed #CCC;padding:20px}.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#F9F9F9;border-radius:4px;border:1px dashed #CCC;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FDFDFD;border-radius:4px;border:1px dashed #CCC}.qq-upload-list{margin:0;padding:0;list-style:none;max-height:450px;overflow-y:auto;box-shadow:0 1px 0 rgba(15,15,50,.14);clear:both}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;color:#424242;background-color:#F6F6F6;border-top:1px solid #FFF;border-bottom:1px solid #DDD}.qq-upload-list li:first-child{border-top:none}.qq-upload-list li:last-child{border-bottom:none}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-file{vertical-align:middle;display:inline-block;width:300px;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;height:18px}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400;cursor:pointer;vertical-align:middle}.qq-upload-status-text{font-size:14px;font-weight:700;display:block}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text,.qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-upload-list li.qq-upload-success{background-color:#EBF6E0;color:#424242;border-bottom:1px solid #D3DED1;border-top:1px solid #F7FFF5}.qq-upload-list li.qq-upload-fail{background-color:#F5D7D7;color:#424242;border-bottom:1px solid #DECACA;border-top:1px solid #FCE6E6}.qq-progress-bar{display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer;margin-right:4px}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;height:28px;padding:0 8px;margin-right:10px;margin-bottom:-5px;border:1px solid #ccc;border-radius:2px;font-size:16px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:16px}.qq-thumbnail-selector{vertical-align:middle;margin-right:12px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-new.min.css.map */ \ No newline at end of file +.qq-btn{box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset;padding:3px 4px;border:1px solid #ccc;border-radius:2px;color:inherit;background-color:#fff}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-delete{background-color:#e65c47;color:#fafafa;border-color:#dc523d;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-delete:hover{background-color:#f56b56}.qq-upload-cancel{background-color:#f5d7d7;border-color:#e6c8c8}.qq-upload-cancel:hover{background-color:#ffe1e1}.qq-upload-retry{background-color:#ebf6e0;border-color:#d2ddc7}.qq-upload-retry:hover{background-color:#f7ffec}.qq-upload-continue,.qq-upload-pause{background-color:#00abc7;color:#fafafa;border-color:#2dadc2;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-continue:hover,.qq-upload-pause:hover{background-color:#0fbad6}.qq-upload-button{display:inline;width:105px;margin-bottom:10px;padding:7px 10px;text-align:center;float:left;background:#00abc7;color:#fff;border-radius:2px;border:1px solid #2dadc2;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-upload-button-hover{background:#33b6cc}.qq-upload-button-focus{outline:1px dotted #000}.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;background-color:#fdfdfd;border:1px dashed #ccc;padding:20px}.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#f9f9f9;border-radius:4px;border:1px dashed #ccc;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#fdfdfd;border-radius:4px;border:1px dashed #ccc}.qq-upload-list{margin:0;padding:0;list-style:none;max-height:450px;overflow-y:auto;box-shadow:0 1px 0 rgba(15,15,50,.14);clear:both}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;color:#424242;background-color:#f6f6f6;border-top:1px solid #fff;border-bottom:1px solid #ddd}.qq-upload-list li:first-child{border-top:none}.qq-upload-list li:last-child{border-bottom:none}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-file{vertical-align:middle;display:inline-block;width:300px;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;height:18px}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400;cursor:pointer;vertical-align:middle}.qq-upload-status-text{font-size:14px;font-weight:700;display:block}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-upload-list li.qq-upload-success{background-color:#ebf6e0;color:#424242;border-bottom:1px solid #d3ded1;border-top:1px solid #f7fff5}.qq-upload-list li.qq-upload-fail{background-color:#f5d7d7;color:#424242;border-bottom:1px solid #decaca;border-top:1px solid #fce6e6}.qq-progress-bar{display:block;display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer;margin-right:4px}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;height:28px;padding:0 8px;margin-right:10px;margin-bottom:-5px;border:1px solid #ccc;border-radius:2px;font-size:16px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:16px}.qq-hide{display:none}.qq-thumbnail-selector{vertical-align:middle;margin-right:12px}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-new.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map index 2dab29aa6..4ef57d350 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader-new.css"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader-new.css"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.core.js b/styles/bootstrap/fine-uploader/fine-uploader.core.js index 3a6c70071..229a128e1 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.core.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.core.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { var qq = function(element) { "use strict"; @@ -585,7 +585,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -603,9 +603,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -643,7 +640,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -903,7 +904,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -925,6 +927,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -941,6 +944,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -993,6 +1002,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1073,7 +1083,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1150,7 +1167,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1199,6 +1226,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1225,6 +1255,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1247,6 +1281,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1262,6 +1297,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1289,6 +1327,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1299,20 +1359,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1547,17 +1609,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1582,7 +1655,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1659,6 +1741,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -1760,7 +1845,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -1781,6 +1867,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -1933,7 +2041,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2006,19 +2114,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2078,6 +2176,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2173,7 +2276,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2322,6 +2425,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2329,8 +2433,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2358,7 +2464,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2411,9 +2517,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2421,6 +2538,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2519,7 +2639,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2537,6 +2657,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2606,7 +2727,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -2869,13 +2990,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -2894,13 +3016,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); diff --git a/styles/bootstrap/fine-uploader/fine-uploader.core.js.map b/styles/bootstrap/fine-uploader/fine-uploader.core.js.map index 48155fa23..5777241c4 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.core.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.core.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler"],"mappings":"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","file":"fine-uploader.core.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function u(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var l,c,d,p,f,q,h,m,g,_,b,v,S,w,y;return l=e(),p=l&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&u(),f=d&&t(),q=p&&qq.isFileChunkingSupported(),h=p&&q&&s(),m=p&&n(),g=l&&(void 0!==window.postMessage||p),b=i(),_=o(),v=r(),S=a(),w=p&&void 0!==window.FileReader,y=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:v,deleteFileCorsXdr:_,deleteFileCorsXhr:b,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:f,folderSelection:S,imagePreviews:w,imageValidation:w,itemSizeValidation:p,pause:q,progressBar:y,resume:h,scaling:w&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:l,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return u[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function f(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function h(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=v.push(e);if(s<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,f=p.normalizeResponse(n,!1);f.reset?l.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,f,r)||p.cleanup(t,f,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,f=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&u.onResume(e,n,a)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===f.length?l.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),u.onUploadChunk(e,n,o._getChunkDataForCallback(a)),f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](u,{getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t),a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);l[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(h("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;h(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){h("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(h("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||h("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,f=r.inputName,q=s.getUuid,h=s.log,m=new qq.WindowReceiveMessage({log:h});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",f),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(h("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){h("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){h("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,u=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,l=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,h=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),u&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,l(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,u);return d[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=l(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){u&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(u&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);u&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,l(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(u&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:l(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=l(e),a={simple:function(t,n){var i=c(e);t===n?h(e,r,i,i):h(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,d=a,p=c(e),f=l-(d-i),q=u;s[t]=f,qq.each(s,function(e,t){q+=t}),h(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,f=u.width,q=u.height,h=s.getContext("2d"),m=new qq.Promise;return h.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:f}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:f,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",f,q,c.newWidth,c.newHeight),"warn"),f=c.newWidth,q=c.newHeight)),a(s,f,q,u.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*f/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===f?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===f&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function f(e,r,s){var u=new qq.Promise,c=s.scale,f=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,f):d(e,r,u,f):p(e,r,u,f):n(r)?d(e,r,u,f):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),f(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,u,l,c=a.slice(0,4),p=e?n(c):parseInt(c,16),f=o.indexOf(p);if(f>=0&&(u=d[p].name,l=d[p].bytes,s=a.slice(i,i+2*l),r[u]=e?n(s):parseInt(s,16),o.splice(f,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,f=[],q=d.blob?d.blob:d,h=new qq.Identify(q,t);return h.isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});f.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),f.push({uuid:e,name:c,size:q.size,blob:i?q:null})):f.push({uuid:e,name:c,size:q.size,blob:q}),f},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,f=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),f.addReadOnly(t,n)}),l.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,f.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,f,p,h,q,m,g,_,b,v,S,w;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),f=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),p=d&&qq.isFileChunkingSupported(),h=d&&p&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),b=o(),v=r(),S=d&&void 0!==window.FileReader,w=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:p,deleteFileCors:b,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:f,folderSelection:v,imagePreviews:S,imageValidation:S,itemSizeValidation:d,pause:p,progressBar:w,resume:h,scaling:S&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e]&&S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function f(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function p(e){return function(){s(e)}}function h(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){if(S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},v.push(e)<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=f.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),f.cleanup(e,s,a)},function(t,o){var r=f.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||f.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,p=f.normalizeResponse(n,!1);if(p.reset)l.reset(t);else{var h=o._getFileState(t).chunking.inProgress;d=h?qq.indexOf(h,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,p,r)||f.cleanup(t,p,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),p=d.attemptingResume,h=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),p&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),p=!1),null==r&&0===h.length)l.finalize(e);else{h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:p};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=f.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],f.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),f.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=f.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),f.maybeNewUuid(e,r),f.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=f.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||f.cleanup(e,r,o)})}},f={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),f.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),f.maybeSendDeferredFiles(e),c.free(e)}),!1):f.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(f.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,f.now(i);else if(f.isDeferredEligibleForUpload(i))return!1})):(n=!0,f.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=f.normalizeResponse(n.responseJSON,!1);f.cleanup(e,o)}})},start:function(e){var t=f.getProxyOrBlob(e);return t?f.maybeDefer(e,t):(f.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&f.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?f.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){f.cancel(e)}):t!==!1&&f.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),f.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],f&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[h(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},f=r.isCors,p=r.inputName,h=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",p),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;f?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,f=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,f=c[t]||qq.sliceBlob(r,s,u);return c[t]=f,{part:t,start:s,end:u,count:l,blob:f,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=p(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:f(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,f=d(e),p=l-(c-i),h=u;s[t]=p,qq.each(s,function(e,t){h+=t}),m(e,r,h,f)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,f=n.naturalHeight,p=u.width,h=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:f,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:h,targetWidth:p}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:p,origHeight:h}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",p,h,c.newWidth,c.newHeight),"warn"),p=c.newWidth,h=c.newHeight)),a(s,p,h,u.orientation),qq.ios()?function(){e(n)&&(d/=2,f/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,f):1,c=Math.ceil(a*p/d),m=Math.ceil(a*h/f/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===p?function(){var t=e.src;n(r.srcImage,r.blob,i,f).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===p&&o(this.srcImage,this.blob,e,i,f),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,f=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;f.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),f.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function f(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function p(e,r,s){var u=new qq.Promise,c=s.scale,p=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?f(e,r,u,p):d(e,r,u,p):f(e,r,u,p):n(r)?d(e,r,u,p):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),p(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),f=i.indexOf(c);if(f>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(f,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var f=this,p=[],h=d.blob?d.blob:d;return new qq.Identify(h,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=f._determineOutputType({defaultType:r,requestedType:i.type,refType:h.type});p.push({uuid:qq.getUniqueId(),name:f._getName(c,{name:i.name,type:l,refType:h.type}),blob:new qq.BlobProxy(h,qq.bind(f._generateScaledImage,f,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),p.push({uuid:e,name:c,size:h.size,blob:i?h:null})):p.push({uuid:e,name:c,size:h.size,blob:h}),p},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,f=s.uploadData,p=s.paramsStore,h=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=f.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:h}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):f.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:f.retrieve({id:c}).uuid,qqparentsize:f.retrieve({id:c}).size};n[a]=f.retrieve({id:t}).uuid,f.setParentId(t,c),p.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=f.retrieve({id:c}).uuid,p.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){f(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(f(e,0,i),n[e]={loaded:0,total:i})},f=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){f(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5533,12 +5793,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5566,6 +5821,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5653,9 +5916,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5695,8 +5955,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5721,6 +5983,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -5773,7 +6037,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -5856,6 +6120,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6584,7 +6850,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6716,7 +6982,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -6780,15 +7046,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -6894,13 +7160,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -6912,6 +7178,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -6921,7 +7188,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } @@ -7411,4 +7678,4 @@ }); }; })(window); -//# sourceMappingURL=fine-uploader.js.map +//# sourceMappingURL=fine-uploader.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.js.map b/styles/bootstrap/fine-uploader/fine-uploader.js.map index f04b96e4a..a87518cba 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA;ICEV,IAAIC,KAAK,SAASC;QACd;QAEA;YACIC,MAAM;gBACFD,QAAQE,MAAMC,UAAU;gBACxB,OAAOC;;YAIXC,QAAQ,SAASC,MAAMC;gBACnB,IAAIP,QAAQQ,kBAAkB;oBAC1BR,QAAQQ,iBAAiBF,MAAMC,IAAI;uBAChC,IAAIP,QAAQS,aAAa;oBAC5BT,QAAQS,YAAY,OAAOH,MAAMC;;gBAErC,OAAO;oBACHR,GAAGC,SAASU,OAAOJ,MAAMC;;;YAIjCG,QAAQ,SAASJ,MAAMC;gBACnB,IAAIP,QAAQW,qBAAqB;oBAC7BX,QAAQW,oBAAoBL,MAAMC,IAAI;uBACnC,IAAIP,QAAQS,aAAa;oBAC5BT,QAAQY,YAAY,OAAON,MAAMC;;gBAErC,OAAOH;;YAGXS,UAAU,SAASC;gBAKf,KAAKA,YAAY;oBACb,OAAO;;gBAIX,IAAId,YAAYc,YAAY;oBACxB,OAAO;;gBAGX,IAAId,QAAQa,UAAU;oBAClB,OAAOb,QAAQa,SAASC;uBACrB;oBAEH,UAAUA,WAAWC,wBAAwBf,WAAW;;;YAOhEgB,cAAc,SAASC;gBACnBA,SAASC,WAAWF,aAAahB,SAASiB;gBAC1C,OAAOb;;YAGXe,QAAQ;gBACJnB,QAAQkB,WAAWE,YAAYpB;gBAC/B,OAAOI;;YAOXiB,KAAK,SAASC;gBAEV,IAAItB,QAAQE,SAAS,MAAM;oBACvB,MAAM,IAAIH,GAAGwB,MAAM;;gBAIvB,IAAID,OAAOE,WAAW,MAAM;oBACxB,WAAWxB,QAAQE,MAAMsB,YAAY,mBAAoBxB,QAAe,YAAM,aAAa;wBACvFsB,OAAOG,SAAS,mBAAmBC,KAAKC,MAAM,MAAML,OAAOE,WAAW;;;gBAG9EzB,GAAG6B,OAAO5B,QAAQE,OAAOoB;gBAEzB,OAAOlB;;YAGXyB,UAAU,SAASC,MAAMC;gBACrB,IAAIC,KAAK,IAAIC,OAAO,UAAUH,OAAO;gBACrC,OAAOE,GAAGE,KAAKlC,QAAQmC,iBAAiBJ,kBAAkBC,GAAGE,KAAKlC,QAAQkB,WAAWiB;;YAGzFC,UAAU,SAASN;gBACf,KAAK/B,GAAGC,SAAS6B,SAASC,OAAO;oBAC7B9B,QAAQmC,aAAa,MAAML;;gBAE/B,OAAO1B;;YAGXiC,aAAa,SAASP;gBAClB,IAAIE,KAAK,IAAIC,OAAO,UAAUH,OAAO;gBACrC9B,QAAQmC,YAAYnC,QAAQmC,UAAUG,QAAQN,IAAI,KAAKM,QAAQ,cAAc;gBAC7E,OAAOlC;;YAGXmC,YAAY,SAASJ,WAAWK;gBAC5B,IAAIC,YACAC;gBAEJ,IAAIF,SAASxC,QAAQ2C,eAAe;oBAChC,OAAO3C,QAAQ2C,cAAc,MAAMR;uBAElC,IAAInC,QAAQ4C,kBAAkB;oBAC/B,OAAO5C,QAAQ4C,iBAAiB,MAAMT;;gBAG1CM,aAAazC,QAAQ6C,qBAAqB;gBAE1C9C,GAAG+C,KAAKL,YAAY,SAASM,KAAKC;oBAC9B,IAAIjD,GAAGiD,KAAKnB,SAASM,YAAY;wBAC7BO,OAAOO,KAAKD;;;gBAGpB,OAAOR,QAAQE,OAAO,KAAKA;;YAG/BQ,iBAAiB,SAASf;gBACtB,OAAOpC,GAAGC,SAASuC,WAAWJ,WAAW;;YAG7CgB,UAAU;gBACN,IAAIA,eACAC,QAAQpD,QAAQqD;gBAEpB,OAAOD,OAAO;oBACV,IAAIA,MAAME,aAAa,GAAG;wBACtBH,SAASF,KAAKG;;oBAElBA,QAAQA,MAAMG;;gBAGlB,OAAOJ;;YAGXK,SAAS,SAASC;gBACdzD,QAAQ0D,YAAYD;gBACpBzD,QAAQ2D,cAAcF;gBACtB,OAAOrD;;YAGXwD,WAAW;gBACP,OAAO7D,GAAGC,SAASwD,QAAQ;;YAK/BK,cAAc,SAASC;gBACnB,IAAIC;gBAEJ,IAAI/D,QAAQ6D,cAAc;oBAEtB,KAAK7D,QAAQ6D,aAAaC,WAAW;wBACjC,OAAO;;oBAIX,OAAO,WAAaE,KAAKhE,QAAQiE,aAAaH,cAAc;uBAE3D;oBACDC,UAAU/D,QAAQ8D;oBAElB,IAAIC,YAAYG,WAAW;wBACvB,OAAO;;oBAIX,OAAO,WAAaF,KAAKD,YAAY;;;;;KAMpD;QACG;QAEAhE,GAAGoE,eAAe,SAASC,QAAQC,MAAMC;YACrC,OAAOvE,GAAGwE,cAAcH,OAAOI,UAAUH,MAAMC;;QAGnDvE,GAAGwE,gBAAgB,SAASE;YACxB,IAAIC,aAAaC,YACbC,aAAa,SAASC,MAAMR;gBACxB,IAAIS,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;gBAErC,IAAIK,aAAa;oBACbA,YAAYC,OAAOP;oBACnB,OAAOM,YAAYE,QAAQhB;uBAE1B;oBACD,OAAO,IAAIiB,OAAMT;wBAAQvE,MAAM+D;;;eAGvCkB,UAAUC;YAGd,IAAIf,QAAQgB,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cf,aAAagB,KAAKlB,QAAQgB,MAAM,KAAK;mBAEpC;gBACDd,aAAaiB,UAAUnB,QAAQgB,MAAM,KAAK;;YAI9CD,aAAaf,QAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBf,cAAc,IAAImB,YAAYlB,WAAWmB;YACzCP,WAAW,IAAIQ,WAAWrB;YAC1B3E,GAAG+C,KAAK6B,YAAY,SAAS5B,KAAKiD;gBAC9BT,SAASxC,OAAOiD,UAAUC,WAAW;;YAGzC,OAAOrB,WAAWF,aAAac;;QAGnCzF,GAAGmG,MAAM,SAASC,SAASC;YACvB,IAAIrB,OAAOsB,SAAS;gBAChB,KAAKD,SAASA,UAAU,QAAQ;oBAC5BrB,OAAOsB,QAAQH,IAAIC;uBAGvB;oBACI,IAAIpB,OAAOsB,QAAQD,QAAQ;wBACvBrB,OAAOsB,QAAQD,OAAOD;2BAErB;wBACDpB,OAAOsB,QAAQH,IAAI,MAAME,QAAQ,OAAOD;;;;;QAMxDpG,GAAGuG,WAAW,SAASC;YACnB,OAAOA,aAAaA,SAASjD,YAAYkD,OAAOC,UAAUC,SAASC,KAAKJ,cAAc;;QAG1FxG,GAAG6G,aAAa,SAASL;YACrB,cAAc,aAAe;;QASjCxG,GAAG8G,UAAU,SAASC;YAClB,OAAON,OAAOC,UAAUC,SAASC,KAAKG,WAAW,oBAC5CA,SAAS/B,OAAOc,eAAeiB,MAAMC,UAAUD,MAAMC,OAAOC,gBAAgBnB;;QAIrF9F,GAAGkH,aAAa,SAASC;YACrB,OAAOV,OAAOC,UAAUC,SAASC,KAAKO,mBAAmB;;QAK7DnH,GAAGoH,aAAa,SAASC;YACrB,OAAOZ,OAAOC,UAAUC,SAASC,KAAKS,mBAAmB,uBAGpDA,cAAcC,QAAQD,cAAcE;;QAG7CvH,GAAGwH,WAAW,SAASC;YACnB,OAAOhB,OAAOC,UAAUC,SAASC,KAAKa,iBAAiB;;QAG3DzH,GAAG0H,UAAU,SAASC;YAClB,IAAIC,OAAOlB,UAAUmB,MAAM;gBACvB,OAAOF,OAAOE;;YAGlB,OAAOF,OAAOpF,QAAQ,cAAc;;QAOxCvC,GAAG8H,SAAS,SAASC;YAEjB,IAAIC,OAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW,IAC9CC,SAASL,KACTM,mBAAmBD,OAAOzC,QAAQ;YAEtC3F,GAAG+C,KAAKiF,MAAM,SAAShF,KAAKC;gBACxB,IAAIqF,YAAYF,OAAOG,UAAU,GAAGF,mBAChCG,WAAWJ,OAAOG,UAAUF,mBAAmB;gBAEnDD,SAASE,YAAYrF,MAAMuF;gBAC3BH,mBAAmBD,OAAOzC,QAAQ,MAAM0C,mBAAmBpF,IAAI8C;gBAG/D,IAAIsC,mBAAmB,GAAG;oBACtB,OAAO;;;YAIf,OAAOD;;QAGXpI,GAAGyI,SAAS,SAASC;YACjB,OAAO1D,OAAO2D,QAAQlC,OAAOC,UAAUC,SAASC,KAAK8B,eAAe;;QAGxE1I,GAAG4I,aAAa,SAASC;YACrB,OAAO7D,OAAO8D,YAAYrC,OAAOC,UAAUC,SAASC,KAAKiC,mBAAmB;;QAGhF7I,GAAG+I,gBAAgB,SAASC;YACxB,OAAOhJ,GAAGyI,OAAOO,qBAAqBhJ,GAAGiJ,QAAQD;;QAGrDhJ,GAAGiJ,UAAU,SAASC,YAAYC;YAC9B,IAAIC,eAAe,SAAS7I;gBACxB,IAAI8I,iBAAiB9I,KAAK+I;gBAE1B,IAAIH,SAAS;oBACT,OAAOE,mBAAmB;;gBAG9B,OAAOA,mBAAmB;;YAG9B,IAAIrE,OAAOuE,kBAAkB;gBACzB,IAAI9C,OAAOC,UAAUC,SAASC,KAAKsC,gBAAgB,6BAA6B;oBAC5E,IAAIA,WAAW3I,QAAQ6I,aAAaF,WAAW3I,OAAO;wBAClD,OAAO;;;;YAInB,IAAI2I,WAAWM,SAAS;gBACpB,IAAIN,WAAWM,QAAQF,kBAAkB,SAAS;oBAC9C,IAAIJ,WAAW3I,QAAQ6I,aAAaF,WAAW3I,OAAO;wBAClD,OAAO;;;;YAKnB,OAAO;;QAGXP,GAAGyJ,SAAS,SAASC;YACjB,IAAI1E,OAAOO,QAAQkB,OAAOC,UAAUC,SAASC,KAAK8C,eAAe,iBAAiB;gBAC9E,OAAO;;;QAIf1J,GAAG2J,uBAAuB;YACtB,IAAIC,QAAQC,SAASC,cAAc;YACnCF,MAAMrJ,OAAO;YAEb,OACIqJ,MAAMG,aAAa5F,oBACRwE,SAAS,sBACTqB,aAAa,sBACZhK,GAAGiK,oBAAqBC,WAAW;;QAIvDlK,GAAGiK,oBAAoB;YACnB,IAAIjF,OAAOmF,gBAAgB;gBACvB,OAAO,IAAIA;;YAGf;gBACI,OAAO,IAAIC,cAAc;cAE7B,OAAOC;gBACHrK,GAAGmG,IAAI,yCAAyC;gBAChD,OAAO;;;QAIfnG,GAAGsK,wBAAwB,SAASC;YAChC,OAAOA,aAAaC,SAChBD,aAAaC,MAAMzE,SAAS,KAC5BwE,aAAaC,MAAM,GAAGC;;QAG9BzK,GAAG0K,0BAA0B;YACzB,QAAQ1K,GAAG2K,kBACP3K,GAAG2J,2BACFhB,KAAKjC,UAAUwB,UAAU/D,aAAawE,KAAKjC,UAAUkE,gBAAgBzG,aAAawE,KAAKjC,UAAUmE,aAAa1G;;QAGvHnE,GAAG8K,YAAY,SAASC,YAAYC,OAAOC;YACvC,IAAIC,SAASH,WAAW7C,SAAS6C,WAAWF,YAAYE,WAAWH;YAEnE,OAAOM,OAAOtE,KAAKmE,YAAYC,OAAOC;;QAG1CjL,GAAGmL,mBAAmB,SAASnE;YAC3B,IAAIoE,aAAa,IACbC,QAAQ,IAAIrF,WAAWgB;YAE3BhH,GAAG+C,KAAKsI,OAAO,SAASrI,KAAKsI;gBACzB,IAAIC,eAAeD,IAAI3E,SAAS;gBAEhC,IAAI4E,aAAaxF,SAAS,GAAG;oBACzBwF,eAAe,MAAMA;;gBAGzBH,cAAcG;;YAGlB,OAAOH;;QAGXpL,GAAGwL,gBAAgB,SAASC,MAAMC,aAAa3F;YAC3C,IAAI4F,cAAc3L,GAAG8K,UAAUW,MAAMC,aAAaA,cAAc3F,SAC5D6F,aAAa,IAAIC,cACjBC,UAAU,IAAI9L,GAAG+L;YAErBH,WAAWI,SAAS;gBAChBF,QAAQG,QAAQjM,GAAGmL,iBAAiBS,WAAWjJ;;YAGnDiJ,WAAWM,UAAUJ,QAAQK;YAE7BP,WAAWQ,kBAAkBT;YAE7B,OAAOG;;QAGX9L,GAAG6B,SAAS,SAASY,OAAO4J,QAAQC;YAChCtM,GAAG+C,KAAKsJ,QAAQ,SAASE,MAAMtJ;gBAC3B,IAAIqJ,gBAAgBtM,GAAGuG,SAAStD,MAAM;oBAClC,IAAIR,MAAM8J,UAAUpI,WAAW;wBAC3B1B,MAAM8J;;oBAEVvM,GAAG6B,OAAOY,MAAM8J,OAAOtJ,KAAK;uBAE3B;oBACDR,MAAM8J,QAAQtJ;;;YAItB,OAAOR;;QAaXzC,GAAGwM,WAAW,SAASC,QAAQC;YAC3B,IAAIC,aACAC,SAASF,SAASC;YAEtB3M,GAAG+C,KAAK6J,QAAQ,SAASC,aAAaC;gBAClC,IAAIL,OAAOI,iBAAiB1I,WAAW;oBACnCwI,OAAOE,eAAeJ,OAAOI;;gBAGjCJ,OAAOI,eAAeC;;YAG1B,OAAOL;;QAMXzM,GAAG2F,UAAU,SAASoH,KAAKC,KAAKC;YAC5B,IAAIF,IAAIpH,SAAS;gBACb,OAAOoH,IAAIpH,QAAQqH,KAAKC;;YAG5BA,OAAOA,QAAQ;YACf,IAAIC,MAAMH,IAAIhH;YAEd,IAAIkH,OAAO,GAAG;gBACVA,QAAQC;;YAGZ,MAAOD,OAAOC,KAAKD,QAAQ,GAAG;gBAC1B,IAAIF,IAAII,eAAeF,SAASF,IAAIE,UAAUD,KAAK;oBAC/C,OAAOC;;;YAGf,QAAQ;;QAIZjN,GAAGoN,cAAc;YACb,OAAO,uCAAuC7K,QAAQ,SAAS,SAAS8K;gBAEpE,IAAIC,IAAI3L,KAAK4L,WAAW,KAAK,GAAGC,IAAIH,KAAK,MAAMC,IAAKA,IAAI,IAAM;gBAC9D,OAAOE,EAAE7G,SAAS;;;QAM1B3G,GAAGyN,KAAK;YACJ,OAAOC,UAAUC,UAAUhI,QAAQ,aAAa,KAC5C+H,UAAUC,UAAUhI,QAAQ,gBAAgB;;QAGpD3F,GAAG4N,MAAM;YACL,OAAOF,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG6N,MAAM;YACL,OAAOH,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG8N,OAAO;YACN,OAAOJ,UAAUC,UAAUhI,QAAQ,gBAAgB;;QAGvD3F,GAAG+N,OAAO;YACN,OAAO/N,GAAGyN,QAAQC,UAAUC,UAAUhI,QAAQ,cAAc;;QAGhE3F,GAAGgO,OAAO;YACN,OAAON,UAAUC,UAAUhI,QAAQ,WAAW;;QAGlD3F,GAAGiO,SAAS;YACR,OAAOP,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,cAAc;;QAGpF3F,GAAGmO,SAAS;YACR,OAAOT,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,eAAe;;QAGrF3F,GAAGoO,QAAQ;YACP,OAAOV,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,cAAc;;QAGpF3F,GAAGqO,UAAU;YACT,QAASrO,GAAGgO,WAAWhO,GAAG+N,UAAUL,UAAUC,UAAUhI,QAAQ,gBAAgB,KAAK+H,UAAUQ,WAAW/J,aAAauJ,UAAUQ,WAAW;;QAGhJlO,GAAGsO,UAAU;YACT,OAAOZ,UAAUa,aAAa;;QAGlCvO,GAAGwO,UAAU;YACT,OAAOd,UAAUC,UAAUrE,cAAc3D,QAAQ,gBAAgB;;QAKrE3F,GAAG2K,eAAe;YACd,OAAO3K,GAAGwO,aAAad,UAAUC,UAAUrE,cAAc3D,QAAQ,YAAY;;QAGjF3F,GAAGyO,OAAO;YACN,OAAOzO,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGlE3F,GAAG2O,OAAO;YACN,OAAO3O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGlE3F,GAAG4O,OAAO;YACN,OAAO5O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAIlE3F,GAAG6O,SAAS;YACR,OAAO7O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,iBAAiB;;QAGpE3F,GAAG0O,MAAM;YAEL,OAAOhB,UAAUC,UAAUhI,QAAQ,aAAa,KACzC+H,UAAUC,UAAUhI,QAAQ,aAAa,KACzC+H,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG8O,YAAY;YACX,OAAO9O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,cAAc;;QAGjE3F,GAAG+O,YAAY;YACX,OAAO/O,GAAG0O,UAAU1O,GAAG8O,eAAepB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGrF3F,GAAGgP,mBAAmB;YAClB,OAAOhP,GAAG0O,UAAU1O,GAAG8O,gBAAgB9O,GAAG+O;;QAM9C/O,GAAGiP,iBAAiB,SAASC;YACzB,IAAIA,EAAED,gBAAgB;gBAClBC,EAAED;mBACC;gBACHC,EAAEC,cAAc;;;QAQxBnP,GAAGoP,YAAa;YACZ,IAAIC,MAAMxF,SAASC,cAAc;YACjC,OAAO,SAASwF;gBACZD,IAAIE,YAAYD;gBAChB,IAAIrP,UAAUoP,IAAI/L;gBAClB+L,IAAIhO,YAAYpB;gBAChB,OAAOA;;;QAKfD,GAAG+C,OAAO,SAASyM,cAAcC;YAC7B,IAAIC,YAAYC;YAEhB,IAAIH,cAAc;gBAEd,IAAIxK,OAAO4K,WAAWJ,aAAavI,gBAAgBjC,OAAO4K,SAAS;oBAC/D,KAAKF,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASD,aAAaK,IAAIH,aAAaF,aAAaM,QAAQN,aAAaK,IAAIH;wBACtF,IAAIC,WAAW,OAAO;4BAClB;;;uBAMP,IAAI3P,GAAG8G,QAAQ0I,iBAAiBxP,GAAGkH,WAAWsI,iBAAiBxP,GAAGoH,WAAWoI,eAAe;oBAC7F,KAAKE,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASC,YAAYF,aAAaE;wBAC3C,IAAIC,WAAW,OAAO;4BAClB;;;uBAIP,IAAI3P,GAAGwH,SAASgI,eAAe;oBAChC,KAAKE,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASC,YAAYF,aAAaO,OAAOL;wBAClD,IAAIC,WAAW,OAAO;4BAClB;;;uBAIP;oBACD,KAAKD,cAAcF,cAAc;wBAC7B,IAAI/I,OAAOC,UAAUyG,eAAevG,KAAK4I,cAAcE,aAAa;4BAChEC,SAASF,SAASC,YAAYF,aAAaE;4BAC3C,IAAIC,WAAW,OAAO;gCAClB;;;;;;;QASxB3P,GAAGgQ,OAAO,SAASC,SAASC;YACxB,IAAIlQ,GAAG6G,WAAWoJ,UAAU;gBACxB,IAAIjI,OAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW;gBAElD,OAAO;oBACH,IAAIgI,UAAUnQ,GAAG6B,WAAWmG;oBAC5B,IAAIG,UAAUpC,QAAQ;wBAClBoK,UAAUA,QAAQC,OAAOnI,MAAMvB,UAAUwB,MAAMtB,KAAKuB;;oBAExD,OAAO8H,QAAQI,MAAMH,SAASC;;;YAItC,MAAM,IAAI3O,MAAM;;QAmBpBxB,GAAGsQ,UAAU,SAASC,KAAKC,MAAMC;YAE7B,IAAIC,iBACAC,SAAS,KACTC,MAAM,SAASC,SAASC;gBACpB,IAAIC,WAAWP,OACR,QAAQrO,KAAKqO,QACdA,OACAA,OAAO,MAAMM,IAAI,MACjBA;gBACN,IAAKC,aAAa,eAAiBD,MAAM,aAAc;oBACnDJ,WAAWxN,YACC2N,YAAY,WACd7Q,GAAGsQ,QAAQO,SAASE,UAAU,QAC7BtK,OAAOC,UAAUC,SAASC,KAAKiK,aAAa,sBAC7CG,mBAAmBD,YAAY,MAAMC,mBAAmBH,aACxDG,mBAAmBD,YAAY,MAAMC,mBAAmBH;;;YAK9E,KAAKJ,cAAcD,MAAM;gBACrBG,SAAU,KAAKxO,KAAKqO,QAAU,MAAMrO,KAAKqO,QAAS,KAAK,MAAM;gBAC7DE,WAAWxN,KAAKsN;gBAChBE,WAAWxN,KAAKlD,GAAGsQ,QAAQC;mBACxB,IAAK9J,OAAOC,UAAUC,SAASC,KAAK2J,SAAS,2BAA6BA,QAAQ,aAAc;gBACnGvQ,GAAG+C,KAAKwN,KAAK,SAASvN,KAAKC;oBACvB2N,IAAI3N,KAAKD;;mBAEV,WAAYuN,QAAQ,eAAiBA,QAAQ,eAAiBA,QAAQ,UAAW;gBACpFvQ,GAAG+C,KAAKwN,KAAK,SAAShE,MAAMtJ;oBACxB2N,IAAI3N,KAAKsJ;;mBAEV;gBACHmE,WAAWxN,KAAK8N,mBAAmBR,QAAQ,MAAMQ,mBAAmBT;;YAGxE,IAAIC,MAAM;gBACN,OAAOE,WAAWO,KAAKN;mBACpB;gBACH,OAAOD,WAAWO,KAAKN,QAClBpO,QAAQ,MAAM,IACdA,QAAQ,QAAQ;;;QAI7BvC,GAAGkR,eAAe,SAASX,KAAKY,UAAUC;YACtC,KAAKD,UAAU;gBACXA,WAAW,IAAInH;;YAGnBhK,GAAG+C,KAAKwN,KAAK,SAASV,KAAK5M;gBACvB4M,MAAMuB,eAAeA,eAAe,MAAMvB,MAAM,MAAMA;gBAEtD,IAAI7P,GAAGuG,SAAStD,MAAM;oBAClBjD,GAAGkR,aAAajO,KAAKkO,UAAUtB;uBAE9B,IAAI7P,GAAG6G,WAAW5D,MAAM;oBACzBkO,SAAS9L,OAAOwK,KAAK5M;uBAEpB;oBACDkO,SAAS9L,OAAOwK,KAAK5M;;;YAI7B,OAAOkO;;QAGXnR,GAAGqR,aAAa,SAASd,KAAKe;YAC1B,IAAI1H;YAEJ,KAAK0H,MAAM;gBACPA,OAAOzH,SAASC,cAAc;;YAGlC9J,GAAGkR,aAAaX;gBACZlL,QAAQ,SAASwK,KAAK5M;oBAClB2G,QAAQC,SAASC,cAAc;oBAC/BF,MAAM2H,aAAa,QAAQ1B;oBAC3BjG,MAAM2H,aAAa,SAAStO;oBAC5BqO,KAAKE,YAAY5H;;;YAIzB,OAAO0H;;QAOXtR,GAAGyR,YAAY,SAASC;YAEpB,IAAI1M,OAAO2M,QAAQ3R,GAAG6G,WAAW8K,KAAKC,QAAQ;gBAC1C,OAAOD,KAAKC,MAAMF;mBACf;gBACH,OAAOG,KAAK,MAAMH,OAAO;;;QAUjC1R,GAAG8R,eAAe,SAASC;YACvB,IAAIC,SAASD,SAASE,YAAY,OAAO;YAEzC,IAAID,SAAS,GAAG;gBACZ,OAAOD,SAASG,OAAOF,QAAQD,SAAShM,SAASiM;;;QAIzDhS,GAAGmS,cAAc,SAASC;YAGtB,IAAIpS,GAAGiJ,QAAQmJ,kBAAkB;gBAE7B,OAAOA,gBAAgBrL,MAAMxE,QAAQ,aAAa;mBAEjD,IAAIvC,GAAGyI,OAAO2J,kBAAkB;gBACjC,IAAIA,gBAAgBC,aAAa,QAAQD,gBAAgBC,aAAalO,WAAW;oBAC7E,OAAOiO,gBAAgBC;;;YAI/B,OAAOD,gBAAgBrQ;;QAM3B/B,GAAGsS,iBAAiB;YAChB,IAAIC;YAEJ;gBAEIC,SAAS;oBACL,IAAIC;oBACJ,GAAG;wBACCA,WAAWF,UAAUG;wBACrB,IAAID,UAAU;4BACVA;;6BAGDA;;gBAIXnS,QAAQ;oBACJ,IAAI0H,OAAOG;oBAEX9H,KAAKsS,YAAY3S,GAAGgI,KAAK,IAAI1H,OAAO+P,MAAMhQ,MAAM4H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW;;gBAI1FwK,aAAa,SAASC;oBAClBL,UAAUrP,KAAK0P;;;;;KCt2B9B;QACG;QACA,WAAWC,WAAW,cAAcA,OAAOC,KAAK;YAC5CD,OAAO;gBACH,OAAO7S;;eAGV,WAAW+S,WAAW,eAAeA,OAAOC,SAAS;YACtDD,OAAOC,UAAUhT;eAEhB;YACDD,OAAOC,KAAKA;;;KCRnB;QACG;QAEAA,GAAGwB,QAAQ,SAAS4E;YAChB/F,KAAK+F,UAAU,oBAAoBpG,GAAGiT,UAAU,OAAO7M;;QAG3DpG,GAAGwB,MAAMkF,YAAY,IAAIlF;;ICV7BxB,GAAGiT,UAAU;ICAbjT,GAAGkT,oBAAqB;QACpB;QAEA,IAAIC,mBACAC,wBACAC,kBACAC,2BACAC,oBACAC,kBACAC,gBACAC,wBACAC,oBACAC,uBACAC,2BACAC,wBACAC,yBACAC,uBACAC;QAEJ,SAASC;YACL,IAAIC,YAAY,MACZC;YAEJ;gBACIA,YAAYvK,SAASC,cAAc;gBACnCsK,UAAU7T,OAAO;gBACjBP,GAAGoU,WAAWlU;gBAEd,IAAIkU,UAAUC,UAAU;oBACpBF,YAAY;;cAGpB,OAAOG;gBACHH,YAAY;;YAGhB,OAAOA;;QAIX,SAASI;YACL,QAAQvU,GAAGmO,YAAYnO,GAAGoO,YACtBV,UAAUC,UAAU6G,MAAM,2CAA2CrQ;;QAI7E,SAASsQ;YACL,QAAQzU,GAAGmO,YAAYnO,GAAGoO,YACtBV,UAAUC,UAAU6G,MAAM,2CAA2CrQ;;QAI7E,SAASuQ;YACL,IAAI1P,OAAOmF,gBAAgB;gBACvB,IAAIwK,MAAM3U,GAAGiK;gBAGb,OAAO0K,IAAIC,oBAAoBzQ;;YAGnC,OAAO;;QAIX,SAAS0Q;YACL,OAAO7P,OAAO8P,mBAAmB3Q;;QAKrC,SAAS4Q;YACL,IAAIL,6BAA6B;gBAC7B,OAAO;;YAGX,OAAOG;;QAGX,SAASG;YAEL,OAAOnL,SAASC,cAAc,SAASmL,oBAAoB9Q;;QAG/D,SAAS+Q;YACL;gBACI,SAASlQ,OAAOmQ,gBAEZnV,GAAG6G,WAAW7B,OAAOmQ,aAAaC;cAE1C,OAAO/K;gBAEH,OAAO;;;QAIf,SAASgL;YACL,IAAIC,OAAOzL,SAASC,cAAc;YAElC,QAAQ,eAAewL,QAAS,iBAAiBA,QAAQ,YAAYA,UAChEtV,GAAGwO,cAAcxO,GAAG0O;;QAG7ByE,oBAAoBe;QAEpBZ,4BAA4BH,qBAAqBnT,GAAG2J;QAEpDyJ,yBAAyBE,8BAA8BtT,GAAG2K;QAE1D0I,mBAAmBC,6BAA6B+B;QAEhD9B,qBAAqBF,oBAAoBkB;QAEzCf,mBAAmBF,6BAA6BtT,GAAG0K;QAEnD+I,iBAAiBH,6BAA6BE,oBAAoB0B;QAElExB,yBAAyBJ,6BAA6BmB;QAEtDd,qBAAqBR,sBAAsBnO,OAAOuQ,gBAAgBpR,aAAamP;QAE/EO,4BAA4Ba;QAE5Bd,wBAAwBiB;QAExBf,yBAAyBiB;QAEzBhB,0BAA0BiB;QAE1BhB,wBAAwBV,6BAA6BtO,OAAO6G,eAAe1H;QAE3E8P,yBAA0B;YACtB,IAAIX,2BAA2B;gBAC3B,QAAQtT,GAAG2K,mBAAmB3K,GAAG8O;;YAErC,OAAO;;QAGX;YACI0G,eAAelC;YACfmC,eAAerC;YACfsC,kBAAkBpC;YAClBqC,UAAUnC;YACVoC,gBAAgB9B;YAChB+B,mBAAmBjC;YACnBkC,mBAAmBjC;YACnBkC,iBAAiB/Q,OAAOgR;YACxBC,UAAU5C;YACV6C,YAAY3C;YACZ4C,iBAAiBpC;YACjBqC,eAAepC;YACfqC,iBAAiBrC;YACjBsC,oBAAoBhD;YACpBiD,OAAO/C;YACPgD,aAAavC;YACbwC,QAAQhD;YACRiD,SAAS1C,yBAAyBZ;YAClCuD,cAAc3W,GAAGiO;YACjB2I,2BAA2B5W,GAAG0O;YAC9BmI,WAAW1D;YACX2D,YAAYnD;YACZoD,qBAAqBzD;YACrB0D,oBAAoB1D;YACpB2D,gBAAgBvD;;;IChKxB1T,GAAGkX,mBAAmB,SAASC;QAC3B;QACA,UAAUA,gBAAgBA,aAAaC,QAAQpX,GAAG6G,WAAWsQ,aAAaC;;IAG9EpX,GAAG+L,UAAU;QACT;QAEA,IAAIsL,aAAaC,aACbC,uBACAC,uBACAC,oBACAC,QAAQ;QAEZ1X,GAAG6B,OAAOxB;YACN+W,MAAM,SAASO,WAAWC;gBACtB,IAAIF,UAAU,GAAG;oBACb,IAAIC,WAAW;wBACXJ,iBAAiBrU,KAAKyU;;oBAE1B,IAAIC,WAAW;wBACXJ,iBAAiBtU,KAAK0U;;uBAGzB,IAAIF,WAAW,GAAG;oBACnBE,aAAaA,UAAUvH,MAAM,MAAMiH;uBAElC,IAAIK,WAAW;oBAChBA,UAAUtH,MAAM,MAAMgH;;gBAG1B,OAAOhX;;YAGXwX,MAAM,SAASpI;gBACX,IAAIiI,UAAU,GAAG;oBACbD,cAAcvU,KAAKuM;uBAElB;oBACDA,SAASY,MAAM,MAAMiH,gBAAgBnT,YAAYkT,cAAcC;;gBAGnE,OAAOjX;;YAGX4L,SAAS;gBACLyL,QAAQ;gBACRL,cAAclP;gBAEd,IAAIoP,iBAAiBxR,QAAQ;oBACzB/F,GAAG+C,KAAKwU,kBAAkB,SAASvU,KAAKyM;wBACpCA,SAASY,MAAM,MAAMgH;;;gBAI7B,IAAII,cAAc1R,QAAQ;oBACtB/F,GAAG+C,KAAK0U,eAAe,SAASzU,KAAKyM;wBACjCA,SAASY,MAAM,MAAMgH;;;gBAI7B,OAAOhX;;YAGX8L,SAAS;gBACLuL,SAAS;gBACTJ,cAAcnP;gBAEd,IAAIqP,iBAAiBzR,QAAQ;oBACzB/F,GAAG+C,KAAKyU,kBAAkB,SAASxU,KAAKyM;wBACpCA,SAASY,MAAM,MAAMiH;;;gBAI7B,IAAIG,cAAc1R,QAAQ;oBACtB/F,GAAG+C,KAAK0U,eAAe,SAASzU,KAAKyM;wBACjCA,SAASY,MAAM,MAAMiH;;;gBAI7B,OAAOjX;;;;IC3EnBL,GAAG8X,YAAY,SAASC,eAAeC;QACnC;QAEAhY,GAAG6B,OAAOxB;YACN0X,eAAeA;YAEfE,QAAQ;gBACJ,OAAOD,SAASD;;;;ICF5B/X,GAAGkY,eAAe,SAASC;QACvB;QAEA,IAAIC,OAAO/X,MAEPgY,iBAAiB,IAAIrY,GAAGsS,kBAExBgG;YAEIC,aAAa;YAGbtY,SAAS;YAETuY,YAAY;YAGZC,SAAS;YAGTC,YAAY;YAEZC,4BAA4B;YAG5B5O,UAAU;YAGVhI,MAAM;YAGN6W,UAAU,SAAShP;YAEnBiP,OAAO;WAEXjP,OAAOkP;QAGX9Y,GAAG6B,OAAOyW,SAASH;QAEnBW,WAAW9Y,GAAGoN;QAGd,SAAS2L;YACL,IAAInP,QAAQC,SAASC,cAAc;YAEnCF,MAAM2H,aAAavR,GAAGkY,aAAac,qBAAqBF;YACxDlP,MAAM2H,aAAa,SAAS+G,QAAQO;YAEpCT,KAAKa,YAAYX,QAAQvO,UAAUH;YAEnC,IAAI0O,QAAQG,WAAWzY,GAAGkT,kBAAkBiD,iBAAiB;gBAEzDvM,MAAM2H,aAAa,mBAAmB;;YAG1C,IAAI+G,QAAQC,aAAa;gBACrB3O,MAAM2H,aAAa,UAAU+G,QAAQC;;YAGzC3O,MAAM2H,aAAa,QAAQ;YAC3B3H,MAAM2H,aAAa,QAAQ+G,QAAQvW;YAEnC/B,GAAG4J,OAAOtI;gBACN4X,UAAU;gBAIVC,OAAO;gBACPC,KAAK;gBACLC,YAAY;gBASZC,UAAUtZ,GAAGyN,SAASzN,GAAG6N,QAAQ,WAAW;gBAC5C0L,QAAQ;gBACRC,SAAS;gBACTC,QAAQ;gBACRhY,SAAS;;aAKZzB,GAAG4N,SAAS5N,GAAG4J,OAAOtI;gBAAKoY,QAAQ;;YAEpCpB,QAAQrY,QAAQuR,YAAY5H;YAE5ByO,eAAe/X,OAAOsJ,OAAO,UAAU;gBACnC0O,QAAQM,SAAShP;;YAIrByO,eAAe/X,OAAOsJ,OAAO,aAAa;gBACtC5J,GAAGsY,QAAQrY,SAASoC,SAASiW,QAAQI;;YAEzCL,eAAe/X,OAAOsJ,OAAO,YAAY;gBACrC5J,GAAGsY,QAAQrY,SAASqC,YAAYgW,QAAQI;;YAG5CL,eAAe/X,OAAOsJ,OAAO,SAAS;gBAClC5J,GAAGsY,QAAQrY,SAASoC,SAASiW,QAAQE;;YAEzCH,eAAe/X,OAAOsJ,OAAO,QAAQ;gBACjC5J,GAAGsY,QAAQrY,SAASqC,YAAYgW,QAAQE;;YAG5C,OAAO5O;;QAIX5J,GAAGsY,QAAQrY,SAASqB;YAChB4X,UAAU;YACVS,UAAU;YAEVC,WAAW;;QAIf5Z,GAAG6B,OAAOxB;YACNwZ,UAAU;gBACN,OAAOjQ;;YAGXkQ,aAAa;gBACT,OAAOhB;;YAGXG,aAAa,SAASc,YAAYC;gBAC9B,IAAIpQ,QAAQoQ,YAAY3Z,KAAKwZ;gBAK7B,IAAIvB,QAAQK,8BAA8B3Y,GAAG4O,WAAW5O,GAAG8O,eAAe9O,GAAGgP,qBAAqB;oBAC9FpF,MAAM2H,aAAa,YAAY;uBAG9B;oBACD,IAAIwI,YAAY;wBACZnQ,MAAM2H,aAAa,YAAY;2BAE9B;wBACD3H,MAAMqQ,gBAAgB;;;;YAKlCC,gBAAgB,SAAS3B;gBACrB,IAAIA,gBAAgBD,QAAQC,aAAa;oBACrC3O,MAAM2H,aAAa,UAAUgH;;;YAIrC4B,OAAO;gBACH,IAAIvQ,MAAMzI,YAAY;oBAClBnB,GAAG4J,OAAOxI;;gBAGdpB,GAAGsY,QAAQrY,SAASqC,YAAYgW,QAAQE;gBACxC5O,QAAQ;gBACRA,QAAQmP;;;QAIhBnP,QAAQmP;;IAGZ/Y,GAAGkY,aAAac,sBAAsB;ICxLtChZ,GAAGoa,aAAa,SAASC;QACrB;QAEA,IAAIvV,WACAwV,aACAC,eACAC,qBACAC;QAEJ,SAASC,aAAaC;YAClB,IAAI3a,GAAG8G,QAAQ6T,UAAU;gBACrB,IAAIC;gBAEJ5a,GAAG+C,KAAK4X,SAAS,SAAS3X,KAAK6X;oBAC3BD,QAAQ1X,KAAK4B,KAAK+V;;gBAGtB,OAAOD;;YAGX,OAAO9V,KAAK6V;;QAGhB,SAASG,eAAeC;YACpB,IAAI/a,GAAG8G,QAAQiU,QAAQ;gBACnB,IAAIH;gBAEJ5a,GAAG+C,KAAKgY,OAAO,SAAS/X,KAAKgY;oBACzBJ,QAAQ1X,KAAK4B,KAAKwV,OAAOU;;gBAG7B,OAAOJ;;YAGX,OAAO9V,KAAKwV,OAAOS;;QAGvB,SAASE,gBAAgBC;YACrB,IAAIC,oBACAC,cAAchL,OAAO8K;YAEzBlb,GAAG+C,KAAKqY,UAAU,SAASC,OAAOC;gBAC9B,IAAIC,sBAAsBhB,SAASe;gBAEnC,IAAIC,wBAAwBpX,WAAW;oBACnCnE,GAAG+C,KAAKwY,qBAAqB,SAASzK,GAAG0K;wBACrCL,cAAcjY,KAAK4B,KAAK0W;;;;YAKpC,OAAOL;;QAGXnb,GAAG6B,OAAOxB;YAeNob,SAAS,SAASC;gBACd,IAAIR,SAASQ,KAAKR,UAAUlb,GAAGkb,OAAOS,YAClCd,KAAK/V,KAAK5B;oBACNnB,MAAM2Z,KAAK3Z;oBACX6Z,cAAcF,KAAK3Z;oBACnBiZ,MAAMU,KAAKV;oBACXa,MAAMH,KAAKG,QAAQ,QAAQ,IAAIH,KAAKG;oBACpCX,QAAQA;qBACP;gBAET,IAAIQ,KAAKI,SAAS;oBACdhX,KAAK+V,IAAIiB,UAAUJ,KAAKI;oBAExB,IAAIrB,UAAUiB,KAAKI,aAAa3X,WAAW;wBACvCsW,UAAUiB,KAAKI;;oBAEnBrB,UAAUiB,KAAKI,SAAS5Y,KAAK2X;;gBAGjC,IAAIa,KAAKK,cAAc;oBACnBjX,KAAK+V,IAAIkB,eAAeL,KAAKK;oBAE7B,IAAIvB,eAAekB,KAAKK,kBAAkB5X,WAAW;wBACjDqW,eAAekB,KAAKK;;oBAExBvB,eAAekB,KAAKK,cAAc7Y,KAAK2X;;gBAG3C/V,KAAK+V,IAAIA,KAAKA;gBACdP,OAAOoB,KAAKV,QAAQH;gBAEpB,IAAIN,SAASW,YAAY/W,WAAW;oBAChCoW,SAASW;;gBAEbX,SAASW,QAAQhY,KAAK2X;gBAEtBR,cAAc2B,eAAenB,IAAI,MAAMK;gBAEvC,OAAOL;;YAGXoB,UAAU,SAASC;gBACf,IAAIlc,GAAGuG,SAAS2V,mBAAmBpX,KAAKiB,QAAS;oBAC7C,IAAImW,eAAerB,OAAO1W,WAAW;wBACjC,OAAOuW,aAAawB,eAAerB;2BAGlC,IAAIqB,eAAelB,SAAS7W,WAAW;wBACxC,OAAO2W,eAAeoB,eAAelB;2BAGpC,IAAIkB,eAAehB,QAAQ;wBAC5B,OAAOD,gBAAgBiB,eAAehB;;uBAGzC;oBACD,OAAOlb,GAAG6B,WAAWiD,MAAM;;;YAInCqV,OAAO;gBACHrV;gBACAwV;gBACAC;gBACAE;;YAGJ0B,WAAW,SAAStB,IAAIuB;gBACpB,IAAIC,YAAYvX,KAAK+V,IAAIK,QACrBoB,yBAAyBtc,GAAG2F,QAAQ4U,SAAS8B,YAAYxB;gBAE7DN,SAAS8B,WAAWE,OAAOD,wBAAwB;gBAEnDxX,KAAK+V,IAAIK,SAASkB;gBAElB,IAAI7B,SAAS6B,eAAejY,WAAW;oBACnCoW,SAAS6B;;gBAEb7B,SAAS6B,WAAWlZ,KAAK2X;gBAEzBR,cAAc2B,eAAenB,IAAIwB,WAAWD;;YAGhDI,aAAa,SAAS3B,IAAI4B;gBACtB,IAAIC,UAAU5X,KAAK+V,IAAIG;gBAEvBlW,KAAK+V,IAAIG,OAAOyB;gBAChBnC,OAAOmC,WAAW5B;uBACXP,OAAOoC;;YAGlBC,YAAY,SAAS9B,IAAI+B;gBACrB9X,KAAK+V,IAAI9Y,OAAO6a;;YAGpBC,YAAY,SAAShC,IAAIiC;gBACrBhY,KAAK+V,IAAIgB,OAAOiB;;YAIpBC,aAAa,SAASC,UAAUC;gBAC5BnY,KAAKkY,UAAUC,WAAWA;;YAG9BC,oBAAoB,SAASrC;gBACzB,IAAIkB,eAAejX,KAAK+V,IAAIkB;gBAE5B,IAAIA,cAAc;oBACd,OAAOvB,eAAeuB;;gBAE1B;;YAGJoB,eAAe,SAAStC;gBACpB,IAAIiB,UAAUhX,KAAK+V,IAAIiB;gBAEvB,OAAOrB,UAAUqB;;;;IAK7B9b,GAAGkb;QACCS,YAAY;QACZyB,WAAW;QACXC,UAAU;QACVC,QAAQ;QACRC,UAAU;QACVC,QAAQ;QACRC,WAAW;QACXC,iBAAiB;QACjBC,mBAAmB;QACnBC,eAAe;QACfC,eAAe;QACfC,UAAU;QACVC,SAAS;;KCxMZ;QACG;QAEA/d,GAAGge;YAECC,UAAU,SAASC,iBAAiBC,QAAQC;gBACxC/d,KAAKge,SAASH,iBAAiBC,QAAQC;;YAG3CE,iBAAiB,SAASC;gBACtB,IAAInG,OAAO/X;gBAEXL,GAAG+C,KAAKwb,gBAAgB,SAASlD,OAAOmD;oBACpCpG,KAAKqG,eAAeD;;;YAI5BH,UAAU,SAASvZ,MAAMqZ,QAAQC;gBAC7B/d,KAAKqe;gBAEL,IAAI5C,UAAUzb,KAAKse,WAAW5Y,WAAW,IAAI/F,GAAGoN,gBAAgB/M,KAAKue,iBAEjEC,cAAc7e,GAAGgQ,KAAK,SAASvE;oBAC3BpL,KAAKye;wBACDrT,MAAMA;wBACN1J,MAAM1B,KAAK0e,SAASC,MAAMC;uBAC3BnD,SAASoD;mBACb7e,OAEH8e,kBAAkBnf,GAAGgQ,KAAK,SAASoP;oBAC/B/e,KAAKye,eAAeM,UAAUtD,SAASoD;mBACxC7e,OAEHgf,gBAAgBrf,GAAGgQ,KAAK,SAAS3L;oBAC7B,IAAIoH,OAAOzL,GAAGoE,aAAaC;oBAE3BhE,KAAKye;wBACDrT,MAAMA;wBACN1J,MAAM1B,KAAK0e,SAASC,MAAMC,cAAc;uBACzCnD,SAASoD;mBACb7e,OAEHif,oBAAoBtf,GAAGgQ,KAAK,SAASuP;oBACjC,IAAIC,oBAAoBD,WAAWhb,WAAWgb,WAAWhb,UAAU,KAC/DkH,OAAOzL,GAAGoE,aAAamb,WAAWlb,QAAQkb,WAAWhf,MAAMif;oBAE/Dnf,KAAKye;wBACDrT,MAAMA;wBACN1J,MAAMwd,WAAWxd;uBAClB+Z,SAASoD;mBACb7e,OAEHof,qBAAqBzf,GAAGgQ,KAAK,SAAS0P;oBAClC,IAAI1f,GAAGiJ,QAAQyW,gBAAgB1f,GAAGkT,kBAAkBsC,eAAe;wBAC/D,IAAImK,QAAQ1X,MAAMvB,UAAUwB,MAAMtB,KAAK8Y,YAAYC,QAC/CvH,OAAO/X;wBAEXL,GAAG+C,KAAK4c,OAAO,SAAS3c,KAAK4c;4BACzBxH,KAAK0G,eAAec,MAAM9D,SAASoD;;2BAGtC;wBACD7e,KAAKye,eAAeY,aAAa5D,SAASoD;;mBAE/C7e,OAEHwf,gBAAgB;oBACZ,IAAI7f,GAAG4I,WAAW9D,OAAO;wBACrBA,OAAOmD,MAAMvB,UAAUwB,MAAMtB,KAAK9B;;oBAEtCA,UAAUsL,OAAOtL;mBAGrBsT,OAAO/X,MACP6e;gBAEJ7e,KAAKue,kBAAkB9C;gBAEvB,IAAIhX,MAAM;oBACN+a;oBAEA7f,GAAG+C,KAAK+B,MAAM,SAAS9B,KAAK8c;wBACxB,IAAI9f,GAAG+I,cAAc+W,gBAAgB;4BACjCL,mBAAmBK;+BAElB,IAAI9f,GAAGyJ,OAAOqW,gBAAgB;4BAC/BjB,YAAYiB;+BAEX,IAAI9f,GAAGuG,SAASuZ,gBAAgB;4BACjC,IAAIA,cAAcrU,QAAQqU,cAAc/d,MAAM;gCAC1Cod,gBAAgBW;mCAEf,IAAIA,cAAczb,UAAUyb,cAAc/d,MAAM;gCACjDud,kBAAkBQ;;+BAGrB,IAAIA,cAActW,WAAWsW,cAActW,QAAQF,kBAAkB,UAAU;4BAChF+V,cAAcS;+BAEb;4BACD1H,KAAKjS,IAAI2Z,gBAAgB,8CAA8C;;;oBAI/Ezf,KAAK8F,IAAI,cAAc+Y,cAAcnZ,SAAS;oBAC9C1F,KAAK0f,uBAAuBb,eAAef,QAAQC;;;YAI3D4B,QAAQ,SAASnF;gBACbxa,KAAK4f,SAASD,OAAOnF;;YAGzBqF,WAAW;gBACP,IAAIC,oBACA/H,OAAO/X;gBAEXL,GAAG6B,OAAOse,eAAe9f,KAAKse;gBAC9B3e,GAAG+C,KAAKod,eAAe,SAASnd,KAAKod;oBACjChI,KAAK4H,OAAOI;;gBAGhB/f,KAAK4f,SAASC;;YAGlBG,kBAAkB;gBACdhgB,KAAKse;;YAGT2B,gBAAgB,SAASzF;gBACrB,IAAI0F,aAAalgB,KAAKmgB,YAAYvE;oBAAUpB,IAAIA;;gBAEhD,KAAK7a,GAAGkT,kBAAkBqD,UAAUlW,KAAK0e,SAASpJ,SAAS8K,SAAS;oBAChE,OAAO;;gBAGX,IAAIF,WAAWrF,WAAWlb,GAAGkb,OAAOsC,QAAQ;oBACxCnd,KAAK8F,IAAInG,GAAG8H,OAAO,0DAA0D+S,IAAIxa,KAAKqgB,QAAQ7F;oBAC9Fxa,KAAKsgB,YAAY9F;oBACjB,OAAO;uBAEN;oBACDxa,KAAK8F,IAAInG,GAAG8H,OAAO,uDAAuD+S,IAAIxa,KAAKqgB,QAAQ7F,MAAM;;gBAGrG,OAAO;;YAGX+F,YAAY,SAAS/F;gBACjB,OAAOxa,KAAKwgB,gBAAgBhG;;YAIhCiG,WAAW,SAASC;gBAChB,OAAO1gB,KAAK4f,SAASe,QAAQD;;YAOjCE,eAAe,SAASC,QAAQC,aAAaC,SAASC,YAAYC;gBAC9D,IAAIC,kBAAkB,IAAIvhB,GAAG+L,WACzByV,WAAWlJ;gBAEf,IAAIjY,KAAKohB,iBAAiB;oBACtBD,YAAYnhB,KAAKqhB,eAAeR;oBAChC5I;wBACIgJ,sBAAsBA;wBACtBF,SAASA,UAAU,IAAIA,UAAU;wBACjCO,OAAOP,UAAU;;oBAKrB,KAAKC,cAAcrhB,GAAGkT,kBAAkBkD,eAAe;wBACnDoL,YAAYnhB,KAAKuhB,QAAQV;;oBAI7B,IAAIM,aAAa,MAAM;wBACnBD,gBAAgBpV;4BAAS0V,WAAWV;4BAAa9W,OAAO;;2BAEvD;wBACDhK,KAAKohB,gBAAgBK,SAASN,WAAWL,aAAa7I,SAASlB,KAC3D,SAASnL,QAAQ8V;4BACbR,gBAAgBtV,QAAQ8V;2BAG5B,SAAS5V,QAAQ0V,WAAWG;4BACxBT,gBAAgBpV;gCAAS0V,WAAWA;gCAAWxX,OAAO2X,UAAU;;;;uBAK3E;oBACDT,gBAAgBpV;wBAAS0V,WAAWV;wBAAa9W,OAAO;;;gBAG5D,OAAOkX;;YAGXU,WAAW,SAASf;gBAChB,OAAO7gB,KAAK6hB,WAAW7hB,KAAK8hB,qBAAqBjB;;YAGrDkB,aAAa,SAASlB;gBAClB,OAAO7gB,KAAKgiB,eAAeC,IAAIpB;;YAGnCU,SAAS,SAASb;gBACd,OAAO1gB,KAAK4f,SAAS2B,QAAQb,iBAAiB;;YAGlDwB,eAAe;gBACX,OAAOliB,KAAKmgB,YAAYvE;oBACpBf,UACIlb,GAAGkb,OAAOuC,WACVzd,GAAGkb,OAAOwC,iBACV1d,GAAGkb,OAAOoC;mBAEfvX;;YAGP2a,SAAS,SAAS7F;gBACd,OAAOxa,KAAKmgB,YAAYvE;oBAAUpB,IAAIA;mBAAK9Y;;YAI/CygB,aAAa,SAAS3H;gBAClB,IAAI4H,kBAAkBpiB,KAAKqiB;oBAAY7H,IAAIA;oBACvCoC,WAAW;gBAEf,IAAIwF,iBAAiB;oBACjB,IAAIA,gBAAgBxF,aAAa9Y,WAAW;wBACxC8Y,WAAWwF,gBAAgBxF;;;gBAInC,OAAOA;;YAGX0F,uBAAuB;gBACnB,OAAOtiB,KAAK4f,SAAS0C;;YAGzBC,SAAS,SAAS/H;gBACd,OAAOxa,KAAKmgB,YAAYvE;oBAAUpB,IAAIA;mBAAKgB;;YAG/CgH,eAAe;gBACX,OAAOxiB,KAAKyiB;;YAGhBC,0BAA0B;gBACtB,IAAIC,eAAe3iB,KAAK4iB;gBAExB,IAAID,eAAe,GAAG;oBAClB,OAAOA,eAAe3iB,KAAK6iB;;gBAG/B,OAAO;;YAGXR,YAAY,SAASxG;gBACjB,OAAO7b,KAAKmgB,YAAYvE,SAASC;;YAGrCiH,SAAS,SAAStI;gBACd,OAAOxa,KAAKmgB,YAAYvE;oBAAUpB,IAAIA;mBAAKG;;YAG/C7U,KAAK,SAAS4B,KAAK1B;gBACf,IAAIhG,KAAK0e,SAASqE,WAAW/c,SAASA,UAAU,SAAS;oBACrDrG,GAAGmG,IAAI,oBAAoBnG,GAAGiT,UAAU,OAAOlL;uBAE9C,IAAI1B,SAASA,UAAU,QAAQ;oBAChCrG,GAAGmG,IAAI,oBAAoBnG,GAAGiT,UAAU,OAAOlL,KAAK1B;;;YAK5Dgd,aAAa,SAASxI;gBAClB,IAAI0F,aAAalgB,KAAKmgB,YAAYvE;oBAAUpB,IAAIA;;gBAEhD,KAAK7a,GAAGkT,kBAAkBqD,UAAUlW,KAAK0e,SAASpJ,SAAS8K,SAAS;oBAChE,OAAO;;gBAIX,IAAIzgB,GAAG2F,UAAS3F,GAAGkb,OAAOuC,WAAWzd,GAAGkb,OAAOwC,mBAAkB6C,WAAWrF,WAAW,GAAG;oBACtF,IAAI7a,KAAK4f,SAAS1J,MAAMsE,KAAK;wBACzBxa,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOsC;wBACzC,OAAO;2BAEN;wBACDnd,KAAK8F,IAAInG,GAAG8H,OAAO,oCAAoC+S,IAAIxa,KAAKqgB,QAAQ7F,MAAM;;uBAGjF;oBACDxa,KAAK8F,IAAInG,GAAG8H,OAAO,yDAAyD+S,IAAIxa,KAAKqgB,QAAQ7F,MAAM;;gBAGvG,OAAO;;YAGXV,OAAO;gBACH9Z,KAAK8F,IAAI;gBAET9F,KAAK4f,SAAS9F;gBACd9Z,KAAKse;gBACLte,KAAKijB;gBACLjjB,KAAKkjB;gBACLljB,KAAKmjB;gBACLnjB,KAAKqhB;gBAEL1hB,GAAG+C,KAAK1C,KAAKojB,UAAU,SAASzgB,KAAK0gB;oBACjCA,OAAOvJ;;gBAGX9Z,KAAKsjB,aAAaxJ;gBAClB9Z,KAAKgiB,eAAelI;gBACpB9Z,KAAK6iB,uBAAuB;gBAC5B7iB,KAAKyiB,eAAe;gBACpBziB,KAAKmgB,YAAYrG;gBACjB9Z,KAAK8hB;gBAEL9hB,KAAKujB,iBAAiBvjB,KAAKujB,cAAczJ;gBACzC9Z,KAAK0e,SAAS8E,QAAQC,kBAAkBzjB,KAAK0jB;gBAE7C1jB,KAAK2jB;gBACL3jB,KAAK4jB;gBAEL5jB,KAAK6jB,kBAAkB7jB,KAAK6jB,eAAe/J;;YAG/CgK,OAAO,SAAStJ;gBACZ,OAAOxa,KAAK+jB,aAAavJ;;YAG7BwJ,YAAY,SAASxJ,IAAIyJ;gBACrB,IAAIlM,OAAO/X;gBAEX,OAAOL,GAAGukB,OAAO7d,UAAU2d,WAAWxJ,IAAIyJ;oBACtCne,KAAKnG,GAAGgQ,KAAKoI,KAAKjS,KAAKiS;oBACvBwJ,SAAS5hB,GAAGgQ,KAAKoI,KAAKwJ,SAASxJ;oBAC/BmI,YAAYnI,KAAKoI;;;YAIzBgE,kBAAkB,SAASC,SAAS5J;gBAChCxa,KAAKqkB,oBAAoBC,IAAIF,SAAS5J;;YAG1C+J,4BAA4B,SAASH,SAAS5J;gBAC1Cxa,KAAKwkB,8BAA8BF,IAAIF,SAAS5J;;YAGpDiK,uBAAuB,SAAS1G,UAAUvD;gBACtCxa,KAAK0kB,yBAAyBJ,IAAIvG,UAAUvD;;YAGhDmK,qBAAqB,SAAS7G,QAAQtD;gBAClCxa,KAAK4kB,uBAAuBN,IAAIxG,QAAQtD;;YAI5CqK,aAAa,SAAS9G,UAAUvD;gBAC5Bxa,KAAKgiB,eAAesC,IAAIvG,UAAUvD;;YAGtCsK,SAAS,SAASC;gBACd/kB,KAAKglB,4BAA4BD;;YAGrCE,cAAc,SAASC;gBACnBllB,KAAK4iB,oBAAoBsC;;YAG7BC,SAAS,SAAS3K,IAAI+B;gBAClBvc,KAAKmgB,YAAY7D,WAAW9B,IAAI+B;;YAGpC6I,WAAW,SAAStH,QAAQtD;gBACxBxa,KAAKsjB,aAAagB,IAAIxG,QAAQtD;;YAGlC6K,SAAS,SAAS7K,IAAI4B;gBAClB,OAAOpc,KAAKmgB,YAAYhE,YAAY3B,IAAI4B;;YAG5CkJ,mBAAmB;gBACf,IAAItlB,KAAKse,WAAW5Y,WAAW,GAAG;oBAC9B1F,KAAKulB,WAAW;uBAEf;oBACDvlB,KAAKwlB;;;;QAQjB7lB,GAAG8lB;YAECrH,gBAAgB,SAASsH;gBACrB,IAAIlL,KAAKxa,KAAKmgB,YAAY/E;oBACtBT,MAAM+K,YAAY/K;oBAClBjZ,MAAMgkB,YAAYhkB;oBAClB8Z,MAAMkK,YAAYlK;oBAClBX,QAAQlb,GAAGkb,OAAOyC;;gBAGtBoI,YAAYC,sBAAsB3lB,KAAKykB,sBAAsBiB,YAAYC,oBAAoBnL;gBAC7FkL,YAAYE,oBAAoB5lB,KAAK2kB,oBAAoBe,YAAYE,kBAAkBpL;gBAEvF,IAAIkL,YAAYG,cAAc;oBAC1B7lB,KAAKqhB,eAAe7G,MAAMkL,YAAYG;;gBAG1C7lB,KAAKyiB;gBACLziB,KAAK6iB;gBAEL,OAAOrI;;YAGXsL,uBAAuB,SAASvG,MAAMwG;gBAClC,IAAIpmB,GAAGyI,OAAOmX,OAAO;oBACjBA,KAAKyG,aAAahmB,KAAKimB,aAAaF;;;YAI5CG,aAAa,SAASngB;gBAClB/F,KAAK0e,SAASyH,UAAUC,QAAQ,MAAM,MAAMrgB,SAASjC;;YAGzDuiB,sBAAsB;gBAClB,IAAItO,OAAO/X;gBAEX,OAAO,IAAIL,GAAG2mB;oBACVC,QAAQvmB,KAAK0e,SAAS6B,WAAWgG,OAAOC;oBACxCC,gBAAgBzmB,KAAK0e,SAAS+H;oBAC9BC,eAAe1mB,KAAK0e,SAASiI,QAAQC;oBACrCC,eAAe7mB,KAAKwkB;oBACpBsC,aAAa9mB,KAAK4kB;oBAClBmC,eAAe/mB,KAAK0kB;oBACpBsC,MAAMhnB,KAAK0e,SAASsI;oBACpBlhB,KAAKnG,GAAGgQ,KAAKoI,KAAKjS,KAAKiS;oBACvBkP,UAAU,SAASzM;wBACfzC,KAAKmP,UAAU1M;wBACfzC,KAAK2G,SAASyH,UAAUc,SAASzM;;oBAErC2M,kBAAkB,SAAS3M,IAAI4M,UAAUC;wBACrCtP,KAAKuP,kBAAkB9M,IAAI4M,UAAUC;wBACrCtP,KAAK2G,SAASyH,UAAUgB,iBAAiB3M,IAAI4M,UAAUC;;;;YAMnEE,qBAAqB;gBACjB,IAAIxP,OAAO/X;gBAEX,OAAO,IAAIL,GAAG6nB;oBACVC,eAAeznB,KAAK0e,SAASgJ,MAAMD;oBACnCtB;wBACIrgB,KAAKnG,GAAGgQ,KAAKoI,KAAKjS,KAAKiS;wBACvB4P,eAAe,SAASvc;4BACpB2M,KAAK6P;gCACDlmB,MAAM;gCACN0N,UAAUzP,GAAGgQ,KAAKoI,KAAK2G,SAASyH,UAAU0B,iBAAiB9P,MAAM3M;gCACjEkM,WAAW3X,GAAGgQ,KAAKoI,KAAK+P,qBAAqB/P,MAAM3M;gCACnD2c,YAAY;;;;;;YAOhCC,cAAc,SAASC,cAAcC;gBACjC,IAAIC,YACAC,WAAWH,cACXI,0BACAC,iBAAiBJ,kBACjBK,OAAO,SAASC;oBACZ,IAAI7oB,GAAGuG,SAASsiB,OAAO;wBACnB,OAAO7oB,GAAG6B,WAAWgnB;;oBAEzB,OAAOA;mBAEXC,oBAAoB;oBAChB,IAAI9oB,GAAG6G,WAAW8hB,iBAAiB;wBAC/B,OAAOA;;oBAEX,OAAOA;mBAEXI,wBAAwB,SAASlO,IAAImO;oBACjC,IAAIL,kBAAkB3oB,GAAGuG,SAASyiB,WAAW;wBACzChpB,GAAG6B,OAAOmnB,UAAUF;;oBAGxB,IAAIJ,oBAAoB7N,KAAK;wBACzB7a,GAAG6B,OAAOmnB,UAAUN,oBAAoB7N;;;gBAIpD;oBACI8J,KAAK,SAAS1hB,KAAK4X;wBAEf,IAAIA,MAAM,MAAM;4BACZ2N;4BACAC,WAAWG,KAAK3lB;+BAEf;4BACDulB,MAAM3N,MAAM+N,KAAK3lB;;;oBAIzBqf,KAAK,SAASzH;wBACV,IAAIoO;wBAGJ,IAAIpO,MAAM,QAAQ2N,MAAM3N,KAAK;4BACzBoO,SAAST,MAAM3N;+BAEd;4BACDoO,SAASL,KAAKH;;wBAGlBM,sBAAsBlO,IAAIoO;wBAE1B,OAAOL,KAAKK;;oBAGhBC,aAAa,SAASrO,IAAIoO;wBAEtB,IAAIjpB,GAAGuG,SAASiiB,QAAQ;4BAEpB,IAAI3N,OAAO,MAAM;gCACb,IAAI7a,GAAG6G,WAAWoiB,SAAS;oCACvBN,iBAAiBM;uCAEhB;oCACDN,iBAAiBA;oCACjB3oB,GAAG6B,OAAO8mB,gBAAgBM;;mCAG7B;gCACDP,oBAAoB7N,MAAM6N,oBAAoB7N;gCAC9C7a,GAAG6B,OAAO6mB,oBAAoB7N,KAAKoO;;;;oBAK/C7nB,QAAQ,SAAS8f;wBACb,cAAcsH,MAAMtH;;oBAGxB/G,OAAO;wBACHqO;wBACAE;wBACAD,WAAWH;;;;YAKvBa,0BAA0B;gBACtB,IAAI/Q,OAAO/X;gBAEX,OAAO,IAAIL,GAAGoa;oBACVsG,SAAS,SAAS7F;wBACd,OAAOzC,KAAKsI,QAAQ7F;;oBAExBsI,SAAS,SAAStI;wBACd,OAAOzC,KAAK+K,QAAQtI;;oBAExB+H,SAAS,SAAS/H;wBACd,OAAOzC,KAAKwK,QAAQ/H;;oBAExBmB,gBAAgB,SAASnB,IAAIwB,WAAWD;wBACpChE,KAAKgR,sBAAsBvO,IAAIwB,WAAWD;wBAC1ChE,KAAK2G,SAASyH,UAAUxK,eAAenB,IAAIwB,WAAWD;wBACtDhE,KAAKiR,kBAAkBxO,IAAIuB;wBAE3B,IAAIhE,KAAK8L,gBAAgB;4BACrBoF,WAAW;gCACPlR,KAAK8L,eAAelI,eAAenB,IAAIwB,WAAWD;+BACnD;;;;;YAcnBmN,qBAAqB,SAAS7N;gBAC1B,IAAItD,OAAO/X,MACPkY,cAAcmD,KAAK8N,UAAUnpB,KAAK0e,SAAS0K,WAAWlR,aACtDmR,oBAAoBhO,KAAKgO,qBAAqBrpB,KAAK0e,SAAS0K,WAAWC,mBACvEhG;gBAEJ,SAASiG;oBACL,IAAI3pB,GAAGkT,kBAAkBsC,eAAe;wBAEpC,IAAI4C,KAAK2G,SAAS6K,YAAYC,kBAC1B7pB,GAAG0O,UACF1O,GAAGyO,UACJ2J,KAAK0R,oBAAoBJ,mBAAmB,SAAS;4BAErD,OAAO;;wBAGX,IAAIhO,KAAK3R,aAAa5F,WAAW;4BAC7B,OAAOiU,KAAK2G,SAAShV;;wBAGzB,OAAO2R,KAAK3R;;oBAGhB,OAAO;;gBAGX2Z,SAAS,IAAI1jB,GAAGkY;oBACZK,aAAaA;oBACbtY,SAASyb,KAAKzb;oBACduY,YAAYnY,KAAK0e,SAASgL,QAAQC;oBAClCvR,SAASiD,KAAKjD;oBACdC,YAAYrY,KAAK0e,SAASgL,QAAQE;oBAClCtR,4BAA4BtY,KAAK0e,SAAS6K,YAAYM;oBACtDngB,UAAU4f;oBACV5nB,MAAM1B,KAAK0e,SAASiI,QAAQmD;oBAC5BvR,UAAU,SAAShP;wBACfwO,KAAKgS,eAAexgB;;oBAExBiP,OAAO6C,KAAK7C,SAAS,OAAOxY,KAAK0e,SAASrb,KAAK2mB,iBAAiB3O,KAAK7C;;gBAGzExY,KAAKiqB,gBAAgB3X,YAAY;oBAC7B+Q,OAAOlR;;gBAGX4F,KAAKqL,SAASvgB,KAAKwgB;gBAEnB,OAAOA;;YAGX6G,sBAAsB,SAASC,mBAAmBC;gBAC9C,IAAIrS,OAAO/X,MACPqqB,qBACApS;oBACI8K,OAAO/iB,KAAK0e,SAASqE;oBACrB0D,gBAAgBzmB,KAAK0e,SAAS+H;oBAC9BO,MAAMhnB,KAAK0e,SAASsI;oBACpBF,aAAa9mB,KAAKsjB;oBAClByD,eAAe/mB,KAAKgiB;oBACpB1M,UAAUtV,KAAK0e,SAASpJ;oBACxBc,QAAQpW,KAAK0e,SAAStI;oBACtBuI,OAAO3e,KAAK0e,SAASC;oBACrB7Y,KAAKnG,GAAGgQ,KAAKoI,KAAKjS,KAAKiS;oBACvBuS,mBAAmBtqB,KAAK0e,SAASoF,MAAMyG;oBACvCC,YAAY,SAAShQ,IAAI9Y,MAAM+oB,QAAQC;wBACnC,IAAID,SAAS,KAAKC,QAAQ,GAAG;4BACzB;;wBAGJ,IAAIL,eAAe7P,KAAK;4BACpB,IAAI6P,eAAe7P,IAAIiQ,WAAWA,UAAUJ,eAAe7P,IAAIkQ,UAAUA,OAAO;gCAC5E3S,KAAK4S,YAAYnQ,IAAI9Y,MAAM+oB,QAAQC;gCACnC3S,KAAK2G,SAASyH,UAAUqE,WAAWhQ,IAAI9Y,MAAM+oB,QAAQC;;+BAGxD;4BACD3S,KAAK4S,YAAYnQ,IAAI9Y,MAAM+oB,QAAQC;4BACnC3S,KAAK2G,SAASyH,UAAUqE,WAAWhQ,IAAI9Y,MAAM+oB,QAAQC;;wBAGzDL,eAAe7P;4BAAOiQ,QAAQA;4BAAQC,OAAOA;;;oBAGjDE,YAAY,SAASpQ,IAAI9Y,MAAMY,QAAQgS;+BAC5B+V,eAAe7P;wBAEtB,IAAIK,SAAS9C,KAAKsK;4BAAY7H,IAAIA;2BAAKK,QACnCvL;wBAMJ,IAAIuL,WAAWlb,GAAGkb,OAAOyC,qBAAqBzC,WAAWlb,GAAGkb,OAAO0C,eAAe;4BAC9E;;wBAGJjO,SAASyI,KAAK8S,YAAYrQ,IAAI9Y,MAAMY,QAAQgS;wBAI5C,IAAIhF,kBAAmB3P,GAAG+L,SAAS;4BAC/B4D,OAAOkI,KAAK;gCACRO,KAAK2G,SAASyH,UAAUyE,WAAWpQ,IAAI9Y,MAAMY,QAAQgS;;+BAGxD;4BACDyD,KAAK2G,SAASyH,UAAUyE,WAAWpQ,IAAI9Y,MAAMY,QAAQgS;;;oBAG7DwW,UAAU,SAAStQ,IAAI9Y,MAAMqpB;wBACzB,IAAItf,UAAU,IAAI9L,GAAG+L;wBAErBqM,KAAK6P;4BACDlmB,MAAM;4BACN0N,UAAUzP,GAAGgQ,KAAKoI,KAAK2G,SAASyH,UAAU2E,UAAU/S,MAAMyC,IAAI9Y;4BAC9D6V,WAAW9L,QAAQK;4BACnBwL,WAAW;gCACPyT,yBAAyBhU,KAAK;oCAC1BgB,KAAKiT,UAAUxQ,IAAI9Y;;gCAGvB+J,QAAQG;;4BAEZmc,YAAYvN;;wBAGhB,OAAO/O;;oBAEXwf,cAActrB,GAAGgQ,KAAK3P,KAAKkrB,eAAelrB;oBAC1CmrB,UAAU,SAAS3Q,IAAI9Y;wBACnBqW,KAAKqT,UAAU5Q,IAAI9Y;wBACnBqW,KAAK2G,SAASyH,UAAUgF,SAAS3Q,IAAI9Y;;oBAEzC2pB,eAAe,SAAS7Q,IAAI9Y,MAAM4pB;wBAC9BvT,KAAKwT,eAAe/Q,IAAI8Q;wBACxBvT,KAAK2G,SAASyH,UAAUkF,cAAc7Q,IAAI9Y,MAAM4pB;;oBAEpDE,sBAAsB,SAAShR,IAAI8Q,WAAWhpB,QAAQgS;wBAClDyD,KAAK2G,SAASyH,UAAUqF,qBAAqBxb,MAAM+H,MAAMjQ;;oBAE7D2jB,UAAU,SAASjR,IAAI9Y,MAAM4pB;wBACzB,OAAOvT,KAAK2G,SAASyH,UAAUsF,SAASjR,IAAI9Y,MAAM4pB;;oBAEtDI,aAAa,SAASlR,IAAI9Y,MAAMiqB,cAAcrX;wBAC1C,OAAOyD,KAAK6T,aAAa5b,MAAM+H,MAAMjQ;;oBAEzC+jB,eAAe,SAASrR,IAAI4B;wBACxBrE,KAAKjS,IAAI,wCAAwCiS,KAAK+K,QAAQtI,MAAM,WAAW4B,UAAU;wBACzFrE,KAAKsN,QAAQ7K,IAAI4B;;oBAErBiE,SAAS1gB,GAAGgQ,KAAKoI,KAAKsI,SAAStI;oBAC/B+K,SAASnjB,GAAGgQ,KAAKoI,KAAK+K,SAAS/K;oBAC/BwK,SAAS5iB,GAAGgQ,KAAKoI,KAAKwK,SAASxK;oBAC/B+T,SAASnsB,GAAGgQ,KAAKoI,KAAKgU,UAAUhU;oBAChCiU,eAAe,SAASrR;wBACpB,OAAO5C,KAAKsK;4BAAY1H,MAAMA;;;oBAElCsR,UAAU,SAASzR;wBACf,IAAIK,SAAS9C,KAAKsK;4BAAY7H,IAAIA;2BAAKK;wBACvC,OAAOA,WAAWlb,GAAGkb,OAAOoC,UACxBpC,WAAWlb,GAAGkb,OAAOkC,aACrBlC,WAAWlb,GAAGkb,OAAOwC,mBACrBxC,WAAWlb,GAAGkb,OAAOsC;;oBAE7BN,oBAAoB9E,KAAKoI,YAAYtD;oBACrCC,eAAe/E,KAAKoI,YAAYrD;;gBAGxCnd,GAAG+C,KAAK1C,KAAK0e,SAASiI,SAAS,SAASza,MAAMtJ;oBAC1CqV,QAAQ/L,QAAQtJ;;gBAGpBqV,QAAQ4O,gBAAgB7mB,KAAKqkB;gBAE7B,IAAI8F,mBAAmB;oBACnBxqB,GAAG+C,KAAKynB,mBAAmB,SAAS3a,KAAK5M;wBACrCqV,QAAQzI,OAAO5M;;;gBAIvB,OAAO,IAAIjD,GAAGusB,wBAAwBjU,SAASmS;;YAGnD+B,qBAAqB,SAAS3R;gBAC1Bxa,KAAK6iB;gBACL7iB,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOmC;;YAG7CoP,aAAa,SAASphB;gBAClB,IAAIA,UAAU,GAAG;oBACb,OAAOA,QAAQhL,KAAK0e,SAASrb,KAAKgpB,YAAY;;gBAElD,IAAI5b,KAAK;gBACT,GAAG;oBACCzF,QAAQA,QAAQ;oBAChByF;yBACKzF,QAAQ;gBAEjB,OAAO1J,KAAKgrB,IAAIthB,OAAO,IAAKuhB,QAAQ,KAAKvsB,KAAK0e,SAASrb,KAAKgpB,YAAY5b;;YAK5E+b,2BAA2B;gBACvB,IAAIzU,OAAO/X;gBAEXA,KAAKysB;gBAEL9sB,GAAG+C,KAAK1C,KAAK0e,SAASgO,cAAc,SAAS/pB,KAAKgqB;oBAC9C,IAAIjjB,WAAWijB,uBAAuBjjB,UAClC0f,aAAazpB,GAAG6B,WAAWuW,KAAK2G,SAAS0K,YAAY,OACrDwD,kBAAkBjtB,GAAG6B,WAAWmrB;oBAEpC,IAAIjjB,aAAa5F,WAAW;wBACxB4F,WAAWqO,KAAK2G,SAAShV;;oBAG7B,IAAIkjB,gBAAgBxD,YAAY;wBAC5BzpB,GAAG6B,OAAO4nB,YAAYuD,uBAAuBvD,YAAY;;oBAG7DzpB,GAAG6B,OAAOorB;wBACNljB,UAAUA;wBACV0f,YAAYA;uBACb;oBAEHrR,KAAK8U,iBAAiBD;;;YAI9B/K,YAAY,SAASpJ;gBACjB,IAAIqU,mBAAmB9sB,KAAKysB,kBAAkBhU;gBAE9C,IAAIqU,kBAAkB;oBAClB,OAAOA,iBAAiBltB;uBAEvB,IAAI6Y,aAAazY,KAAK+sB,kBAAkB;oBACzC,OAAO/sB,KAAK0e,SAAS2E;;;YAW7B4C,cAAc,SAAS+G;gBACnB,IAAIC,QAAQC,WACRC,kBAAkBH;gBAGtB,IAAIG,2BAA2BxtB,GAAG8X,WAAW;oBACzC0V,kBAAkBA,gBAAgBzV;;gBAItC,IAAIyV,oBAAoBxtB,GAAGyJ,OAAO+jB,kBAAkB;oBAChD,IAAIxtB,GAAGyI,OAAO+kB,kBAAkB;wBAC5B,OAAOA,gBAAgBnH;2BAEtB,IAAImH,gBAAgBhkB,QAAQF,kBAAkB,WAC/CkkB,gBAAgBjtB,KAAK+I,kBAAkB,QAAQ;wBAE/C,OAAOkkB,gBAAgBtpB,aAAalE,GAAGkY,aAAac;;oBAGxDsU,SAASE,gBAAgB1qB,qBAAqB;oBAE9C9C,GAAG+C,KAAKuqB,QAAQ,SAAStqB,KAAK4G;wBAC1B,IAAIA,MAAM1F,aAAa,YAAY,QAAQ;4BACvCqpB,YAAY3jB;4BACZ,OAAO;;;oBAIf,IAAI2jB,WAAW;wBACX,OAAOA,UAAUrpB,aAAalE,GAAGkY,aAAac;;;;YAK1DyU,iBAAiB;gBACb,OAAOptB,KAAKmgB,YAAYvE;oBACpBf,UACIlb,GAAGkb,OAAOuC,WACVzd,GAAGkb,OAAOwC,iBACV1d,GAAGkb,OAAOoC,QACVtd,GAAGkb,OAAOS,YACV3b,GAAGkb,OAAOkC,WACVpd,GAAGkb,OAAOsC;mBAEfzX;;YAKP2nB,oBAAoB,SAAS5U;gBACzB,IAAImU,kBAAkB5sB,KAAKysB,kBAAkBhU;gBAE7C,OAAOmU,kBAAkBA,gBAAgBxD,aAAappB,KAAK0e,SAAS0K;;YAGxEkE,0BAA0B,SAASC;gBAC/B,IAAIA,YAAYhO,gBAAgB5f,GAAG8X,WAAW;oBAC1C;wBACI/V,MAAM/B,GAAGmS,YAAYyb,YAAYhO,KAAK7H;wBACtC8D,MAAM+R,YAAYhO,KAAK7H,cAAc8D;;;gBAI7C;oBACI9Z,MAAM1B,KAAKqiB;wBAAY7H,IAAI+S,YAAY/S;uBAAK9Y;oBAC5C8Z,MAAMxb,KAAKqiB;wBAAY7H,IAAI+S,YAAY/S;uBAAKgB;;;YAIpDgS,2BAA2B,SAASC;gBAChC,IAAI1V,OAAO/X,MACP0tB;gBAEJ/tB,GAAG+C,KAAK+qB,cAAc,SAAS9qB,KAAK4qB;oBAChCG,gBAAgB7qB,KAAKkV,KAAKuV,yBAAyBC;;gBAGvD,OAAOG;;YAIXC,qBAAqB;gBACjB,IAAI3tB,KAAK0e,SAASkP,OAAOvf,OAAO1O,GAAG0O,OAAO;oBACtC,IAAIwf,kBAAkB,0BAClBxK,SAASrjB,KAAK0e,SAASkP,OAAOvK,QAC9B5K,WAAW4K,SAASrjB,KAAKimB,aAAa5C,UAAUrjB,KAAK+sB,kBACrDe,aAAa9tB,KAAK0e;oBAGtB,IAAIjG,YAAYA,aAAazY,KAAK+sB,kBAAkB;wBAChDe,aAAa9tB,KAAKysB,kBAAkBhU;;oBAIxCqV,WAAWpkB,WAAW;oBAGtB,IAAIokB,WAAW1E,WAAWlR,gBAAgB,MAAM;wBAC5C4V,WAAW1E,WAAWlR,cAAc2V;2BAEnC;wBACDC,WAAW1E,WAAWlR,eAAe,MAAM2V;;oBAI/CluB,GAAG+C,KAAK1C,KAAKojB,UAAU,SAASzgB,KAAK0gB;wBACjC,IAAIA,OAAO5J,kBAAkBhB,UAAU;4BACnC4K,OAAOzK,YAAYkV,WAAWpkB;4BAC9B2Z,OAAOxJ,eAAeiU,WAAW5V;4BAEjC,OAAO;;;;;YAMvB0P,wBAAwB,SAASmG;gBAC7B,IAAIhW,OAAO/X,MACPguB,iBAAiBD,QAAQ3e;gBAE7B,IAAIzP,GAAGkX,iBAAiBmX,iBAAiB;oBACrChuB,KAAK8F,IAAIioB,QAAQrsB,OAAO,oBAAoBqsB,QAAQrsB,OAAO,kCAAkCqsB,QAAQhG;oBACrG,OAAOiG,eAAejX,KAClB,SAASkX;wBACLlW,KAAKjS,IAAIioB,QAAQrsB,OAAO,0BAA0BqsB,QAAQhG;wBAC1DgG,QAAQzW,UAAU2W;uBAEtB;wBACI,IAAIF,QAAQxW,WAAW;4BACnBQ,KAAKjS,IAAIioB,QAAQrsB,OAAO,0BAA0BqsB,QAAQhG;4BAC1DgG,QAAQxW;+BAEP;4BACDQ,KAAKjS,IAAIioB,QAAQrsB,OAAO,0BAA0BqsB,QAAQhG;;;;gBAK1E,IAAIiG,mBAAmB,OAAO;oBAC1BD,QAAQzW,UAAU0W;uBAEjB;oBACD,IAAID,QAAQxW,WAAW;wBACnBvX,KAAK8F,IAAIioB,QAAQrsB,OAAO,qCAAqCqsB,QAAQhG,aAAa;wBAClFgG,QAAQxW;2BAEP;wBACDvX,KAAK8F,IAAIioB,QAAQrsB,OAAO,qCAAqCqsB,QAAQhG,aAAa;;;gBAI1F,OAAOiG;;YAIXvP,gBAAgB,SAASc,MAAM9D,SAASyS;gBACpC,IAAInW,OAAO/X,MACP2a,OAAOhb,GAAGoN,eACVyO,QAAQ,GACR9Z,OAAO/B,GAAGmS,YAAYyN,OACtB4O,aAAa5O,KAAKnU,QAAQmU,MAC1B6O,UAAUpuB,KAAKquB,wBACXruB,KAAKquB,wBACL1uB,GAAGgQ,KAAKoI,KAAKuW,uBAAuBvW;gBAE5C,KAAKpY,GAAGiJ,QAAQulB,eAAeA,WAAW3S,QAAQ,GAAG;oBACjDA,OAAO2S,WAAW3S;;gBAGtB4S,QAAQD,YAAYzsB,MAAMiZ,MAAMa,MAAM0S,oBAAoBzS,SAASzb,KAAK0e,SAASiI,QAAQC;oBACrF1G,YAAYnI,KAAKoI;oBACjB2G,aAAa/O,KAAKuL;oBAClBiL,kBAAkB,SAAS/T,IAAI+E;wBAC3BxH,KAAK6H,SAASrP,IAAIiK,IAAI+E;wBACtBxH,KAAK8K;wBACL9K,KAAKyW,aAAahU;;;;YAK9B8T,uBAAuB,SAAS/O,MAAM7d,MAAMiZ,MAAMa,MAAMiT,UAAUhT;gBAC9D,IAAIjB,KAAKxa,KAAKmgB,YAAY/E;oBAAST,MAAMA;oBAAMjZ,MAAMA;oBAAM8Z,MAAMA;oBAAMC,SAASA;;gBAEhFzb,KAAK4f,SAASrP,IAAIiK,IAAI+E;gBACtBvf,KAAKwuB,aAAahU;gBAElBxa,KAAK6iB;gBAEL4L,SAAS5rB;oBAAM2X,IAAIA;oBAAI+E,MAAMA;;;YAGjCuI,qBAAqB,SAAS1c,MAAMsjB;gBAChC,IAAIC,YAAYvjB,KAAKlL,KAAKmF,MAAM,KAAK,IACjC3D,OAAOgtB;gBAGX,IAAIhtB,QAAQ,MAAM;oBACdA,OAAO1B,KAAK0e,SAASgJ,MAAM9I;;gBAG/Bld,QAAQ,MAAMitB;gBAEd3uB,KAAKge;oBACDtc,MAAMA;oBACN0J,MAAMA;;;YAKdyhB,kBAAkB,SAASxR;gBACvB,IAAIgI,SAASrjB,KAAKkpB;oBACdC,QAAQ9N,KAAK+N,WAAWlR;oBACxBmR,mBAAmBhO,KAAK+N,WAAWC;oBACnCzpB,SAASyb,KAAKzb;oBACdwY,SAASiD,KAAKjD;oBACd1O,UAAU2R,KAAK3R;oBACf8O,OAAO6C,KAAK2O;;gBAGhBhqB,KAAKysB,kBAAkBpJ,OAAO5J,iBAAiB4B;;YAGnDuT,2BAA2B;gBACvB5uB,KAAK6uB,eAAelvB,GAAGmvB,eAAe,IAAInvB,GAAGmvB,YACzC9uB,KAAK0e,SAASzN,MAAMtR,GAAGgQ,KAAK3P,KAAKslB,mBAAmBtlB,OAAOL,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;gBAGjF,IAAIA,KAAK6uB,gBAAgB7uB,KAAK6uB,aAAaE,gBAAgB;oBACvD/uB,KAAKsjB,eAAetjB,KAAKgoB,aACrBhoB,KAAK0e,SAASiI,QAAQ7I,QAAS9d,KAAK6uB,aAAaG;oBAGrDhvB,KAAK0e,SAASuQ,aAAajvB,KAAK6uB,aAAaK;oBAC7C,IAAIlvB,KAAK6uB,aAAaM,aAAa;wBAC/BnvB,KAAK0e,SAASiI,QAAQ5I,WAAW/d,KAAK6uB,aAAaM;;uBAGtD;oBACDnvB,KAAKsjB,eAAetjB,KAAKgoB,aAAahoB,KAAK0e,SAASiI,QAAQ7I;;;YAIpEsR,mBAAmB;gBACf,KAAKzvB,GAAG2mB,4BAA4BtmB,KAAK0e,SAAS6B,WAAWH,SAAS;oBAClE,OAAO;;gBAGX,IAAIpgB,KAAK0e,SAASsI,KAAKqI,UAAU;oBAC7B,IAAI1vB,GAAGkT,kBAAkB4C,mBAAmB;wBACxC,OAAO;;oBAGX,IAAI9V,GAAGkT,kBAAkB2C,qBAAqBxV,KAAK0e,SAASsI,KAAKsI,UAAU;wBACvE,OAAO;;oBAGX,OAAO;;gBAGX,OAAO;;YAGX7F,qBAAqB,SAAS8F,SAASvd;gBACnC,IAAIwd,QAAQ;gBAEZ,KAAKD,QAAQ7pB,QAAQ;oBACjB,OAAO;;gBAGX/F,GAAG+C,KAAK6sB,SAAS,SAAS5sB,KAAK8sB;oBAK3B,IAAI9vB,GAAGwH,SAASsoB,aAAa;wBAEzB,IAAIC,WAAW,IAAI7tB,OAAO,QAAQ4tB,aAAa,KAAK;wBAEpD,IAAIzd,SAASmC,MAAMub,aAAa,MAAM;4BAClCF,QAAQ;4BACR,OAAO;;;;gBAKnB,OAAOA;;YAWXjK,YAAY,SAASoK,MAAMC,kBAAkB3oB;gBACzC,IAAIlB,UAAU/F,KAAK0e,SAASmR,SAASF,OACjCtG,wBACAyG,WAAW/f,OAAO6f,mBAClBluB,OAAOouB,MAAM,IACbrX,WAAWzY,KAAKimB,aAAahf,OAC7B8oB,iBAAiB/vB,KAAKqtB,mBAAmB5U,WACzCuX,sBAAsBC;gBAE1B,SAAShjB,EAAEvL,MAAMwuB;oBAAenqB,UAAUA,QAAQ7D,QAAQR,MAAMwuB;;gBAEhEvwB,GAAG+C,KAAKqtB,eAAe1G,mBAAmB,SAAS1mB,KAAKwtB;oBAKpD,IAAIxwB,GAAGwH,SAASgpB,mBAAmB;wBAC/B9G,kBAAkBxmB,KAAKstB;;;gBAI/BH,uBAAuB3G,kBAAkBzY,KAAK,MAAM3H;gBAEpDgE,EAAE,UAAUjN,KAAK0e,SAAS0R,eAAe1uB;gBACzCuL,EAAE,gBAAgB+iB;gBAClB/iB,EAAE,eAAejN,KAAKosB,YAAY2D,eAAeM;gBACjDpjB,EAAE,kBAAkBjN,KAAKosB,YAAY2D,eAAeO;gBAEpDL,mBAAmBlqB,QAAQoO,MAAM;gBACjC,IAAI8b,qBAAqB,MAAM;oBAC3BtwB,GAAG+C,KAAKutB,kBAAkB,SAASttB,KAAK4tB;wBACpCtjB,EAAEsjB,aAAaT,MAAMntB;;;gBAI7B3C,KAAK0e,SAASyH,UAAUC,QAAQ,MAAM1kB,MAAMqE,SAASjC;gBAErD,OAAOiC;;YAYXge,cAAc,SAASvJ,IAAIpL;gBACvB,IAAIpP,KAAKwwB,qBAAqBhW,KAAK;oBAC/Bxa,KAAK6iB;oBACL7iB,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOwC;oBAEzC,IAAIjO,UAAU;wBACVA,SAASoL;2BAER;wBACDxa,KAAK4f,SAASkE,MAAMtJ;;oBAGxB,OAAO;;;YAIfwO,mBAAmB,SAASxO,IAAIK;gBAC5B,IAAI9C,OAAO/X,MACPywB,cAAczwB,KAAKotB;gBAEvB,IAAIvS,WAAWlb,GAAGkb,OAAOyC,mBAAmB;oBACxCtd,KAAK2jB,+BAA+B9gB,KAAK2X;uBAExC,IAAIK,WAAWlb,GAAGkb,OAAO0C,eAAe;oBACzCvd,KAAK4jB,4BAA4B/gB,KAAK2X;;gBAG1C,IAAIiW,gBAAgB,MACfzwB,KAAK2jB,+BAA+Bje,UAAU1F,KAAK4jB,4BAA4Ble,SAAS;oBAEzFujB,WAAW;wBACPlR,KAAK2Y,eAAe3Y,KAAK4L,gCAAgC5L,KAAK6L;uBAC/D;;;YAIXvF,kCAAkC;gBAC9B,IAAItG,OAAO/X;gBAEX,IAAIA,KAAK0e,SAAS6K,YAAYoH,qBAAqBhxB,GAAG6O,YAAY7O,GAAG+O,aAAa;oBAC9Eua,WAAW;wBACPtkB,OAAOisB,MAAM7Y,KAAK2G,SAASmR,SAASgB;uBACrC;oBACH,MAAM,IAAIlxB,GAAGwB,MAAMnB,KAAK0e,SAASmR,SAASgB;;;YAIlDC,+BAA+B,SAAStW,IAAI9Y,MAAMqvB,UAAUzc;gBAGxD,KAAKyc,SAASnlB,SAAS;oBACnB,IAAI0I,OAAOA,IAAIuG,WAAW,QAAQkW,SAAS/mB,OAAO;wBAC9ChK,KAAK0e,SAASyH,UAAUC,QAAQ5L,IAAI9Y,MAAM,gCAAgC4S,IAAIuG,QAAQvG;2BAErF;wBACD,IAAI0c,cAAcD,SAAS/mB,QAAQ+mB,SAAS/mB,QAAQhK,KAAK0e,SAASrb,KAAK4tB;wBACvEjxB,KAAK0e,SAASyH,UAAUC,QAAQ5L,IAAI9Y,MAAMsvB,aAAa1c;;;;YAKnE4c,8CAA8C,SAASC,WAAWhnB,OAAO6Q,OAAO8C,QAAQC;gBACpF,IAAIhG,OAAO/X;gBAEX,IAAImK,MAAMzE,SAASsV,OAAO;oBACtB,IAAImW,cAAcnxB,KAAK0e,SAAS0K,WAAWgI,wBAAwB;wBAE/DnI,WAAW;4BACP,IAAIoI,uBAAuBtZ,KAAKuV,yBAAyBnjB,MAAM6Q,SAC3DvC,WAAWV,KAAKkO,aAAa9b,MAAM6Q,OAAOuE,OAC1C8D,SAAStL,KAAK8J,WAAWpJ;4BAE7BV,KAAK6P;gCACDlmB,MAAM;gCACN0N,UAAUzP,GAAGgQ,KAAKoI,KAAK2G,SAASyH,UAAUmL,YAAYvZ,MAAMsZ,sBAAsBhO;gCAClF/L,WAAW3X,GAAGgQ,KAAKoI,KAAKwZ,4BAA4BxZ,MAAM5N,OAAO6Q,OAAO8C,QAAQC;gCAChFxG,WAAW5X,GAAGgQ,KAAKoI,KAAKyZ,4BAA4BzZ,MAAM5N,OAAO6Q,OAAO8C,QAAQC;gCAChFgK,YAAY,WAAWsJ,qBAAqB3vB,OAAO,cAAc2vB,qBAAqB7V;;2BAE3F;2BAEF,KAAK2V,WAAW;wBACjB,MAAOnW,QAAQ7Q,MAAMzE,QAAQsV,SAAS;4BAClCjD,KAAKoU,oBAAoBhiB,MAAM6Q,OAAOR;;;;;YAMtDkW,gBAAgB,SAASe,YAAYC;gBACjC1xB,KAAK6jB,kBAAkB7jB,KAAK6jB,eAAe8N,cAAcF,YAAYC,QAAQ1xB,KAAKmjB;gBAElFnjB,KAAK0e,SAASyH,UAAUwL,cAAchyB,GAAG6B,WAAWiwB,aAAa9xB,GAAG6B,WAAWkwB;gBAE/E1xB,KAAK2jB;gBACL3jB,KAAK4jB;;YAeTgI,cAAc,SAASpR,IAAI9Y,MAAMiqB,cAAcrX,KAAKlF;gBAChD,IAAI2I,OAAO/X;gBAEX+X,KAAKoL,gBAAgB3I,MAAMmR,aAAa5T,KAAK2G,SAASoF,MAAMyG;gBAE5D,IAAIxS,KAAK6Z,iBAAiBpX,IAAI9Y,MAAMiqB,eAAe;oBAC/C,IAAIkG,kBAAkB9Z,KAAK2G,SAASoF,MAAMgO,mBAAmB;oBAE7D/Z,KAAK+Y,8BAA8B9gB,MAAM+H,MAAMjQ;oBAC/CiQ,KAAK2G,SAASyH,UAAUuF,YAAYlR,IAAI9Y,MAAMqW,KAAKkL,aAAazI;oBAChEzC,KAAKga,mBAAmBvX,IAAI9Y;oBAE5BqW,KAAKoI,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOwC;oBACzCtF,KAAKmL,eAAe1I,MAAMyO,WAAW;wBACjClR,KAAKjS,IAAI,wBAAwBpE,OAAO;wBAExC,IAAI0N,UAAU;4BACVA,SAASoL;+BAER;4BACDzC,KAAK6H,SAASkE,MAAMtJ;;uBAEzBqX;oBAEH,OAAO;;;YAIfE,oBAAoB,SAASvX,IAAI9Y;gBAC7B1B,KAAK8F,IAAI,aAAa9F,KAAK0e,SAASoF,MAAMgO,mBAAmB,8BAA8BpwB,OAAO;;YAItG8uB,sBAAsB,SAAShW;gBAC3B,IAAIwX,YAAYhyB,KAAK4iB,mBACjB5Q;gBAEJ,IAAIhS,KAAKmjB,gBAAgB3I,KAAK;oBAC1Bxa,KAAK8F,IAAI,kCAAkC0U,IAAI;oBAC/C,OAAO;uBAEN,IAAIxa,KAAK4f,SAASe,QAAQnG,KAAK;oBAChCxI,WAAWhS,KAAKqgB,QAAQ7F;oBAExB,IAAIxa,KAAK0e,SAASyH,UAAU8L,cAAczX,IAAIxI,cAAc,OAAO;wBAC/D,OAAO;;oBAGX,IAAIggB,YAAY,KAAKhyB,KAAK6iB,uBAAuB,IAAImP,WAAW;wBAC5DhyB,KAAKulB,WAAW;wBAChB,OAAO;;oBAGXvlB,KAAK8F,IAAI,0BAA0BkM,WAAW,YAAYwI,KAAK;oBAC/D,OAAO;uBAEN;oBACDxa,KAAK8F,IAAI,MAAM0U,KAAK,4BAA4B;oBAChD,OAAO;;;YAIfwQ,WAAW,SAASxQ,IAAI9Y;gBACpB1B,KAAK6iB;gBAELqP,aAAalyB,KAAKkjB,eAAe1I;gBAEjC,IAAI2X,kBAAkBxyB,GAAG2F,QAAQtF,KAAKse,YAAY9D;gBAClD,KAAKxa,KAAK0e,SAASuQ,cAAckD,mBAAmB,GAAG;oBACnDnyB,KAAKse,WAAWpC,OAAOiW,iBAAiB;;gBAG5CnyB,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOqC;;YAG7C2N,aAAa,SAASrQ,IAAI9Y,MAAMY,QAAQgS;gBACpC,KAAKhS,OAAOsJ,SAAS;oBACjB5L,KAAK6iB;oBACL7iB,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAO0C;oBAEzC,IAAIjb,OAAOtC,KAAK0e,SAASoF,MAAMyG,kCAAkC,MAAM;wBACnEvqB,KAAKmjB,gBAAgB3I,MAAM;;uBAG9B;oBACD,IAAIlY,OAAOujB,cAAc;wBACrB7lB,KAAKqhB,eAAe7G,MAAMlY,OAAOujB;;oBAGrC7lB,KAAKyiB;oBACLziB,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOyC;;gBAG7Ctd,KAAK8wB,8BAA8BtW,IAAI9Y,MAAMY,QAAQgS;gBAErD,OAAOhS,OAAOsJ,UAAU,OAAO;;YAGnCsb,WAAW,SAAS1M;gBAChBxa,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAO4C;;YAG7C6J,mBAAmB,SAAS9M,IAAI4M,UAAUC;gBACtC,IAAI3lB,OAAO1B,KAAKqgB,QAAQ7F;gBAExB,IAAI6M,SAAS;oBACTrnB,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAO2C;oBACzCxd,KAAK8F,IAAI,yBAAyBpE,OAAO,iBAAiB;oBAI1D,IAAI0lB,SAAS7S,oBAAoBzQ,WAAW;wBACxC9D,KAAK0e,SAASyH,UAAUC,QAAQ5L,IAAI9Y,MAAM,yBAAyB0lB;2BAElE;wBACDpnB,KAAK0e,SAASyH,UAAUC,QAAQ5L,IAAI9Y,MAAM,8CAA8C0lB,SAASvM,QAAQuM;;uBAG5G;oBACDpnB,KAAK6iB;oBACL7iB,KAAKyiB;oBACLziB,KAAK4f,SAASwS,QAAQ5X;oBACtBxa,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAO6C;oBACzC1d,KAAK8F,IAAI,yBAAyBpE,OAAO;;;YAIjDqoB,gBAAgB,SAASxgB;gBACrB,IAAI8oB;gBAEJ,IAAI1yB,GAAGkT,kBAAkBsC,eAAe;oBACpC,KAAKkd,YAAY,GAAGA,YAAY9oB,MAAM+V,MAAM5Z,QAAQ2sB,aAAa;wBAC7DryB,KAAK8lB,sBAAsBvc,MAAM+V,MAAM+S,YAAY9oB;;oBAGvDvJ,KAAKge,SAASzU,MAAM+V;uBAGnB,IAAI/V,MAAM7C,MAAMhB,SAAS,GAAG;oBAC7B1F,KAAKge,SAASzU;;gBAGlB5J,GAAG+C,KAAK1C,KAAKojB,UAAU,SAASzgB,KAAK0gB;oBACjCA,OAAOvJ;;;YAIf6Q,aAAa,SAASnQ,IAAI9Y,MAAM+oB,QAAQC;gBACpC1qB,KAAK6jB,kBAAkB7jB,KAAK6jB,eAAeyO,qBAAqB9X,IAAIiQ,QAAQC;;YAGhF6H,WAAW,SAAS/X,IAAI9Y;YAIxB8wB,0BAA0B,SAAShY,IAAI9Y;gBACnC1B,KAAKuyB,UAAUviB,MAAMhQ,MAAM8H;gBAC3B9H,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOkC;gBACzC/c,KAAKyyB,aAAaziB,MAAMhQ,MAAM8H;gBAE9B,IAAI9H,KAAK0e,SAASuQ,YAAY;oBAC1BjvB,KAAK0e,SAASyH,UAAUuM,YAAY1iB,MAAMhQ,MAAM8H;oBAChD9H,KAAKsgB,YAAY9F;uBAEhB;oBACDxa,KAAK2yB,eAAenY;oBACpBxa,KAAK0e,SAASyH,UAAUuM,YAAY1iB,MAAMhQ,MAAM8H;;;YAIxD0Y,iBAAiB,SAAShG,IAAIoY,mBAAmBC;gBAC7C,IAAIlY,OAAO3a,KAAK8iB,QAAQtI,KACpBsY;gBAEJ,IAAIF,mBAAmB;oBACnBE,4BAA4BnzB,GAAGgQ,KAAKijB,mBAAmB5yB,MAAMwa,IAAIG,MAAMkY;;gBAG3E,IAAI7yB,KAAKovB,qBAAqB;oBAC1BpvB,KAAK4nB;wBACDlmB,MAAM;wBACN0N,UAAUzP,GAAGgQ,KAAK3P,KAAK0e,SAASyH,UAAU4M,gBAAgB/yB,MAAMwa;wBAChElD,WAAWwb,6BACPnzB,GAAGgQ,KAAK3P,KAAKgzB,eAAeC,YAAYjzB,MAAMwa,IAAIG,MAAMkY;wBAC5D9K,YAAYvN;;oBAEhB,OAAO;uBAEN;oBACDxa,KAAK8F,IAAI,mCAAmC0U,KAAK,0DAC7C,oEAAoE;oBACxE,OAAO;;;YAIfiY,cAAc,SAASjY;YAIvB0Y,kBAAkB,SAASzI,QAAQC;gBAC/B1qB,KAAK0e,SAASyH,UAAUgN,gBAAgB1I,QAAQC;;YAGpDQ,eAAe,SAAS1Q;YAIxB4Q,WAAW,SAAS5Q,IAAI9Y;gBACpB1B,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOuC;;YAG7CmO,gBAAgB,SAAS/Q,IAAI8Q;YAI7BvC,uBAAuB,SAASvO,IAAIwB,WAAWD;gBAE3C,IAAIA,cAAcpc,GAAGkb,OAAOsC,QAAQ;oBAChC+U,aAAalyB,KAAKkjB,eAAe1I;;;YAIzC4Y,iCAAiC,SAAS3F;gBACtC,IAAI1V,OAAO/X;gBAEXL,GAAG+C,KAAK+qB,cAAc,SAAS9qB,KAAK4qB;oBAChCxV,KAAKoU,oBAAoBoB,YAAY/S;;;YAI7C6Y,iCAAiC,SAASC,uBAAuBnpB,OAAO2T,QAAQC,UAAUsF;gBACtF,IAAIkQ,cACAvB,YAAYhyB,KAAK4iB,mBACjB4Q,mCAAmCxzB,KAAK6iB;gBAE5C,IAAImP,cAAc,KAAKwB,oCAAoCxB,WAAW;oBAClE,IAAI7nB,MAAMzE,SAAS,GAAG;wBAClB1F,KAAK4nB;4BACDlmB,MAAM;4BACN0N,UAAUzP,GAAGgQ,KAAK3P,KAAK0e,SAASyH,UAAUmL,YAAYtxB,MAAMszB,sBAAsB,IAAIjQ;4BACtF/L,WAAW3X,GAAGgQ,KAAK3P,KAAKuxB,4BAA4BvxB,MAAMmK,OAAO,GAAG2T,QAAQC;4BAC5ExG,WAAW5X,GAAGgQ,KAAK3P,KAAKwxB,4BAA4BxxB,MAAMmK,OAAO,GAAG2T,QAAQC;4BAC5EgK,YAAY,WAAW5d,MAAM,GAAGoV,KAAK7d,OAAO,cAAcyI,MAAM,GAAGoV,KAAK/D;;2BAG3E;wBACDxb,KAAKulB,WAAW;;uBAGnB;oBACDvlB,KAAKozB,gCAAgCjpB;oBACrCopB,eAAevzB,KAAK0e,SAASmR,SAAS4D,kBACjCvxB,QAAQ,iBAAiBsxB,kCACzBtxB,QAAQ,kBAAkB8vB;oBAC/BhyB,KAAKkmB,YAAYqN;;;YAIzB/B,4BAA4B,SAASrnB,OAAO6Q,OAAO8C,QAAQC;gBACvD,IAAI2V,YAAY1Y,QAAQ;gBAExBhb,KAAKmsB,oBAAoBhiB,MAAM6Q,OAAOR,IAAIrQ,MAAM6Q,OAAOuE,KAAK7d;gBAE5D1B,KAAKkxB,6CAA6C,OAAO/mB,OAAOupB,WAAW5V,QAAQC;;YAGvFwT,4BAA4B,SAASpnB,OAAO6Q,OAAO8C,QAAQC;gBACvD,IAAIhG,OAAO/X,MACP0zB,YAAY1Y,QAAQ,GACpBqW,uBAAuBrxB,KAAKstB,yBAAyBnjB,MAAM6Q;gBAE/Dhb,KAAK2zB,wBAAwBxpB,MAAM6Q,QAAQqW,sBACtCta,KACD;oBACIgB,KAAK6b,QAAQzpB,MAAM6Q,OAAOR,IAAIsD,QAAQC;oBACtChG,KAAKmZ,6CAA6C,MAAM/mB,OAAOupB,WAAW5V,QAAQC;mBAEtF;oBACIhG,KAAKmZ,6CAA6C,OAAO/mB,OAAOupB,WAAW5V,QAAQC;;;YAK/F2B,wBAAwB,SAASvV,OAAO2T,QAAQC;gBAC5C,IAAI5T,MAAMzE,WAAW,GAAG;oBACpB1F,KAAKulB,WAAW;oBAChB;;gBAGJ,IAAI+N,wBAAwBtzB,KAAKwtB,0BAA0BrjB,QACvDsO,WAAWzY,KAAKimB,aAAa9b,MAAM,GAAGoV,OACtC8D,SAASrjB,KAAK6hB,WAAWpJ;gBAE7BzY,KAAK4nB;oBACDlmB,MAAM;oBACN0N,UAAUzP,GAAGgQ,KAAK3P,KAAK0e,SAASyH,UAAU0N,iBAAiB7zB,MAAMszB,uBAAuBjQ;oBACxF/L,WAAW3X,GAAGgQ,KAAK3P,KAAKqzB,iCAAiCrzB,MAAMszB,uBAAuBnpB,OAAO2T,QAAQC,UAAUsF;oBAC/G9L,WAAW5X,GAAGgQ,KAAK3P,KAAKozB,iCAAiCpzB,MAAMmK;oBAC/D4d,YAAY;;;YAIpB+L,yBAAyB;gBACrB,IAAI/b,OAAO/X;gBAEXA,KAAKiqB,gBAAgBhqB,OAAO0E,QAAQ,gBAAgB,SAASkK;oBACzD,IAAIkJ,KAAKmK,iBAAiB;wBACtBrT,IAAIA,KAAKlK,OAAOovB;wBAEhBllB,EAAEC,cAAciJ,KAAK2G,SAASmR,SAASmE;wBAEvC,OAAOjc,KAAK2G,SAASmR,SAASmE;;;;YAQ1CtQ,qBAAqB;gBACjB,IAAI3L,OAAO/X,MACPiY,UAAUjY,KAAK0e,SAAS8E;gBAG5B,IAAI7jB,GAAGs0B,WAAWj0B,KAAK0e,SAAS8E,QAAQzF,YAAY,MAAM;oBACtD,KAAK/d,KAAKk0B,UAAU;wBAChBv0B,GAAG6B,OAAOyW;4BAAU+O,MAAMhnB,KAAK0e,SAASsI;;wBAExC/O,QAAQnS,MAAMnG,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;wBAChCiY,QAAQkc,gBAAgBx0B,GAAGgQ,KAAK3P,KAAKoe,gBAAgBpe;wBAErDA,KAAKk0B,WAAW,IAAIv0B,GAAGs0B,QAAQhc;;oBAGnCgR,WAAW;wBACPlR,KAAKmc,SAASE,UAAUrd,KAAK,SAASga,UAAU3J;4BAC5CrP,KAAKsc;4BACLtc,KAAK2G,SAASyH,UAAUmO,yBAAyBvD,UAAU,MAAM3J;2BAElE,SAAS2J,UAAU3J;4BAElBrP,KAAK2G,SAASyH,UAAUmO,yBAAyBvD,UAAU,OAAO3J;;uBAEvE;;;YAIXiN,yBAAyB;YAEzBtI,UAAU,SAASvR,IAAIiC;gBACnBzc,KAAKmgB,YAAY3D,WAAWhC,IAAIiC;gBAChCzc,KAAK6jB,kBAAkB7jB,KAAK6jB,eAAe0Q,UAAU/Z;;YAGzDoX,kBAAkB,SAASpX,IAAI9Y,MAAMiqB;gBACjC,IAAIzL,aAAalgB,KAAKmgB,YAAYvE;oBAAUpB,IAAIA;;gBAGhD,KAAKxa,KAAKmjB,gBAAgB3I,OACnBxa,KAAK0e,SAASoF,MAAM0Q,cACpBtU,WAAWrF,WAAWlb,GAAGkb,OAAOsC,QAAQ;oBAE3C,IAAInd,KAAKijB,aAAazI,QAAQ1W,WAAW;wBACrC9D,KAAKijB,aAAazI,MAAM;;oBAG5B,IAAIxa,KAAKijB,aAAazI,MAAMxa,KAAK0e,SAASoF,MAAM2Q,iBAAiB;wBAC7Dz0B,KAAKijB,aAAazI,OAAO;wBACzB,OAAO;;;gBAIf,OAAO;;YAGXmY,gBAAgB,SAASnY;gBACrBxa,KAAKse,WAAWzb,KAAK2X;;YAIzBgU,cAAc,SAAShU;gBACnB,IAAI/B;gBAEJ,IAAI9Y,GAAGkT,kBAAkBsC,eAAe;oBACpCsD,WAAWzY,KAAK4f,SAAS2B,QAAQ/G,IAAIwL;uBAEpC;oBACDvN,WAAWzY,KAAKimB,aAAajmB,KAAK4f,SAASpG,SAASgB;;gBAGxD,IAAI/B,UAAU;oBACVzY,KAAK8hB,qBAAqBtH,MAAM/B;;;YAIxCuM,6BAA6B,SAAS0P;gBAClC10B,KAAK0e,SAASzN,KAAKrR,UAAU80B;gBAE7B10B,KAAK6uB,eAAelvB,GAAGmvB,eAAe,IAAInvB,GAAGmvB,YACrC9uB,KAAK0e,SAASzN,MAAMtR,GAAGgQ,KAAK3P,KAAKslB,mBAAmBtlB,OAAOL,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;gBAGrF,IAAIA,KAAK6uB,gBAAgB7uB,KAAK6uB,aAAaE,gBAAgB;oBACvD/uB,KAAKsjB,aAAauF,YAAY,MAAM7oB,KAAK6uB,aAAaG;oBAEtDhvB,KAAK0e,SAASuQ,aAAajvB,KAAK6uB,aAAaK;oBAC7C,IAAIlvB,KAAK6uB,aAAaM,aAAa;wBAC/BnvB,KAAK6kB,YAAY7kB,KAAK6uB,aAAaM;;;;YAK/CyE,SAAS,SAASpZ,IAAIsD,QAAQC;gBAC1B,IAAIrc,OAAO1B,KAAKqgB,QAAQ7F;gBAExB,IAAIsD,QAAQ;oBACR9d,KAAKolB,UAAUtH,QAAQtD;;gBAG3B,IAAIuD,UAAU;oBACV/d,KAAK6kB,YAAY9G,UAAUvD;;gBAG/Bxa,KAAK4nB;oBACDlmB,MAAM;oBACN0N,UAAUzP,GAAGgQ,KAAK3P,KAAK0e,SAASyH,UAAUwO,UAAU30B,MAAMwa,IAAI9Y;oBAC9D4V,WAAW3X,GAAGgQ,KAAK3P,KAAKwyB,0BAA0BxyB,MAAMwa,IAAI9Y;oBAC5D6V,WAAW5X,GAAGgQ,KAAK3P,KAAKmsB,qBAAqBnsB,MAAMwa,IAAI9Y;oBACvDqmB,YAAYvN;;;YAIpB8F,aAAa,SAAS9F;gBAClB,KAAKxa,KAAK4f,SAAS/V,OAAO2Q,KAAK;oBAC3Bxa,KAAKmgB,YAAYrE,UAAUtB,IAAI7a,GAAGkb,OAAOoC;;;YAIjDuI,oBAAoB;gBAChB,IAAIoP,YAAYC,iBACZ9c,OAAO/X;gBAEX,OAAOA,KAAKse,WAAW5Y,QAAQ;oBAC3BkvB,aAAa50B,KAAKse,WAAWjM;oBAC7BrS,KAAKsgB,YAAYsU;;gBAIrBC,kBAAkB70B,KAAKqiB;oBAAYxH,QAAQlb,GAAGkb,OAAOS;mBAAa5V;gBAClE,IAAImvB,iBAAiB;oBACjBl1B,GAAGmG,IAAI,uBAAuB+uB,kBAAkB;oBAChD5L,WAAW;wBACPlR,KAAKyN;uBACN;;;YAYXmO,yBAAyB,SAASpG,aAAa8D;gBAC3C,IAAItZ,OAAO/X,MACPuf,OAAQ;oBACJ,IAAIgO,YAAYhO,gBAAgB5f,GAAG8X,WAAW;wBAC1C,OAAO8V,YAAYhO,KAAK7H;;oBAE5B,OAAO6V,YAAYhO;qBAEvB7d,OAAO2vB,qBAAqB3vB,MAC5B8Z,OAAO6V,qBAAqB7V,MAC5B/C,WAAWzY,KAAKimB,aAAasH,YAAYhO,OACzCwQ,iBAAiB/vB,KAAKqtB,mBAAmB5U,WACzCqc,kBAAkB,IAAIn1B,GAAG+L;gBAE7BopB,gBAAgB/d,KACZ,eACA;oBACIgB,KAAKoU,oBAAoBoB,YAAY/S,IAAI9Y;;gBAGjD,IAAI/B,GAAG+I,cAAc6W,UAAUvf,KAAKypB,oBAAoBsG,eAAe1G,mBAAmB3nB,OAAO;oBAC7F1B,KAAKulB,WAAW,aAAa7jB,MAAM6d;oBACnC,OAAOuV,gBAAgBhpB;;gBAG3B,KAAK9L,KAAK0e,SAAS0K,WAAW2L,cAAcvZ,SAAS,GAAG;oBACpDxb,KAAKulB,WAAW,cAAc7jB,MAAM6d;oBACpC,OAAOuV,gBAAgBhpB;;gBAG3B,IAAI0P,OAAO,KAAKuU,eAAeM,aAAa7U,OAAOuU,eAAeM,WAAW;oBACzErwB,KAAKulB,WAAW,aAAa7jB,MAAM6d;oBACnC,OAAOuV,gBAAgBhpB;;gBAG3B,IAAI0P,OAAO,KAAKA,OAAOuU,eAAeO,cAAc;oBAChDtwB,KAAKulB,WAAW,gBAAgB7jB,MAAM6d;oBACtC,OAAOuV,gBAAgBhpB;;gBAG3B,IAAInM,GAAGq1B,mBAAmBr1B,GAAGkT,kBAAkBkD,iBAAiBpW,GAAGyI,OAAOmX,OAAO;oBAC7E,IAAI5f,GAAGq1B,gBAAgBzV,MAAM5f,GAAGgQ,KAAKoI,KAAKjS,KAAKiS,OAAOkd,SAASlF,eAAemF,OAAOne,KACjF+d,gBAAgBlpB,SAChB,SAASupB;wBACLpd,KAAKwN,WAAW4P,YAAY,cAAczzB,MAAM6d;wBAChDuV,gBAAgBhpB;;uBAIvB;oBACDgpB,gBAAgBlpB;;gBAGpB,OAAOkpB;;YAGXM,gBAAgB;gBACZ,IAAIrd,MAAMsd,cAAcnpB;gBAExB6L,OAAO/X;gBAEPq1B,eAAe,SAAS3zB,MAAM0N,UAAUzH;oBACpC,IAAI2tB;oBAEJ;wBACI,OAAOlmB,SAASY,MAAM+H,MAAMpQ;sBAEhC,OAAO4tB;wBACHD,WAAWC,UAAUxvB,WAAWwvB,UAAUjvB;wBAC1CyR,KAAKjS,IAAI,0BAA0BpE,OAAO,kBAAkB4zB,UAAU;;;gBAK9E,KAAKppB,QAAQlM,KAAK0e,SAASyH,WAAW;qBACjC;wBACG,IAAIqP,cAAcC;wBAClBD,eAAetpB;wBACfupB,eAAe1d,KAAK2G,SAASyH,UAAUqP;wBACvCzd,KAAK2G,SAASyH,UAAUqP,gBAAgB;4BACpC,OAAOH,aAAaG,cAAcC,cAAc3tB;;;;;;;KCh0DvE;QACG;QAEAnI,GAAG+1B,oBAAoB,SAAS5d;YAC5B,IAAIC,OAAO/X;YAGXA,KAAK0e;gBACDqE,OAAO;gBACPM,QAAQ;gBACR3Z,UAAU;gBACV+c,gBAAgB;gBAChBkP,6BAA6B;gBAC7B1G,YAAY;gBAEZtI;oBACIE;oBACA9I,UAAU;oBACV6X,eAAe;oBACfC,gBAAgB;oBAChB/L,WAAW;oBACXvD,QAAQ;oBACRzI;oBACAgY,cAAc;oBACdC,mBAAmB;oBACnBnP,UAAU;;gBAGdwC;oBACIC;oBACAgH,WAAW;oBACXC,cAAc;oBACd0B,WAAW;oBACXZ,wBAAwB;oBACxBlZ,aAAa;oBACbgd;wBACIc,WAAW;wBACXC,UAAU;wBACVC,WAAW;wBACXC,UAAU;;oBAEdpB,YAAY;;gBAGhB5O;oBACIwO,UAAU,SAASna,IAAI9Y;oBACvBgxB,aAAa,SAASlY,IAAI9Y;oBAC1BkpB,YAAY,SAASpQ,IAAI9Y,MAAMiqB,cAAcyK;oBAC7CzE,eAAe,SAASF,YAAYC;oBACpC5G,UAAU,SAAStQ,IAAI9Y;oBACvBypB,UAAU,SAAS3Q,IAAI9Y;oBACvB2pB,eAAe,SAAS7Q,IAAI9Y,MAAM4pB;oBAClCE,sBAAsB,SAAShR,IAAI8Q,WAAWK,cAAcrX;oBAC5DmX,UAAU,SAASjR,IAAIxI,UAAUsZ;oBACjCd,YAAY,SAAShQ,IAAI9Y,MAAM+oB,QAAQC;oBACvCyI,iBAAiB,SAAS1I,QAAQC;oBAClCtE,SAAS,SAAS5L,IAAI9Y,MAAMigB,QAAQ0U;oBACpC3K,aAAa,SAASlR,IAAI9Y,MAAM40B;oBAChCrE,eAAe,SAASzX,IAAI9Y;oBAC5BmyB,iBAAiB,SAAS0C;oBAC1BjF,YAAY,SAASiF;oBACrBxD,gBAAgB,SAASvY;oBACzByM,UAAU,SAASzM;oBACnB2M,kBAAkB,SAAS3M,IAAI4M,UAAUC;oBACzCQ,iBAAiB,SAASzc;oBAC1BuQ,gBAAgB,SAASnB,IAAIwB,WAAWD;oBACxCuY,0BAA0B,SAASvD,UAAUnlB,SAASwb;;gBAG1DyI;oBACI2G,WAAW;oBACXC,WAAW;oBACXC,cAAc;oBACdC,YAAY;oBACZC,cAAc;oBACdnD,mBAAmB;oBACnBoD,qBAAqB;oBACrBC,oBAAoB;oBACpBC,qBAAqB;oBACrBC,oBAAoB;oBACpBC,uBAAuB;oBACvBjD,SAAS;oBACTnD,8BAA8B;;gBAGlC/M;oBACI0Q,YAAY;oBACZC,iBAAiB;oBACjB3C,kBAAkB;oBAClBvH,8BAA8B;;gBAGlCb;oBACIE,aAAa;oBACbD,aAAa;;gBAGjBrU;oBACI8K,SAAS;oBACT8W;wBACI9W,SAAS;;oBAEb+W,WAAW;oBACXC;wBACIC,WAAW;wBACXC,gBAAgB;wBAChBC,WAAW;wBACXC,eAAe;wBACfC,YAAY;;oBAEhBC,UAAU;oBAEV9rB;wBACImS,UAAU;;;gBAIlB3H;oBACIgK,SAAS;oBACTuX,iBAAiB;oBACjBP;wBACIQ,UAAU;;;gBAIlBxH,gBAAgB,SAASyH;oBACrB,OAAOA;;gBAGXx0B;oBACI4tB,sBAAsB;oBACtBjH,gBAAgB;oBAChBqC,eAAc,MAAM,MAAM,MAAM,MAAM,MAAM;;gBAGhD9L;oBACIH,SAAS;oBACTmG,QAAQ;oBACRxI,UAAU;oBACV8I;oBACA/I;;gBAGJkJ;oBACIqI,UAAU;oBACVyI,iBAAiB;oBACjBxI,UAAU;;gBAGd3Q;oBACIC,aAAa;;gBAGjB8I;oBACID,eAAe;oBACf7I,aAAa;;gBAGjBgP;oBACIvf,KAAK;oBAGLgV,QAAQ;;gBASZqJ;gBAIAlJ;oBACIzF,UAAU;oBACVD;oBACA+I;oBACApD,gBAAgB;;gBAIpBxS;oBAEIrR,SAAS;oBAGTqvB,YAAY;oBAGZ8I,iBAAiB;;gBAIrB1hB;oBACI2hB,eAAe;oBAGfC,cAAc;oBAGdC,QAAQ;oBAIRC,aAAa;oBAEbC,gBAAgB;oBAEhBC,aAAa;oBAEbC,aAAa;oBAGbC;;gBAGJhP;oBACIC,gBAAgB;oBAChBmH,mBAAmB;oBACnB9G,kBAAkB;;;YAK1BlqB,GAAG6B,OAAOxB,KAAK0e,UAAU5G,GAAG;YAE5B9X,KAAKojB;YACLpjB,KAAKysB;YACLzsB,KAAK8hB;YAEL9hB,KAAKo1B;YACLp1B,KAAKiqB,kBAAmB,IAAItqB,GAAGsS;YAE/BjS,KAAKse;YACLte,KAAKijB;YACLjjB,KAAKkjB;YACLljB,KAAKmjB;YACLnjB,KAAKqhB;YAELrhB,KAAK6iB,uBAAuB;YAC5B7iB,KAAKyiB,eAAe;YACpBziB,KAAKmgB,cAAcngB,KAAK8oB;YAExB9oB,KAAK4uB;YAEL5uB,KAAKqkB,sBAAsBrkB,KAAKgoB,aAAahoB,KAAK0e,SAASiI,QAAQE;YACnE7mB,KAAKwkB,gCAAgCxkB,KAAKgoB,aAAahoB,KAAK0e,SAAS6B,WAAWsG;YAEhF7mB,KAAK4kB,yBAAyB5kB,KAAKgoB,aAAahoB,KAAK0e,SAAS6B,WAAWzC;YAEzE9d,KAAKgiB,iBAAiBhiB,KAAKgoB,aAAahoB,KAAK0e,SAASiI,QAAQ5I;YAC9D/d,KAAK0kB,2BAA2B1kB,KAAKgoB,aAAahoB,KAAK0e,SAAS6B,WAAWxC;YAE3E/d,KAAK4f,WAAW5f,KAAKkqB;YAErBlqB,KAAKgzB,iBAAiBrzB,GAAG2mB,2BAA2BtmB,KAAKqmB;YAEzD,IAAIrmB,KAAK0e,SAAS2E,QAAQ;gBACtBrjB,KAAK+sB,mBAAmB/sB,KAAKkpB;oBACzBtpB,SAASI,KAAK0e,SAAS2E;oBACvB7K,OAAOxY,KAAK0e,SAASrb,KAAK2mB;mBAC3BvQ;;YAGPzZ,KAAKwsB;YAELxsB,KAAK2tB;YAEL,IAAI3tB,KAAK0e,SAASgJ,MAAMD,eAAe;gBACnC,IAAI9nB,GAAG6nB,cAAc;oBACjBxnB,KAAKujB,gBAAgBvjB,KAAKunB;uBAEzB;oBACDvnB,KAAK8F,IAAI,kCAAkC;;;YAInD9F,KAAK8zB;YAEL9zB,KAAKohB,kBAAkBzhB,GAAG64B,kBAAkB,IAAI74B,GAAG64B,eAAe74B,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;YACpFA,KAAK0jB;YAEL1jB,KAAK2jB;YACL3jB,KAAK4jB;YAEL5jB,KAAKy4B,UAAW94B,GAAGukB,UAAU,IAAIvkB,GAAGukB,OAAOlkB,KAAK0e,SAASrI,SAAS1W,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;YACpF,IAAIA,KAAKy4B,QAAQrY,SAAS;gBACtBpgB,KAAKquB,wBAAwB1uB,GAAGgQ,KAAK3P,KAAKy4B,QAAQC,eAAe14B,KAAKy4B;;YAG1E,IAAI94B,GAAGg5B,iBAAiBh5B,GAAGkT,kBAAkBsD,aAAa;gBACtDnW,KAAK6jB,iBAAiB,IAAIlkB,GAAGg5B,cACzBh5B,GAAGgQ,KAAK3P,KAAKkzB,kBAAkBlzB,OAE/B,SAASwa;oBACL,IAAIoe,QAAQ7gB,KAAKoI,YAAYvE;wBAAUpB,IAAIA;;oBAC3C,OAAQoe,SAASA,MAAMpd,QAAS;;;YAK5Cxb,KAAK4iB,oBAAoB5iB,KAAK0e,SAAS0K,WAAW4I;;QAItDryB,GAAG+1B,kBAAkBrvB,YAAY1G,GAAGge;QACpChe,GAAG6B,OAAO7B,GAAG+1B,kBAAkBrvB,WAAW1G,GAAG8lB;;ICnTjD9lB,GAAGk5B,gBAAgB,SAAS/gB;QACxB;QAEA,IAAIhS,KAAKgzB,6BACLC,YACAC,kBACA/gB;YACIghB,cAAc;YACdC,gBAAe,SAAS,QAAQ;YAChC3S,QAAQ;YACR4S,aAAa;YACb1S,gBAAgB;YAChBI;YACAE;YACAD;YACAsS;YACAC,oCAAoC;YACpCC;gBACIC,UAAS,KAAK,KAAK;gBACnBC,SAAQ,KAAK,KAAK,KAAK,KAAK;gBAC5BC,QAAO,KAAK,KAAK,KAAK,KAAK;gBAC3BC,OAAM,KAAK,KAAK,KAAK,KAAK;gBAC1BC,OAAM;;YAEV3S;gBACIqI,UAAU;gBACVyI,iBAAiB;;YAErBhyB,KAAK,SAAS4B,KAAK1B;YACnB4zB,QAAQ,SAASpf;YACjBoQ,YAAY,SAASpQ,IAAI4M,UAAUC;YACnCmD,YAAY;;QAGpB7qB,GAAG6B,OAAOyW,SAASH;QACnBhS,MAAMmS,QAAQnS;QAEd,IAAInG,GAAG2F,QAAQ2S,QAAQihB,cAAcjhB,QAAQsO,UAAU,GAAG;YACtD,MAAM,IAAIplB,MAAM,MAAM8W,QAAQsO,SAAS;;QAM3C,SAASsT;YACL,OAAOl6B,GAAG2F,UAAS,OAAO,QAAQ,UAAS2S,QAAQsO,WAAW;;QAMlE,SAASuT,yBAAyB1V;YAC9B,IAAI2V,oBAAoB;YAExBp6B,GAAG+C,KAAKq3B,mBAAmB,SAASp3B,KAAKq3B;gBACrC,IAAIr6B,GAAG2F,UAAS,UAAU,mBAAmB,oBAAoB,kBAAiB00B,UAAU,GAAG;oBAC3FD,oBAAoB;oBACpB,OAAO;;;YAIf,OAAOA;;QAGX,SAASE,MAAM3lB;YAEX,OAAO2D,QAAQ+O,KAAKqI,YAAY/a,IAAIC,oBAAoBzQ;;QAI5D,SAASo2B;YACL,IAAI9S;YAEJ,IAAIziB,OAAOmF,kBAAkBnF,OAAOoF,eAAe;gBAC/Cqd,WAAWznB,GAAGiK;gBAEd,IAAIwd,SAAS7S,oBAAoBzQ,WAAW;oBACxCsjB,WAAW,IAAI3S;oBAEf2S,SAASzb,SAAS;oBAClByb,SAASvb,UAAU;oBACnBub,SAAS+S,YAAY;oBACrB/S,SAASgT,aAAa;;;YAI9B,OAAOhT;;QAIX,SAASiT,YAAY7f,IAAI8f;YACrB,IAAIlT,WAAW4R,YAAYxe,IAAIlG;YAE/B,KAAK8S,UAAU;gBACX,IAAIkT,aAAa;oBACblT,WAAWkT;uBAEV;oBACD,IAAIriB,QAAQ+O,KAAKqI,UAAU;wBACvBjI,WAAW8S;2BAEV;wBACD9S,WAAWznB,GAAGiK;;;gBAItBovB,YAAYxe,IAAIlG,MAAM8S;;YAG1B,OAAOA;;QAIX,SAASmT,QAAQ/f;YACb,IAAI/J,IAAI9Q,GAAG2F,QAAQyzB,OAAOve,KACtB8R,MAAMrU,QAAQwO,gBACd+T;mBAEGxB,YAAYxe;YACnBue,MAAM7c,OAAOzL,GAAG;YAEhB,IAAIsoB,MAAMrzB,UAAU4mB,OAAO7b,IAAI6b,KAAK;gBAChCkO,SAASzB,MAAMzM,MAAM;gBACrBmO,YAAYD;;;QAIpB,SAAS5P,WAAWpQ,IAAIkgB;YACpB,IAAIpmB,MAAM+lB,YAAY7f,KAClB+L,SAAStO,QAAQsO,QACjBc,UAAUqT,aAAa;YAE3BH,QAAQ/f;YAER,IAAI6M,SAAS;gBACTvhB,IAAIygB,SAAS,kBAAkB/L,KAAK,eAAe;mBAElD,KAAKyf,MAAM3lB,SAASqmB,qBAAqBrmB,IAAIuG,SAAS;gBACvDwM,UAAU;gBACVvhB,IAAIygB,SAAS,kBAAkB/L,KAAK,iCAAiClG,IAAIuG,QAAQ;;YAGrF5C,QAAQ2S,WAAWpQ,IAAIlG,KAAK+S;;QAGhC,SAASuT,UAAUpgB;YACf,IAAIqgB,iBAAiB7B,YAAYxe,IAAIsgB,kBACjC1B,iBAAiBnhB,QAAQmhB,gBACzBtb;YAEJ,IAAI7F,QAAQ6O,YAAY7E,KAAK;gBACzBnE,SAAS7F,QAAQ6O,YAAY7E,IAAIzH;;YAGrC,IAAIqgB,gBAAgB;gBAChBl7B,GAAG+C,KAAKm4B,gBAAgB,SAASn5B,MAAMkB;oBACnCkb,SAASA;oBACTA,OAAOpc,QAAQkB;;;YAIvB,IAAIw2B,gBAAgB;gBAChBz5B,GAAG+C,KAAK02B,gBAAgB,SAAS13B,MAAMkB;oBACnCkb,SAASA;oBACTA,OAAOpc,QAAQkB;;;YAIvB,OAAOkb;;QAGX,SAAS2c,YAAYjgB,IAAIugB;YACrB,IAAIzmB,MAAM+lB,YAAY7f,IAAIugB,SACtBxU,SAAStO,QAAQsO,QACjBzI,SAAS8c,UAAUpgB,KACnBwgB,UAAUhC,YAAYxe,IAAIwgB,SAC1BC;YAEJhjB,QAAQ2hB,OAAOpf;YAEfygB,MAAMC,UAAU1gB,IAAIsD,QAAQkb,YAAYxe,IAAI2gB;YAG5C,IAAIlB,MAAM3lB,MAAM;gBACZA,IAAI3I,SAASyvB,kBAAkB5gB;gBAC/BlG,IAAIzI,UAAUwvB,mBAAmB7gB;mBAEhC;gBACDlG,IAAIgnB,qBAAqBC,8BAA8B/gB;;YAG3DghB,0BAA0BhhB;YAG1BlG,IAAImnB,KAAKlV,QAAQ0U,KAAK;YAItB,IAAIhjB,QAAQ+O,KAAKqI,YAAYpX,QAAQ+O,KAAK8Q,oBAAoBmC,MAAM3lB,MAAM;gBACtEA,IAAIC,kBAAkB;;YAG1BmnB,WAAWlhB;YAEX1U,IAAI,aAAaygB,SAAS,kBAAkB/L;YAE5C,IAAIwgB,SAAS;gBACT1mB,IAAIqnB,KAAKX;mBAER,IAAIlC,gCAAgChb,QAAQ;gBAC7CxJ,IAAIqnB;mBAEH,IAAI7d,UAAU7F,QAAQkhB,eAAelhB,QAAQkhB,YAAYlwB,cAAc3D,QAAQ,wCAAwC,GAAG;gBAC3HgP,IAAIqnB,KAAKh8B,GAAGsQ,QAAQ6N,QAAQ;mBAE3B,IAAIA,UAAU7F,QAAQkhB,eAAelhB,QAAQkhB,YAAYlwB,cAAc3D,QAAQ,uBAAuB,GAAG;gBAC1GgP,IAAIqnB,KAAKrqB,KAAKsqB,UAAU9d;mBAEvB;gBACDxJ,IAAIqnB,KAAK7d;;YAGb,OAAOxJ;;QAGX,SAAS4mB,UAAU1gB,IAAIsD,QAAQqd;YAC3B,IAAIpd,WAAW9F,QAAQ8O,cAAc9E,IAAIzH,KACrCqhB,YAAY7C,YAAYxe,IAAIqhB;YAGhC,IAAIA,aAAa/3B,WAAW;gBACxBia,YAAY,MAAM8d;;YAGtB,IAAI/C,+BAA+Bhb,QAAQ;gBACvCC,WAAWpe,GAAGsQ,QAAQ6N,QAAQC;;YAGlC,IAAIod,uBAAuB;gBACvBpd,WAAWpe,GAAGsQ,QAAQkrB,uBAAuBpd;;YAGjD,OAAOA;;QAKX,SAASwd,8BAA8B/gB;YACnC,OAAO;gBACH,IAAI6f,YAAY7f,IAAIshB,eAAe,GAAG;oBAClClR,WAAWpQ;;;;QAKvB,SAASghB,0BAA0BhhB;YAC/B,IAAIgQ,aAAavS,QAAQuS;YAEzB,IAAIA,YAAY;gBACZ6P,YAAY7f,IAAI3Q,OAAOuwB,aAAa,SAASvrB;oBACzC,IAAIA,EAAEktB,kBAAkB;wBACpBvR,WAAWhQ,IAAI3L,EAAE4b,QAAQ5b,EAAE6b;;;;;QAQ3C,SAAS0Q,kBAAkB5gB;YACvB,OAAO;gBACHoQ,WAAWpQ;;;QAMnB,SAAS6gB,mBAAmB7gB;YACxB,OAAO;gBACHoQ,WAAWpQ,IAAI;;;QAIvB,SAASkhB,WAAWlhB;YAChB,IAAIlG,MAAM+lB,YAAY7f,KAClBqM,gBAAgB5O,QAAQ4O,eACxBmV,kBAAkBhD,YAAYxe,IAAIyhB,yBAClC1V,SAAStO,QAAQsO,QACjB2V;YAGJ,KAAKjC,MAAM3lB,MAAM;gBACb2D,QAAQghB,gBAAgB3kB,IAAI6nB,iBAAiB,UAAUlkB,QAAQghB;gBAG/D,IAAIhhB,QAAQohB,oCAAoC;oBAK5C,KAAKphB,QAAQ+O,KAAKqI,cAAcwK,oBAAoBC,yBAAyBjT,iBAAiB;wBAC1FvS,IAAI6nB,iBAAiB,oBAAoB;wBACzC7nB,IAAI6nB,iBAAiB,iBAAiB;;;gBAI9C,IAAIlkB,QAAQkhB,gBAAgB5S,WAAW,UAAUA,WAAW,QAAQ;oBAChEjS,IAAI6nB,iBAAiB,gBAAgBlkB,QAAQkhB;;gBAGjDx5B,GAAG6B,OAAO06B,YAAYv8B,GAAG6G,WAAWqgB,iBAAiBA,cAAcrM,MAAMqM;gBACzElnB,GAAG6B,OAAO06B,YAAYF;gBAEtBr8B,GAAG+C,KAAKw5B,YAAY,SAASx6B,MAAMkB;oBAC/B0R,IAAI6nB,iBAAiBz6B,MAAMkB;;;;QAKvC,SAAS+3B,qBAAqByB;YAC1B,OAAOz8B,GAAG2F,QAAQ2S,QAAQqhB,wBAAwBrhB,QAAQsO,SAAS6V,iBAAiB;;QAGxF,SAASC,cAAc7hB,IAAIugB,QAAQc,WAAWf,kBAAkBK,uBAAuBc,mBAAmBjB;YACtGhC,YAAYxe;gBACRqhB,WAAWA;gBACXf,kBAAkBA;gBAClBK,uBAAuBA;gBACvBc,mBAAmBA;gBACnBjB,SAASA;;YAGb,IAAInuB,MAAMksB,MAAMl2B,KAAK2X;YAGrB,IAAI3N,OAAOoL,QAAQwO,gBAAgB;gBAC/B,OAAOgU,YAAYjgB,IAAIugB;;;QAI/BjC,8BAA8B7gB,QAAQsO,WAAW,SAAStO,QAAQsO,WAAW;QAE7E5mB,GAAG6B,OAAOxB;YAENs8B,eAAe,SAAS9hB;gBACpB,IAAI+hB,MAAMze,QAAQsG,SAAS4W,SAASwB,aAAarB;gBAEjD;oBAEIsB,UAAU,SAASC;wBACfH,OAAOG;wBACP,OAAO18B;;oBAOX28B,YAAY,SAAS7B;wBACjBhd,SAASgd;wBACT,OAAO96B;;oBAGX48B,iBAAiB,SAASC;wBACtB1B,wBAAwB0B;wBACxB,OAAO78B;;oBAIX88B,aAAa,SAASb;wBAClB7X,UAAU6X;wBACV,OAAOj8B;;oBAIX+8B,aAAa,SAASC;wBAClBhC,UAAUgC;wBACV,OAAOh9B;;oBAIXi9B,iBAAiB;wBACbT,cAAc;wBACd,OAAOx8B;;oBAIX27B,MAAM,SAASZ;wBACX,IAAIyB,eAAe78B,GAAG2F,UAAS,OAAO,YAAW2S,QAAQsO,WAAW,GAAG;4BACnEzI,OAAOof,cAAc,IAAIC,OAAOC;;wBAGpC,OAAOf,cAAc7hB,IAAIugB,QAAQwB,MAAMze,QAAQqd,uBAAuB/W,SAAS4W;;;;YAK3FqC,UAAU,SAAS7iB;gBACf+f,QAAQ/f;;;;IC1YpB7a,GAAG29B,gBAAgB,SAASjiB;QACxB;QAEA,IAAIkiB,QAAQliB,KAAKkiB,OACbC,gBACA1S,WAAWyS,MAAMzS,UACjBzK,UAAUkd,MAAMld;QAEpB1gB,GAAG6B,OAAOxB;YACNuQ,KAAK,SAASiK,IAAIijB;gBACdD,UAAUhjB,MAAMijB;gBAChBD,UAAUhjB,IAAIrK;;YAGlBwP,QAAQ,SAASnF;gBACb,IAAIzC,OAAO/X,MACP+qB,2BAA2B,IAAIprB,GAAG+L,WAClCgyB,iBAAiB5S,SAAStQ,IAAI6F,QAAQ7F,KAAKuQ;gBAE/C2S,eAAe3mB,KAAK;oBAChB,IAAIgB,KAAK4I,QAAQnG,KAAK;wBAClBgjB,UAAUhjB,IAAI6iB,WAAW;wBACzBtlB,KAAKqa,QAAQ5X;;oBAEjBuQ,yBAAyBnf;;;YAIjCwmB,SAAS,SAAS5X;uBACPgjB,UAAUhjB;;YAGrBmjB,qBAAqB,SAASnjB;gBAC1B,OAAOgjB,UAAUhjB,IAAIhL;;YAGzBmR,SAAS,SAASnG;gBACd,OAAOgjB,UAAUhjB,QAAQ1W;;YAG7BgW,OAAO;gBACH0jB;;YAGJI,eAAe,SAASpjB;gBACpB,OAAOgjB,UAAUhjB;;YAGrBqjB,sBAAsB,SAASrjB,IAAIsjB;gBAC/BN,UAAUhjB,IAAIhL,MAAMsuB;;YAGxBC,cAAc,SAASvjB;gBACnB,SAASgjB,UAAUhjB,IAAI6iB;;;;ICpDnC19B,GAAGusB,0BAA0B,SAASpU,GAAGsS;QACrC;QAEA,IAAI4T,aAAah+B,MACbi+B,mBAAmB,OACnBC,6BAA6B,OAC7B5oB,UAAU6oB,sBAAsBr4B,KAAKsoB,SAEzCnW;YACI6O;YACAL,gBAAgB;YAChBnR;gBACI8K,SAAS;gBACT1W;oBACI0W,SAAS;;;YAGjBta,KAAK,SAAS4B,KAAK1B;YACnBwkB,YAAY,SAAShQ,IAAIxI,UAAUyY,QAAQC;YAC3CE,YAAY,SAASpQ,IAAIxI,UAAU+e,UAAUzc;YAC7CwW,UAAU,SAAStQ,IAAIxI;YACvBiZ,cAAc,SAASzQ;YACvB2Q,UAAU,SAAS3Q,IAAIxI;YACvBqZ,eAAe,SAAS7Q,IAAIxI,UAAUsZ;YACtCE,sBAAsB,SAAShR,IAAI8Q,WAAWyF,UAAUzc;YACxDoX,aAAa,SAASlR,IAAIxI,UAAU+e,UAAUzc;YAC9CmX,UAAU,SAASjR,IAAIxI,UAAUsZ;YACjCO,eAAe,SAASrR,IAAI4B;YAC5BiE,SAAS,SAAS7F;YAClBsR,SAAS,SAAStR,IAAIiC;YACtBwP,UAAU,SAASzR;YACnBqC,oBAAoB,SAASrC;YAC7BsC,eAAe,SAAStC;WAG5B4jB;YAEI5mB,MAAM,SAASgD,IAAI6jB,UAAUtN,UAAUzc;gBACnC,IAAIgX,YAAY8C,QAAQkQ,cAAc9jB,IAAI6jB;gBAE1CjQ,QAAQwP,cAAcpjB,IAAI+jB,mBAAmB;uBAEtCnQ,QAAQwP,cAAcpjB,IAAIrK,KAAKquB,cAAcH;gBACpDjQ,QAAQwP,cAAcpjB,IAAIiQ,UAAUa,UAAU9P;gBAE9CvD,QAAQuT,qBAAqBhR,IAAI4T,QAAQqQ,yBAAyBnT,YAAYyF,UAAUzc;;YAK5FoqB,UAAU,SAASlkB;gBACf,IAAIgB,OAAOvD,QAAQsK,QAAQ/H,KACvB9Y,OAAOuW,QAAQoI,QAAQ7F;gBAE3B1U,IAAI,uCAAuC0U,KAAK;gBAChD4T,QAAQuQ,eAAenkB,IAAIzD,KACvB,SAASga,UAAUzc;oBACfxO,IAAI,6BAA6B0U;oBAEjC,IAAIokB,oBAAoB/0B,OAAOg1B,kBAAkB9N,UAAU;oBAE3D9Y,QAAQuS,WAAWhQ,IAAI9Y,MAAM8Z,MAAMA;oBACnC4S,QAAQ0Q,+BAA+BtkB;oBACvC3Q,OAAOk1B,QAAQvkB,IAAIokB,mBAAmBtqB;mBAE1C,SAASyc,UAAUzc;oBACf,IAAIsqB,oBAAoB/0B,OAAOg1B,kBAAkB9N,UAAU;oBAE3DjrB,IAAI,2CAA2C0U,KAAK,QAAQokB,kBAAkB50B,OAAO;oBAErF,IAAI40B,kBAAkB9kB,OAAO;wBACzBskB,QAAQtkB,MAAMU;;oBAGlB,KAAKvC,QAAQyT,YAAYlR,IAAI9Y,MAAMk9B,mBAAmBtqB,MAAM;wBACxDzK,OAAOk1B,QAAQvkB,IAAIokB,mBAAmBtqB;;;;YAMtD0qB,eAAe,SAASX,UAAU7jB,IAAIuW,UAAUzc;gBAC5C,IAAI5S,OAAOuW,QAAQoI,QAAQ7F;gBAE3B1U,IAAI,uCAAuC0U,KAAK,aAAa6jB;gBAE7DjQ,QAAQ6Q,iBAAiBzkB,IAAI6jB;gBAE7B,IAAIa,mBAAmBr1B,OAAOg1B,kBAAkB9N,UAAU,QACtDoO;gBAEJ,IAAID,iBAAiBplB,OAAO;oBACxBskB,QAAQtkB,MAAMU;uBAEb;oBACD2kB,gBAAgBx/B,GAAG2F,QAAQ8oB,QAAQwP,cAAcpjB,IAAIlF,SAAS8pB,YAAYf;oBAC1E,IAAIc,iBAAiB,GAAG;wBACpB/Q,QAAQwP,cAAcpjB,IAAIlF,SAAS8pB,WAAWljB,OAAOijB,eAAe;wBACpE/Q,QAAQwP,cAAcpjB,IAAIlF,SAAS+pB,UAAUC,QAAQjB;;;gBAM7D,KAAKjQ,QAAQwP,cAAcpjB,IAAIrK,KAAKovB,eAAe;oBAG/C,IAAIrB,4BAA4B;wBAC5B9P,QAAQwP,cAAcpjB,IAAIrK,KAAKovB,gBAAgB;wBAE/Cz5B,IAAInG,GAAG8H,OAAO,oFAAoF6J,KAAKsqB,UAAUx1B,OAAOo5B,KAAKpR,QAAQqR,SAASjlB,OAAOlJ,KAAKsqB,UAAUxN,QAAQwP,cAAcpjB,IAAIlF,SAAS8pB;wBACvMz/B,GAAG+C,KAAK0rB,QAAQqR,SAASjlB,KAAK,SAASklB,MAAMC;4BACzC75B,IAAInG,GAAG8H,OAAO,uDAAuD+S,IAAIklB,MAAMC,MAAM7D;4BACrF6D,MAAMC;4BAGND,MAAME,aAAa;;wBAIvBzR,QAAQ0R,0BAA0BtlB;wBAIlCulB,kBAAkBC,KAAKxlB,IAAI;;oBAG/B,KAAKvC,QAAQyT,YAAYlR,IAAI9Y,MAAMw9B,kBAAkB5qB,MAAM;wBAIvDzK,OAAOk1B,QAAQvkB,IAAI0kB,kBAAkB5qB;;;;YAKjD2rB,cAAc,SAASzlB;gBACnB,SAAS4T,QAAQwP,cAAcpjB,IAAIlF,SAAS+pB,UAAU35B;;YAG1Dw6B,UAAU,SAAS1lB;gBACf,IAAI2lB,UAAU/R,QAAQwP,cAAcpjB,IAAIlF,SAAS+pB,UAAUhtB;gBAE3D,IAAI8tB,WAAW/R,QAAQgS,gBAAgB5lB,KAAK;oBACxC2lB,UAAU;;gBAGd,OAAOA;;YAGXrmB,OAAO,SAASU;gBACZ1U,IAAI,gGAAgG0U,IAAI;gBAExG4T,QAAQ0Q,+BAA+BtkB;gBACvC4T,QAAQiS,mBAAmB7lB;gBAC3B4T,QAAQwP,cAAcpjB,IAAIiQ,SAAS;;YAGvC6V,UAAU,SAAS9lB;gBACf,IAAIgB,OAAOvD,QAAQsK,QAAQ/H,KACvB9Y,OAAOuW,QAAQoI,QAAQ7F,KACvB6jB,WAAWD,QAAQ8B,SAAS1lB,KAC5B8Q,YAAY8C,QAAQkQ,cAAc9jB,IAAI6jB,WACtCzG,WAAWxJ,QAAQwP,cAAcpjB,IAAI+jB,kBACrCgC,mBAAmBnS,QAAQwP,cAAcpjB,IAAIlF,SAAS8pB;gBAE1D,IAAIhR,QAAQwP,cAAcpjB,IAAIiQ,UAAU,MAAM;oBAC1C2D,QAAQwP,cAAcpjB,IAAIiQ,SAAS;;gBAIvC,IAAImN,YAAY3f,QAAQwT,SAASjR,IAAI9Y,MAAM4pB,eAAe,OAAO;oBAC7D8S,QAAQtkB,MAAMU;oBACd6jB,WAAWD,QAAQ8B,SAAS1lB;oBAC5B8Q,YAAY8C,QAAQkQ,cAAc9jB,IAAI6jB;oBACtCzG,WAAW;;gBAIf,IAAIyG,YAAY,QAAQkC,iBAAiB76B,WAAW,GAAG;oBACnD04B,QAAQM,SAASlkB;uBAIhB;oBACD1U,IAAInG,GAAG8H,OAAO,qEAAqE+S,IAAI6jB,UAAU/S,UAAU3gB,QAAQ,GAAG2gB,UAAU1gB,KAAK4Q;oBACrIvD,QAAQoT,cAAc7Q,IAAI9Y,MAAM0sB,QAAQqQ,yBAAyBnT;oBACjEiV,iBAAiB19B,KAAKw7B;oBACtBjQ,QAAQwP,cAAcpjB,IAAIlF,SAAS8pB,aAAamB;oBAEhD,IAAIrC,4BAA4B;wBAC5B6B,kBAAkBtE,KAAKjhB,IAAI6jB;;oBAG/B,IAAIH,8BAA8B6B,kBAAkBS,eAAepS,QAAQwP,cAAcpjB,IAAIlF,SAAS+pB,UAAU35B,QAAQ;wBACpH04B,QAAQkC,SAAS9lB;;oBAGrB,IAAI8Q,UAAUlgB,KAAKoQ,SAAS,GAAG;wBAC3B1V,IAAInG,GAAG8H,OAAO,gEAAgE42B,UAAU7jB,KAAK;wBAC7F4jB,QAAQY,cAAcX,UAAU7jB,IAAI,+BAA+B;2BAElE;wBACD4T,QAAQqS,YAAYjmB,IAAI6jB,UAAUzG,UAAU7gB,KAExC,SAASnL,QAAQmlB,UAAUzc;4BACvBxO,IAAI,0CAA0C0U,KAAK,aAAa6jB;4BAEhEjQ,QAAQ6Q,iBAAiBzkB,IAAI6jB;4BAE7B,IAAIkC,mBAAmBnS,QAAQwP,cAAcpjB,IAAIlF,SAAS8pB,kBACtDF,mBAAmBr1B,OAAOg1B,kBAAkB9N,UAAU,OACtD2P,qBAAqB/gC,GAAG2F,QAAQi7B,kBAAkBlC;4BAEtDv4B,IAAInG,GAAG8H,OAAO,+CAA+C42B,UAAU7jB;4BAEvE4jB,QAAQ5mB,KAAKgD,IAAI6jB,UAAUa,kBAAkB5qB;4BAE7C,IAAIosB,sBAAsB,GAAG;gCACzBH,iBAAiBrkB,OAAOwkB,oBAAoB;;4BAGhDtS,QAAQuS,0BAA0BnmB;4BAElC,KAAK4jB,QAAQ6B,aAAazlB,OAAO+lB,iBAAiB76B,WAAW,GAAG;gCAC5D04B,QAAQM,SAASlkB;mCAEhB,IAAI4jB,QAAQ6B,aAAazlB,KAAK;gCAC/B4jB,QAAQkC,SAAS9lB;mCAEhB;gCACD1U,IAAInG,GAAG8H,OAAO,qGAAqG+S,IAAIlJ,KAAKsqB,UAAU2E;;2BAK9I,SAASz0B,QAAQilB,UAAUzc;4BACvB8pB,QAAQY,cAAcX,UAAU7jB,IAAIuW,UAAUzc;2BAGjDkD,KAAK;4BACF4W,QAAQwS,SAASpmB,IAAI6jB;;;;;WAO7C0B;YACIc;YACAC;YACAC;YAEAP,WAAW;gBACP,IAAIlU,MAAMrU,QAAQwO,gBACdua,wBAAwB,GACxBC,kBAAkB;gBAEtBthC,GAAG+C,KAAKq9B,kBAAkBe,aAAa,SAASjgB,QAAQqgB;oBACpDF;oBACAC,mBAAmBC,iBAAiBx7B;;gBAGxC,OAAO4mB,OAAOyT,kBAAkBc,MAAMn7B,SAASs7B,wBAAwBC;;YAM3EjB,MAAM,SAASxlB,IAAI2mB;gBACf,IAAIC,aAAaD,eACbE,eAAe1hC,GAAG2F,QAAQy6B,kBAAkBgB,UAAUvmB,KACtD8mB,mBAAmB3hC,GAAG2F,QAAQy6B,kBAAkBc,OAAOrmB,KACvDggB;uBAEGuF,kBAAkBe,YAAYtmB;gBAErC,IAAI3Q,OAAO03B,eAAe/mB,eAAe7a,GAAG8X,WAAW;oBACnD3R,IAAI,yCAAyC0U,KAAK;2BAC3C4T,QAAQwP,cAAcpjB,IAAI+E;;gBAIrC,IAAI8hB,gBAAgB,GAAG;oBACnBtB,kBAAkBgB,SAAS7kB,OAAOmlB,cAAc;uBAG/C,IAAID,aAAaE,oBAAoB,GAAG;oBACzCvB,kBAAkBc,MAAM3kB,OAAOolB,kBAAkB;oBAEjD9G,SAASuF,kBAAkBgB,SAAS1uB;oBACpC,IAAImoB,UAAU,GAAG;wBACbuF,kBAAkBc,MAAMh+B,KAAK23B;wBAC7B3wB,OAAOc,MAAM6vB;;;;YAKzBgH,uBAAuB;gBACnB,IAAIC;gBAIJ9hC,GAAG+C,KAAKq9B,kBAAkBe,aAAa,SAASjgB,QAAQ6gB;oBACpD,IAAIA,UAAUA,OAAOh8B,QAAQ;wBACzB+7B,mBAAmB5+B,KAAK8+B,SAAS9gB;;;gBAMzClhB,GAAG+C,KAAKq9B,kBAAkBc,OAAO,SAASl+B,KAAKke;oBAC3C,KAAKkf,kBAAkBe,YAAYjgB,SAAS;wBACxC4gB,mBAAmB5+B,KAAK8+B,SAAS9gB;;;gBAKzC4gB,qBAAqBA,mBAAmB1xB,OAAOgwB,kBAAkBgB;gBAEjE,OAAOU;;YAGXG,mBAAmB,SAASpnB;gBACxB,OAAO7a,GAAG2F,QAAQy6B,kBAAkBc,OAAOrmB,OAAO;;YAGtDihB,MAAM,SAASjhB,IAAI6jB;gBACf,IAAIA,YAAY,MAAM;oBAClB0B,kBAAkBgB,SAASl+B,KAAK2X;;gBAGpC,IAAIulB,kBAAkBS,aAAa;oBAC/B,IAAInC,YAAY,MAAM;wBAClB0B,kBAAkBgB,SAASc;wBAC3B9B,kBAAkBc,MAAMh+B,KAAK2X;2BAE5B;yBACA;4BACG,IAAIsnB,kBAAkB/B,kBAAkBe,YAAYtmB;4BACpDsnB,gBAAgBj/B,KAAKw7B;4BACrB0B,kBAAkBe,YAAYtmB,MAAMsnB;;;oBAI5C,OAAO;;gBAGX,OAAO;;YAGXhoB,OAAO;gBACHimB,kBAAkBgB;gBAClBhB,kBAAkBc;;WAI1BkB;YACIpG,MAAM,SAASnhB,IAAI9Y;gBACf0sB,QAAQwP,cAAcpjB,IAAIiQ,SAAS;gBAEnC3kB,IAAI,uCAAuC0U;gBAC3C4T,QAAQ4T,WAAWxnB,IAAIzD,KACnB,SAASga,UAAUgK;oBACfj1B,IAAI,yCAAyC0U;oBAE7C,IAAI0kB,mBAAmBr1B,OAAOg1B,kBAAkB9N,UAAU,OACtDvV,OAAOvD,QAAQsK,QAAQ/H;oBAE3BvC,QAAQuS,WAAWhQ,IAAI9Y,MAAM8Z,MAAMA;oBACnC3R,OAAOo4B,aAAaznB,IAAI0kB;oBACxBr1B,OAAOk1B,QAAQvkB,IAAI0kB,kBAAkBnE;mBAGzC,SAAShK,UAAUgK;oBACfj1B,IAAI,sCAAsC0U;oBAE1C,IAAI0kB,mBAAmBr1B,OAAOg1B,kBAAkB9N,UAAU;oBAE1D,KAAK9Y,QAAQyT,YAAYlR,IAAI9Y,MAAMw9B,kBAAkBnE,SAAS;wBAC1DlxB,OAAOk1B,QAAQvkB,IAAI0kB,kBAAkBnE;;;;WAOzDlxB;YACI8V,QAAQ,SAASnF;gBACb1U,IAAI,gBAAgB0U;gBACpBvC,QAAQ6O,YAAY/lB,OAAOyZ;gBAC3BulB,kBAAkBC,KAAKxlB;;YAG3BukB,SAAS,SAASvkB,IAAIuW,UAAUgK;gBAC5B,IAAIr5B,OAAOuW,QAAQoI,QAAQ7F;gBAE3BvC,QAAQ2S,WAAWpQ,IAAI9Y,MAAMqvB,UAAUgK;gBAEvC,IAAI3M,QAAQwP,cAAcpjB,KAAK;oBAC3B4T,QAAQ8T,cAAc9T,QAAQ8T,WAAW1nB;;gBAG7CulB,kBAAkBC,KAAKxlB;;YAK3B+mB,gBAAgB,SAAS/mB;gBACrB,OAAQ4T,QAAQ+T,YAAY/T,QAAQ+T,SAAS3nB,OACxC4T,QAAQ7M,WAAW6M,QAAQ7M,QAAQ/G;;YAG5C4nB,aAAa;gBACT,IAAIC,cAAcjY,YAAYzqB,GAAGyqB,aAAazqB,GAAG2iC,aAC7CC,uBAAuB5iC,GAAGkT,kBAAkBsC,gBAAgB,QAAQ;gBAExEiZ,UAAU,IAAIiU,YAAYE,uBAAuB,iBAC7CtqB;oBAEI+T,eAAe/T,QAAQ+T;oBACvB3L,SAASpI,QAAQoI;oBACjBkC,SAAStK,QAAQsK;oBACjBO,SAAS7K,QAAQ6K;oBACjBhd,KAAKA;oBACLglB,UAAU7S,QAAQ6S;oBAClBN,YAAYvS,QAAQuS;oBACpBqB,eAAe5T,QAAQ4T;;gBAI/B,IAAIuC,QAAQoU,+BAA+B;oBACvCpU,QAAQoU;;;YAIhBC,6BAA6B,SAASjoB;gBAClC,OAAOvC,QAAQgU,SAASzR;;YAM5BkoB,YAAY,SAASloB,IAAIpP;gBAIrB,IAAIA,SAASgjB,QAAQ7M,QAAQ/G,OAAOpP,gBAAgBzL,GAAG8X,WAAW;oBAK9DQ,QAAQgT,aAAazQ;oBAErB1U,IAAI,iDAAiD0U;oBACrDpP,KAAKwM,SAASb,KAAK,SAAS4rB;wBACxB78B,IAAI,qCAAqC0U;wBAGzC4T,QAAQwU,WAAWpoB,IAAImoB;wBAGvB1qB,QAAQ6T,QAAQtR,IAAImoB,cAAcnnB;wBAGlC4S,QAAQiS,mBAAmB7lB;wBAE3B3Q,OAAOg5B,uBAAuBroB;uBAIlC,SAAS+Y;wBACL,IAAIuP;wBAEJ,IAAIvP,cAAc;4BACduP,cAAc94B,QAAQupB;;wBAG1BztB,IAAInG,GAAG8H,OAAO,0DAA0D+S,IAAI+Y,eAAe;wBAE3Ftb,QAAQ2S,WAAWpQ,IAAIvC,QAAQoI,QAAQ7F,KAAK7a,GAAG6B,OAAOshC,eAAe3E,uBAAuB;wBAC5Ft0B,OAAOg5B,uBAAuBroB;wBAC9BulB,kBAAkBC,KAAKxlB;;uBAG1B;oBACD,OAAO3Q,OAAOg5B,uBAAuBroB;;gBAGzC,OAAO;;YAIXqoB,wBAAwB,SAASroB;gBAC7B,IAAIuoB,aAAa9qB,QAAQ4E,mBAAmBrC,KACxCwoB,iBAAiB;gBAErB,IAAID,cAAcA,WAAWr9B,QAAQ;oBACjCI,IAAI,4CAA4C0U;oBAEhD7a,GAAG+C,KAAKqgC,YAAY,SAASpgC,KAAKsgC;wBAC9B,IAAIp5B,OAAO44B,4BAA4BQ,gBAAgB7U,QAAQ7M,QAAQ0hB,YAAY;4BAC/ED,iBAAiBC,cAAczoB;4BAC/B3Q,OAAOq5B,IAAID;+BAEV,IAAIp5B,OAAO44B,4BAA4BQ,YAAY;4BACpD,OAAO;;;uBAId;oBACDD,iBAAiB;oBACjBn5B,OAAOq5B,IAAI1oB;;gBAGf,OAAOwoB;;YAGXf,cAAc,SAASznB,IAAIuW;gBACvB,IAAIA,SAAS3U,YAAYtY,WAAW;oBAChCmU,QAAQ4T,cAAcrR,IAAIuW,SAAS3U;;;YAO3CyiB,mBAAmB,SAASsE,kBAAkB1R;gBAC1C,IAAIV,WAAWoS;gBAIf,KAAKxjC,GAAGuG,SAASi9B,mBAAmB;oBAChCpS;oBAEA,IAAIpxB,GAAGwH,SAASg8B,sBAAsB1R,YAAY;wBAC9CV,SAAS/mB,QAAQm5B;;;gBAIzBpS,SAASnlB,UAAU6lB;gBAEnB,OAAOV;;YAGXmS,KAAK,SAAS1oB;gBACV,IAAI9Y,OAAOuW,QAAQoI,QAAQ7F;gBAE3B,KAAKwjB,WAAWrd,QAAQnG,KAAK;oBACzB,MAAM,IAAI7a,GAAGwB,MAAMqZ,KAAK;;gBAG5BvC,QAAQkT,SAAS3Q,IAAI9Y;gBAErB,IAAIu8B,oBAAoB7P,QAAQgV,qBAAqB5oB,KAAK;oBACtD4jB,QAAQkC,SAAS9lB;uBAEhB;oBACDunB,OAAOpG,KAAKnhB,IAAI9Y;;;YAIxBiJ,OAAO,SAAS6P;gBACZ,IAAI6oB,eAAex5B,OAAO03B,eAAe/mB;gBAEzC,IAAI6oB,cAAc;oBACd,OAAOx5B,OAAO64B,WAAWloB,IAAI6oB;uBAE5B;oBACDx5B,OAAOq5B,IAAI1oB;oBACX,OAAO;;;;QAKnB7a,GAAG6B,OAAOxB;YAINuQ,KAAK,SAASiK,IAAI+E;gBACd6O,QAAQ7d,IAAIP,MAAMhQ,MAAM8H;;YAM5B+B,QAAQ,SAAS2Q;gBACb,IAAIulB,kBAAkBtE,KAAKjhB,KAAK;oBAC5B,OAAO3Q,OAAOc,MAAM6P;;gBAExB,OAAO;;YAGXsJ,OAAO,SAAStJ;gBAKZ,IAAI0jB,4BAA4B;oBAC5B9P,QAAQwP,cAAcpjB,IAAIrK,KAAKovB,gBAAgB;;gBAKnD,IAAIQ,kBAAkB6B,kBAAkBpnB,KAAK;oBACzC,OAAO3Q,OAAOc,MAAM6P;uBAMnB;oBACD,OAAOwjB,WAAWn0B,OAAO2Q;;;YAOjCmF,QAAQ,SAASnF;gBACb,IAAI8oB,eAAelV,QAAQzO,OAAOnF;gBAElC,IAAI7a,GAAGkX,iBAAiBysB,eAAe;oBACnCA,aAAavsB,KAAK;wBACdlN,OAAO8V,OAAOnF;;uBAGjB,IAAI8oB,iBAAiB,OAAO;oBAC7Bz5B,OAAO8V,OAAOnF;;;YAOtBqF,WAAW;gBACP,IAAI4hB,qBAAqB1B,kBAAkByB,yBACvC/wB;gBAIJ,IAAIgxB,mBAAmB/7B,QAAQ;oBAC3B,KAAK+K,IAAIgxB,mBAAmB/7B,SAAS,GAAG+K,KAAK,GAAGA,KAAK;wBACjDutB,WAAWre,OAAO8hB,mBAAmBhxB;;;gBAI7CsvB,kBAAkBjmB;;YAKtByH,SAAS,SAAS/G;gBACd,IAAI4T,QAAQ+T,YAAY/T,QAAQ+T,SAAS3nB,KAAK;oBAC1C,OAAO4T,QAAQ+T,SAAS3nB,IAAI9C;;gBAGhC,OAAO0W,QAAQ7M,WAAW6M,QAAQ7M,QAAQ/G;;YAI9C+oB,WAAW,SAAS/oB;gBAChB,UAAU4T,QAAQ+T,YAAY/T,QAAQ+T,SAAS3nB;;YAGnDhB,UAAU,SAASgB;gBACf,IAAI4T,QAAQ5U,UAAU;oBAClB,OAAO4U,QAAQ5U,SAASgB;;;YAIhCV,OAAO;gBACHhU,IAAI;gBACJk4B,WAAWne;gBACXkgB,kBAAkBjmB;gBAClBsU,QAAQtU;;YAGZsY,SAAS,SAAS5X;gBACd,IAAIwjB,WAAWrd,QAAQnG,KAAK;oBACxB,OAAO4T,QAAQgE,QAAQ5X;;;YAO/BmG,SAAS,SAASnG;gBACd,OAAO4T,QAAQzN,QAAQnG;;YAG3B8H,uBAAuB;gBACnB,IAAI8L,QAAQ9L,uBAAuB;oBAC/B,OAAO8L,QAAQ9L;;gBAEnB;;YAWJqb,qBAAqB,SAASnjB;gBAC1B,IAAIwjB,WAAWrd,QAAQnG,KAAK;oBACxB,OAAO4T,QAAQuP,oBAAoBnjB;;;YAS3CtE,OAAO,SAASsE;gBACZ,IAAIwjB,WAAWwF,YAAYhpB,OAAO4T,QAAQlY,SAAS8nB,WAAWrd,QAAQnG,OAAO4T,QAAQlY,MAAMsE,KAAK;oBAC5FulB,kBAAkBC,KAAKxlB;oBACvB4T,QAAQ0R,0BAA0BtlB;oBAClC,OAAO;;gBAEX,OAAO;;YAIXgpB,aAAa,SAAShpB;gBAClB,SAAS4T,QAAQoV,eAAepV,QAAQoV,YAAYhpB;;;QAI5D7a,GAAG6B,OAAOyW,SAASH;QACnBhS,MAAMmS,QAAQnS;QACdm4B,mBAAmBhmB,QAAQ3C,SAAS8K,WAAWzgB,GAAGkT,kBAAkByC;QACpE4oB,6BAA6BD,oBAAoBhmB,QAAQ3C,SAAS4hB,WAAW9W;QAE7E+d,uBAAwB;YACpB,IAAIpN;YAEJA,SAAS9Y,QAAQqS,qBAAqB;YAEtC,OAAOyG;;QAGXlnB,OAAOu4B;;IC9uBXziC,GAAG8jC,uBAAuB,SAAS3rB;QAC/B;QAEA,IAAIG;YACInS,KAAK,SAASC,SAASC;WAE3B09B;QAEJ/jC,GAAG6B,OAAOyW,SAASH;QAEnBnY,GAAG6B,OAAOxB;YACN2jC,gBAAgB,SAASnpB,IAAIpL;gBACzB,IAAIw0B,2BAA2B,SAAS7P;oBAChC3kB,SAAS2kB,MAAMtvB;;gBAGvB,IAAIE,OAAOuQ,aAAa;oBACpBwuB,yBAAyBlpB,MAAM7a,GAAGgF,QAAQ1E,OAAO,WAAW2jC;uBAE3D;oBACD99B,IAAI,yDAAyD;;;YAIrE+9B,uBAAuB,SAASrpB;gBAC5B,IAAI7V,OAAOuQ,aAAa;oBACpB,IAAI4uB,WAAWJ,yBAAyBlpB;oBACxC,IAAIspB,UAAU;wBACVA;;;;;;ICvBpBnkC,GAAGokC,oBAAoB,SAAS1oB;QAC5B;QAEA,IAAIpD,UAAUoD,KAAKpD,SACfmW,UAAUpuB,MACVu9B,QAAQliB,KAAKkiB,OACbyG,wBAAwBrkC,GAAGoN,eAC3Bk3B,sBACAC,uBACAC,gCACAC,SAASnsB,QAAQmsB,QACjBta,YAAY7R,QAAQ6R,WACpBhH,UAAUya,MAAMza,SAChBhd,MAAMy3B,MAAMz3B,KACZu+B,sBAAsB,IAAI1kC,GAAG8jC;YAAsB39B,KAAKA;;QAO5D,SAASw+B,YAAY9pB;mBACV0pB,iBAAiB1pB;YAKxB,IAAI4pB,QAAQ;gBACRlS,aAAaiS,0BAA0B3pB;uBAChC2pB,0BAA0B3pB;gBACjC6pB,oBAAoBR,sBAAsBrpB;;YAG9C,IAAI+pB,SAAS/6B,SAASg7B,eAAepW,QAAQqW,eAAejqB;YAC5D,IAAI+pB,QAAQ;gBAIRA,OAAOrzB,aAAa,OAAO;gBAE3BvR,GAAG4kC,QAAQxjC;;;QAQnB,SAAS2jC,uBAAuBC;YAC5B,OAAOA,WAAWt/B,MAAM,KAAK;;QAUjC,SAASu/B,oBAAoBljC;YACzB,IAAI6iC,SAAS5kC,GAAGoP,UAAU,2CAA2CrN,OAAO;YAE5E6iC,OAAOrzB,aAAa,MAAMxP;YAE1B6iC,OAAOzkC,MAAMC,UAAU;YACvByJ,SAASq7B,KAAK1zB,YAAYozB;YAE1B,OAAOA;;QAUX,SAASO,4BAA4BP,QAAQn1B;YACzC,IAAIu1B,aAAaJ,OAAO/pB,IACpBqG,SAAS6jB,uBAAuBC,aAChChqB,OAAOmI,QAAQjC;YAEnBojB,gBAAgBtpB,QAAQvL;YAIxB80B,iBAAiBrjB,UAAUlhB,GAAG4kC,QAAQtkC,OAAO,QAAQ;gBACjD,IAAImuB,QAAQ5U,SAASqH,SAAS;oBAC1B/a,IAAI,qEAAqE6+B,aAAa;oBAEtFR,0BAA0BQ,cAAc1b,WAAW;wBAC/C,IAAIsK,eAAe,kEAAkEoR;wBACrF7+B,IAAIytB,cAAc;wBAClBnkB;4BACIpF,OAAOupB;;uBAEZ;;;YAMX8Q,oBAAoBV,eAAegB,YAAY,SAAS5+B;gBACpDD,IAAI,6CAA6CC,UAAU;gBAC3D,IAAI8a,SAAS6jB,uBAAuBC,aAChC5T,WAAW3C,QAAQ2W,mBAAmBh/B,UACtC4U,OAAOoW,SAASpW,MAChBqqB;gBAEJ,IAAIrqB,QAAQspB,gBAAgBtpB,OAAO;oBAC/B7U,IAAI,uCAAuC6+B;oBAC3CzS,aAAaiS,0BAA0BQ;2BAChCR,0BAA0BQ;oBAEjCvW,QAAQ6W,iBAAiBN;oBAEzBK,iBAAiBf,gBAAgBtpB;2BAE1BspB,gBAAgBtpB;oBACvB0pB,oBAAoBR,sBAAsBc;oBAC1CK,eAAejU;uBAEd,KAAKpW,MAAM;oBACZ7U,IAAI,MAAMC,UAAU;;;;QAKhCpG,GAAG6B,OAAOxB,MAAM,IAAIL,GAAG29B,cAAcjiB;QAErC1b,GAAGwM,SAASnM,MAAM,SAASsM;YACvB;gBAIIiE,KAAK,SAASiK,IAAI0S;oBACd5gB,OAAOiE,IAAIiK;wBAAKjR,OAAO2jB;;oBAEvBA,UAAUhc,aAAa,QAAQ4Y;oBAG/B,IAAIoD,UAAUpsB,YAAY;wBACtBnB,GAAGutB,WAAWnsB;;;gBAItBqxB,SAAS,SAAS5X;oBACd8pB,YAAY9pB;oBACZlO,OAAO8lB,QAAQ5X;;gBAGnBmG,SAAS,SAASnG;oBACd,OAAOlO,OAAOqU,QAAQnG,OAClB4T,QAAQwP,cAAcpjB,IAAIjR,UAAUzF;;;;QAKpDnE,GAAG6B,OAAOxB;YACNwZ,UAAU,SAASgB;gBACf,OAAO4T,QAAQwP,cAAcpjB,IAAIjR;;YAWrC27B,kBAAkB,SAASX,QAAQn1B;gBAE/B,IAAI+1B;gBAEJ,IAAIf,QAAQ;oBACRU,4BAA4BP,QAAQn1B;uBAEnC;oBACD80B,iBAAiBK,OAAO/pB,MAAM7a,GAAG4kC,QAAQtkC,OAAO,QAAQ;wBACpD6F,IAAI,2BAA2By+B,OAAO/pB;wBAKtC,KAAK+pB,OAAOzjC,YAAY;4BACpB;;wBAGJ;4BAEI,IAAIyjC,OAAOa,mBACPb,OAAOa,gBAAgBP,QACvBN,OAAOa,gBAAgBP,KAAK31B,aAAa,SAAS;gCAKlD;;0BAGR,OAAOlF;4BAEHlE,IAAI,gFAAgFkE,MAAMjE,UAAU,KAAK;4BACzGo/B;gCAAsBv5B,SAAS;;;wBAGnCwD,SAAS+1B;;;;YAWrBE,eAAe,SAAS7qB;gBACpB,IAAImqB,aAAavW,QAAQqW,eAAejqB;gBAExC,OAAOoqB,oBAAoBD;;YAQ/BM,kBAAkB,SAASzqB;gBACvB,IAAI0pB,iBAAiB1pB,QAAQ1W,WAAW;oBACpCogC,iBAAiB1pB;2BACV0pB,iBAAiB1pB;;;YAQhCiqB,gBAAgB,SAAS5jB;gBACrB,OAAOA,SAAS,MAAMmjB;;YAY1BsB,oBAAoB,SAASjqB;gBACzB,IAAIkL,SAASlL,KAAKkL,QACdxI,WAAW1C,KAAK0C,UAChBD,SAASzC,KAAKyC,QACdgY,eAAeza,KAAKya,cACpByP,aAAalqB,KAAKkqB,YAClBt0B,OAAOtR,GAAGoP,UAAU,mBAAmBwX,SAAS,4CAChD0U,MAAMld;gBAEV,IAAI+X,cAAc;oBACdn2B,GAAGqR,WAAW8M,QAAQ7M;uBAErB;oBACDgqB,MAAMt7B,GAAGsQ,QAAQ6N,QAAQC;;gBAG7B9M,KAAKC,aAAa,UAAU+pB;gBAC5BhqB,KAAKC,aAAa,UAAUq0B;gBAC5Bt0B,KAAKnR,MAAMC,UAAU;gBACrByJ,SAASq7B,KAAK1zB,YAAYF;gBAE1B,OAAOA;;YAOX8zB,oBAAoB,SAASS;gBACzB,IAAIzU;gBAEJ;oBACIA,WAAWpxB,GAAGyR,UAAUo0B;kBAE5B,OAAOx7B;oBACHlE,IAAI,4DAA4DkE,MAAMjE,UAAU,KAAK;;gBAGzF,OAAOgrB;;;;ICnSnBpxB,GAAG8lC,mBAAmB,SAASpqB;QAC3B;QAEA,IAAI+S,UAAUpuB,MACVoqB,YAAY/O,KAAKpD,QAAQmS,WACzBmT,QAAQliB,KAAKkiB,OACbjoB,WAAW+F,KAAKpD,QAAQ3C,UACxBc,SAASiF,KAAKpD,QAAQ7B,QACtBsvB,aAAapwB,YAAY+F,KAAKpD,QAAQ3C,SAAS8K,WAAWzgB,GAAGkT,kBAAkByC,UAC/EqwB,gBAAgBvvB,UAAUiF,KAAKpD,QAAQ7B,OAAOgK,WAAWslB,cAAc/lC,GAAGkT,kBAAkBuD,QAC5FiK,UAAUkd,MAAMld,SAChBkC,UAAUgb,MAAMhb,SAChBO,UAAUya,MAAMza,SAChBf,cAAcwb,MAAMxb,aACpBiK,gBAAgBuR,MAAMvR,eACtBH,gBAAgB0R,MAAM1R,eACtBrB,aAAa+S,MAAM/S,YACnB1kB,MAAMy3B,MAAMz3B;QAEhB,SAAS85B,MAAMplB;YACX7a,GAAG+C,KAAK0rB,QAAQqR,SAASjlB,KAAK,SAASorB,OAAOtxB;gBAC1C,IAAIuxB,gBAAgBzX,QAAQ0X,kBAAkBtrB,IAAIorB;gBAElDtxB,IAAIgnB,qBAAqB;gBACzBhnB,IAAIzK,OAAOuwB,aAAa;gBACxB9lB,IAAIsrB;gBACJiG,iBAAiBA,cAAcxI,YAAYwI,cAAcxI,SAAS7iB;;;QAI1E7a,GAAG6B,OAAOxB,MAAM,IAAIL,GAAG29B,cAAcjiB;QAErC1b,GAAGwM,SAASnM,MAAM,SAASsM;YACvB;gBAIIiE,KAAK,SAASiK,IAAIurB;oBACd,IAAIpmC,GAAGyI,OAAO29B,gBAAgBpmC,GAAGyJ,OAAO28B,cAAc;wBAClDz5B,OAAOiE,IAAIiK;4BAAK+E,MAAMwmB;;2BAErB,IAAIA,uBAAuBpmC,GAAG8X,WAAW;wBAC1CnL,OAAOiE,IAAIiK;4BAAK+iB,OAAOwI;;2BAEtB;wBACD,MAAM,IAAI5kC,MAAM;;oBAGpBitB,QAAQ4X,eAAexrB;oBACvBmrB,iBAAiBvX,QAAQ6X,uBAAuBzrB;;gBAGpD4X,SAAS,SAAS5X;oBACdolB,MAAMplB;oBACN4T,QAAQ0Q,+BAA+BtkB;oBACvC4T,QAAQ8T,WAAW1nB;oBACnBlO,OAAO8lB,QAAQ5X;;;;QAK3B7a,GAAG6B,OAAOxB;YAENi/B,kBAAkB,SAASzkB,IAAI6jB;uBACpBjQ,QAAQwP,cAAcpjB,IAAIrK,KAAK+1B,aAAa7H;;YAGvDuC,UAAU,SAASpmB,IAAI6jB;gBACnB,IAAI8H,YAAY/X,QAAQwP,cAAcpjB,IAAIrK;gBAE1C,IAAIg2B,UAAUC,MAAM;2BACTD,UAAUC,KAAK/H;;gBAE1B,IAAI8H,UAAUE,gBAAgB;2BACnBF,UAAUE,eAAehI;;;YAMxCM,gBAAgB,SAASnkB,IAAI8rB;gBACzB,IAAIC,eAAenY,QAAQgS,gBAAgB5lB,MAAM,GAC7ClG,MAAM8Z,QAAQoY,QAAQhsB,IAAI+rB;gBAE9B,IAAID,gBAAgB;oBAChB,OAAO,IAAI3mC,GAAG+L,UAAUE,QAAQ06B,eAAehyB,MAAMA;;gBAGzD,OAAO,IAAI3U,GAAG+L,UAAUE,YAAY0I;;YAGxCiN,SAAS,SAAS/G;gBACd,OAAO4T,QAAQzN,QAAQnG,OAAO4T,QAAQwP,cAAcpjB,IAAI+E;;YAG5D4iB,UAAU,SAAS3nB;gBACf,OAAO4T,QAAQzN,QAAQnG,OAAO4T,QAAQwP,cAAcpjB,IAAI+iB;;YAO5Djb,uBAAuB;gBACnB,IAAImkB;gBAEJrY,QAAQsY,sBAAsB,SAASl3B,KAAK0Q;oBACxCkO,QAAQ0R,0BAA0B,MAAM5f,WAAW5K,SAAS8pB,YAAalf,WAAW5K,SAAS+pB;oBAE7F,IAAI56B;wBACA/C,MAAMwe,WAAWxe;wBACjB29B,WAAWnf,WAAW5K,SAAS+pB;wBAC/B7jB,MAAM0E,WAAW1E;wBACjBb,MAAMuF,WAAWvF;;oBAGrB,IAAIuF,WAAW1Q,KAAK;wBAChB/K,KAAK+K,MAAM0Q,WAAW1Q;;oBAG1Bi3B,mBAAmB5jC,KAAK4B;;gBAG5B,OAAOgiC;;YAGXjD,aAAa,SAAShpB;gBAClB,SAASlF,YAAY8Y,QAAQzN,QAAQnG,QAAQ4T,QAAQwP,cAAcpjB,IAAImsB;;YAG3E7G,2BAA2B,SAAStlB,IAAIosB,eAAeC;gBACnD,IAAIzH,aAAawH,iBAAiBxY,QAAQwP,cAAcpjB,IAAIlF,SAAS8pB,YACjEC,YAAYwH,gBAAgBzY,QAAQwP,cAAcpjB,IAAIlF,SAAS+pB;gBAEnE,IAAID,YAAY;oBACZt5B,IAAInG,GAAG8H,OAAO,0DAA0D6J,KAAKsqB,UAAUwD;oBACvFA,WAAW0H;oBACXnnC,GAAG+C,KAAK08B,YAAY,SAASz8B,KAAK07B;wBAC9BgB,UAAUC,QAAQjB;;oBAEtBe,WAAW15B,SAAS;;;YAI5BwQ,OAAO,SAASsE;gBACZ,IAAI4T,QAAQzN,QAAQnG,KAAK;oBACrB1U,IAAInG,GAAG8H,OAAO,6DAA6D+S,IAAI6F,QAAQ7F;oBACvF4T,QAAQwP,cAAcpjB,IAAIusB,SAAS;oBACnCnH,MAAMplB;oBACN,OAAO;;;YAIf6lB,oBAAoB,SAAS7lB;gBACzB,IAAIlF,YAAY8Y,QAAQzN,QAAQnG,KAAK;oBACjC,IAAInD,QAAQ+W,QAAQwP,cAAcpjB,KAC9BwsB,aACAv2B;2BAEG4G,MAAM/B;oBAEb+B,MAAM/B;oBACN0xB,cAAc5Y,QAAQgS,gBAAgB5lB;oBACtC,IAAIwsB,cAAc,KAAK1xB,SAAS6hB,WAAW;wBACvC9f,MAAM/B,SAAS8K,UAAU;wBACzB/I,MAAM/B,SAAS2xB,QAAQD;wBACvB3vB,MAAM/B,SAAS+pB;wBAEf,KAAK5uB,IAAI,GAAGA,IAAIu2B,aAAav2B,KAAK;4BAC9B4G,MAAM/B,SAAS+pB,UAAUx8B,KAAK4N;;wBAGlC2d,QAAQ4X,eAAexrB;2BAEtB;wBACDnD,MAAM/B,SAAS8K,UAAU;;;;YAKrCwiB,YAAY,SAASpoB,IAAI0sB;gBACrB,IAAI9Y,QAAQzN,QAAQnG,KAAK;oBACrB4T,QAAQwP,cAAcpjB,IAAI+E,OAAO2nB;;;YAIzChF,YAAY,SAAS1nB;gBACjB,IAAI2rB,YAAY/X,QAAQwP,cAAcpjB,IAAIrK;gBAE1CxQ,GAAG+C,KAAKyjC,UAAUE,gBAAgB,SAASc;2BAChChB,UAAUE,eAAec;;gBAGpCxnC,GAAG+C,KAAKyjC,UAAUC,MAAM,SAASe;2BACtBhB,UAAUC,KAAKe;;;YAW9BC,YAAY,SAAS5sB,IAAI6sB;gBACrB,OAAOjZ,QAAQkZ,aAAa9sB,IAAI6sB,aAAa1nC,GAAGiK;;YAGpDk8B,mBAAmB,SAAStrB,IAAI6sB;gBAC5B,IAAIhJ,WAAWgJ,eAAe,QAAQ,IAAIA;gBAC1C,OAAOjZ,QAAQwP,cAAcpjB,IAAIrK,KAAKk2B,eAAehI;;YAGzDC,eAAe,SAAS9jB,IAAI+sB;gBACxB,IAAIhQ,YAAYjiB,SAASoiB,UACrB8P,WAAWjlB,QAAQ/H,KACnB9P,aAAa0jB,QAAQ7M,QAAQ/G,KAC7BitB,aAAalQ,YAAYgQ,YACzBG,WAAWD,aAAalQ,aAAaiQ,WAAWA,WAAWC,aAAalQ,WACxEyP,cAAc5Y,QAAQgS,gBAAgB5lB,KACtC0rB,eAAelmC,KAAK49B,cAAcpjB,IAAIrK,KAAK+1B,cAI3C96B,OAAO86B,aAAaqB,eAAe5nC,GAAG8K,UAAUC,YAAY+8B,YAAYC;gBAE5ExB,aAAaqB,cAAcn8B;gBAE3B;oBACIu8B,MAAMJ;oBACN58B,OAAO88B;oBACP78B,KAAK88B;oBACLE,OAAOZ;oBACP57B,MAAMA;oBACNoQ,MAAMksB,WAAWD;;;YAIzBhJ,0BAA0B,SAASnT;gBAC/B;oBACI+L,WAAW/L,UAAUqc;oBACrBE,WAAWvc,UAAU3gB,QAAQ;oBAC7Bm9B,SAASxc,UAAU1gB;oBACnB6sB,YAAYnM,UAAUsc;;;YAQ9BG,oBAAoB,SAASvtB;gBACzB,IAAIwtB,gBAAgB,OAChBtmC,OAAO2e,QAAQ7F,KACfgB,OAAO+G,QAAQ/H,KACf+c,YAAYjiB,SAASoiB,UACrB3Z,WAAWgE,YAAYvH;gBAE3B,OAAO7a,GAAG8H,OAAO,4BAA4B2iB,WAAW4d,eAAetmC,MAAM8Z,MAAM+b,WAAWxZ;;YAGlGkqB,cAAc,SAASztB;gBACnB,OAAO4T,QAAQ7M,QAAQ/G,IAAIta;;YAG/BgoC,qBAAqB,SAAS1tB;gBAC1B,OAAO4T,QAAQwP,cAAcpjB,IAAIlF;;YAOrC8qB,iBAAiB,SAAS5lB;gBACtB,IAAIlF,UAAU;oBACV,IAAIkyB,WAAWjlB,QAAQ/H,KACnB+c,YAAYjiB,SAASoiB;oBAEzB,OAAOp2B,KAAK6mC,KAAKX,WAAWjQ;;;YAIpCiP,SAAS,SAAShsB,IAAI6sB;gBAClB,IAAIhJ,WAAWgJ,eAAe,QAAQ,IAAIA;gBAC1C,OAAOjZ,QAAQwP,cAAcpjB,IAAIrK,KAAKi2B,KAAK/H;;YAG/CoB,UAAU,SAASjlB;gBACf,OAAO4T,QAAQwP,cAAcpjB,IAAIrK,KAAKi2B;;YAK1CM,uBAAuB,SAASt3B;gBAC5B,IAAIu2B,eAAe;oBACfhmC,GAAG+C,KAAKoS,cAAc,SAAStF,KAAKvI;wBAChC,IAAIuI,IAAIlK,QAAQ3F,GAAG8H,OAAO,cAAc2iB,gBAAgB,GAAG;4BACvD,IAAIlK,aAAa5O,KAAKC,MAAMtK;4BAC5BmI,SAASI,KAAK0Q;;;;;YAM9B8lB,gBAAgB,SAASxrB;gBACrB4T,QAAQwP,cAAcpjB,IAAIrK;oBACtBk2B;oBACA7H;oBACA4H;oBACAF;;;YAIRkC,mBAAmB,SAAS5tB;gBACxB4T,QAAQwP,cAAcpjB,IAAImsB,eAAe;;YAK7C7H,gCAAgC,SAAStkB;gBACrC,IAAI6tB;gBAEJ,IAAI1C,iBAAiBvX,QAAQoV,YAAYhpB,KAAK;oBAC1C6tB,iBAAiBja,QAAQ2Z,mBAAmBvtB;oBAE5C,IAAI6tB,kBAAkBvzB,aAAarF,QAAQ44B,iBAAiB;wBACxDvzB,aAAawzB,WAAWD;wBACxB,OAAO;;;gBAIf,OAAO;;YAKXpC,wBAAwB,SAASzrB;gBAC7B,IAAInD,QAAQ+W,QAAQwP,cAAcpjB,KAC9B6tB,gBAAgBE;gBAIpB,IAAI5C,iBAAiBtuB,MAAM7H,QAAQ1L,WAAW;oBAC1CukC,iBAAiBja,QAAQ2Z,mBAAmBvtB;oBAC5C+tB,gBAAgBzzB,aAAarF,QAAQ44B;oBAGrC,IAAIE,eAAe;wBACfA,gBAAgBj3B,KAAKC,MAAMg3B;wBAI3B,IAAIvc,cAAcuc,cAAc5tB,OAAO;4BACnCyT,QAAQga,kBAAkB5tB;+BAEzB;4BACD1U,IAAInG,GAAG8H,OAAO,2DAA2D+S,IAAI6F,QAAQ7F;4BAErFqR,cAAcrR,IAAI+tB,cAAc5tB;4BAEhCtD,MAAM7H,MAAM+4B,cAAc/4B;4BAC1B6H,MAAM/B,WAAWizB,cAAcjzB;4BAC/B+B,MAAMoT,SAAS8d,cAAc9d;4BAC7BpT,MAAMknB,mBAAmB;4BAEzBnQ,QAAQ0R,0BAA0BtlB;;;;;YAOlDmmB,2BAA2B,SAASnmB;gBAChC,IAAInD,QAAQ+W,QAAQwP,cAAcpjB,KAC9B6tB,gBAAgBE;gBAGpB,IAAI5C,iBAAiBvX,QAAQoV,YAAYhpB,KAAK;oBAC1C6tB,iBAAiBja,QAAQ2Z,mBAAmBvtB;oBAE5C+tB;wBACI7mC,MAAM2e,QAAQ7F;wBACdgB,MAAM+G,QAAQ/H;wBACdG,MAAMmI,QAAQtI;wBACdhL,KAAK6H,MAAM7H;wBACX8F,UAAU+B,MAAM/B;wBAChBmV,QAAQpT,MAAMoT;wBACd+d,aAAarL,KAAK+F;;oBAGtB;wBACIpuB,aAAaC,QAAQszB,gBAAgB/2B,KAAKsqB,UAAU2M;sBAExD,OAAOv+B;wBACHlE,IAAInG,GAAG8H,OAAO,2DAA2D+S,IAAIxQ,MAAM1D,aAAa;;;;YAK5GmiC,0BAA0B,SAASjuB,IAAI6jB,UAAU9G;gBAC7C,IAAIjjB,MAAM8Z,QAAQoY,QAAQhsB,IAAI6jB,WAC1B38B,OAAO2e,QAAQ7F,KACfkuB;oBACI3G,QAAQ,SAAStX,QAAQC;wBACrB,IAAI8c,WAAWjlB,QAAQ/H;wBAEvB,IAAIiQ,WAAWC,OAAO;4BAClBF,WAAWhQ,IAAI9Y,MAAM8lC,UAAUA;+BAE9B;4BACDhd,WAAWhQ,IAAI9Y,MAAO+oB,UAAU+c,WAAWA,WAAW,IAAI/c,QAAS+c;;;oBAI3EpJ,SAAS,SAAS3T,QAAQC;wBACtB,IAAI8T,gBAAgBpQ,QAAQwP,cAAcpjB,IAAIrK,KAAKquB,eAC/CmK,iCAAiCva,QAAQwP,cAAcpjB,IAAIiQ,QAC3Dme,mBAAmBne,QACnBoe,kBAAkBne,OAClB8M,gBAAgBjV,QAAQ/H,KACxBsuB,uBAAuBF,oBAAoBC,kBAAkBtR,YAC7DwR,qBAAqBJ;wBAEzBnK,cAAcH,YAAYyK;wBAE1BnpC,GAAG+C,KAAK87B,eAAe,SAASH,UAAU2K;4BACtCD,sBAAsBC;;wBAG1Bxe,WAAWhQ,IAAI9Y,MAAMqnC,oBAAoBvR;;;gBAIrDljB,IAAIzK,OAAOuwB,aAAa,SAASvrB;oBAC7B,IAAIA,EAAEktB,kBAAkB;wBAEpB,IAAI77B,OAAOq3B,aAAa,OAAO,WAAW;wBAC1CmR,mBAAmBxoC,MAAM2O,EAAE4b,QAAQ5b,EAAE6b;;;;YAcjD4c,cAAc,SAAS9sB,IAAI6sB,aAAa/yB,KAAK20B;gBACzC,IAAIC,SAAS7B,eAAe,QAAQ,IAAIA,aACpClB,YAAY/X,QAAQwP,cAAcpjB,IAAIrK;gBAE1Cg2B,UAAUC,OAAOD,UAAUC;gBAC3BD,UAAUE,iBAAiBF,UAAUE;gBAErCF,UAAUC,KAAK8C,UAAU50B;gBAEzB,IAAI20B,kBAAkB;oBAClB9C,UAAUE,eAAe6C,UAAUD;;gBAGvC,OAAO30B;;YAIXkuB,+BAA+B;gBAC3B,IAAI2G,iBAAiB/yB,OAAOuhB;gBAE5BvJ,QAAQsY,sBAAsB,SAASl3B,KAAK0Q;oBACxC,IAAIkpB,iBAAiB,IAAIjM,KAAKjd,WAAWsoB;oBAGzCY,eAAeC,QAAQD,eAAeE,YAAYH;oBAElD,IAAIC,eAAehM,aAAaD,KAAK+F,OAAO;wBACxCp9B,IAAI,6CAA6C0J;wBACjDsF,aAAawzB,WAAW94B;;;;YAWpC4zB,sBAAsB,SAAS5oB;gBAC3B,IAAInD,QAAQ+W,QAAQwP,cAAcpjB;gBAElC,KAAKnD,MAAM/B,UAAU;oBACjB8Y,QAAQiS,mBAAmB7lB;;gBAG/B,OAAOnD,MAAM/B,SAAS8K;;;;ICxflCzgB,GAAG2mB,0BAA0B,SAASxO;QAClC;QAEA,IAAIyxB,WACAtxB;YACIsO,QAAQ;YACRG,eAAe;YACfK;YACAN,gBAAgB;YAChBI,eAAe,SAASrM;gBAAK;;YAC7BsM;YACAE;gBACIqI,UAAU;gBACVyI,iBAAiB;;YAErBhyB,KAAK,SAAS4B,KAAK1B;YACnBihB,UAAU,SAASzM;YACnB2M,kBAAkB,SAAS3M,IAAI4M,UAAUC;;QAGjD1nB,GAAG6B,OAAOyW,SAASH;QAEnB,SAAS0xB;YACL,IAAIvxB,QAAQsO,OAAOC,kBAAkB,QAAQ;gBACzC;oBACIijB,SAAS;;;YAIjB;;QAGJF,YAAY5pC,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGk5B;YAC/BI,cAAc;YACdC,gBAAe,QAAQ;YACvB3S,QAAQtO,QAAQsO;YAChBQ,eAAe9O,QAAQ8O;YACvBD,aAAa7O,QAAQ6O;YACrBsS,gBAAgBoQ;YAChB/iB,gBAAgBxO,QAAQwO;YACxBI,eAAe,SAASrM;gBACpB,OAAOvC,QAAQ4O,cAAc5E,IAAIzH;;YAErC1U,KAAKmS,QAAQnS;YACb8zB,QAAQ3hB,QAAQgP;YAChB2D,YAAY3S,QAAQkP;YACpBH,MAAM/O,QAAQ+O;;QAGlBrnB,GAAG6B,OAAOxB;YACNizB,YAAY,SAASzY,IAAIG,MAAMkY;gBAC3B,IAAI1I,oBAAoB0I;gBAExB5a,QAAQnS,IAAI,wCAAwC0U;gBAEpD,IAAIvC,QAAQsO,WAAW,UAAU;oBAC7BgjB,UAAUjN,cAAc9hB,IACnBiiB,SAAS9hB,MACTgiB,WAAWxS,mBACXwR;uBAEJ;oBACDxR,kBAAkBlS,QAAQyO,iBAAiB/L;oBAC3C4uB,UAAUjN,cAAc9hB,IACnBmiB,WAAWxS,mBACXwR;;;;;KCpDrB;QAMI,SAAS+N,kBAAkBC;YACvB,IAAIC,KAAKD,IAAIE,cACTC,KAAKH,IAAII,eACT/lC,SAASwF,SAASC,cAAc,WAChCugC;YAEJ,IAAIJ,KAAKE,KAAK,OAAO,MAAM;gBACvB9lC,OAAOimC,QAAQjmC,OAAOqV,SAAS;gBAC/B2wB,MAAMhmC,OAAOkmC,WAAW;gBACxBF,IAAIG,UAAUR,MAAMC,KAAK,GAAG;gBAI5B,OAAOI,IAAII,aAAa,GAAG,GAAG,GAAG,GAAG3lC,KAAK,OAAO;mBAC7C;gBACH,OAAO;;;QAQf,SAAS4lC,qBAAqBV,KAAKC,IAAIE;YACnC,IAAI9lC,SAASwF,SAASC,cAAc,WAChC6gC,KAAK,GACLC,KAAKT,IACLU,KAAKV,IACLE,KAAKvlC,MAAMgmC,OAAOC;YAEtB1mC,OAAOimC,QAAQ;YACfjmC,OAAOqV,SAASywB;YAChBE,MAAMhmC,OAAOkmC,WAAW;YACxBF,IAAIG,UAAUR,KAAK,GAAG;YACtBllC,OAAOulC,IAAII,aAAa,GAAG,GAAG,GAAGN,IAAIrlC;YAGrC,OAAO+lC,KAAKF,IAAI;gBACZG,QAAQhmC,MAAM+lC,KAAK,KAAK,IAAI;gBAC5B,IAAIC,UAAU,GAAG;oBACbF,KAAKC;uBACF;oBACHF,KAAKE;;gBAETA,KAAMD,KAAKD,MAAO;;YAGtBI,QAASF,KAAKV;YACd,OAAQY,UAAU,IAAK,IAAIA;;QAM/B,SAASC,qBAAqBhB,KAAKv+B,MAAM6M,SAAS2yB;YAC9C,IAAI5mC,SAASwF,SAASC,cAAc,WAChCxF,OAAOgU,QAAQhU,QAAQ,cACvBwH,UAAU,IAAI9L,GAAG+L;YAErBm/B,oBAAoBlB,KAAKv+B,MAAMpH,QAAQiU,SAAS2yB,UAC3C7zB,KAAK;gBACFtL,QAAQG,QACJ5H,OAAOI,UAAUH,MAAMgU,QAAQ/T,WAAW;;YAItD,OAAOuH;;QAGX,SAASq/B,oCAAoCzvB;YACzC,IAAI0vB,YAAY;YAEhB,KAAKprC,GAAG0O,OAAO;gBACX,MAAM,IAAI1O,GAAGwB,MAAM;;YAGvB,IAAIka,KAAK2vB,aAAa3vB,KAAK4vB,YAAYF,WAAW;gBAC9C;oBACIG,WAAW5pC,KAAKC,MAAMD,KAAK6pC,KAAKJ,aAAa1vB,KAAK2vB,aAAa3vB,KAAK4vB;oBACpEG,UAAU9pC,KAAKC,MAAMD,KAAK6pC,KAAKJ,aAAa1vB,KAAK4vB,YAAY5vB,KAAK2vB;;;;QAQ9E,SAASH,oBAAoBlB,KAAKv+B,MAAMpH,QAAQiU,SAAS2yB;YACrD,IAAIhB,KAAKD,IAAIE,cACTC,KAAKH,IAAII,eACTE,QAAQhyB,QAAQgyB,OAChB5wB,SAASpB,QAAQoB,QACjB2wB,MAAMhmC,OAAOkmC,WAAW,OACxBz+B,UAAU,IAAI9L,GAAG+L,WACjB2/B;YAEJrB,IAAIsB;YAEJ,IAAIrzB,QAAQszB,QAAQ;gBAChB,OAAOC;oBACHpgC,MAAMA;oBACNpH,QAAQA;oBACRkxB,OAAOyU;oBACP8B,aAAa3B;oBACb4B,YAAY9B;oBACZ+B,aAAa1zB,QAAQ0zB;oBACrBJ,QAAQtzB,QAAQszB;oBAChBK,cAAcvyB;oBACdwyB,aAAa5B;;;YAIrB,KAAKtqC,GAAGkT,kBAAkB0D,0BAA0B;gBAChD80B,qBAAqBP;oBACjBG,WAAWhB;oBACXe,YAAY3xB;;gBAGhB,IAAIgyB,oBAAoB;oBACpB1rC,GAAGmG,IAAInG,GAAG8H,OAAO,kFACbwiC,OAAO5wB,QAAQgyB,mBAAmBD,UAAUC,mBAAmBH,YAC/D;oBAEJjB,QAAQoB,mBAAmBD;oBAC3B/xB,SAASgyB,mBAAmBH;;;YAIpCY,oBAAoB9nC,QAAQimC,OAAO5wB,QAAQpB,QAAQ0zB;YAInD,IAAIhsC,GAAG0O,OAAO;iBACT;oBACG,IAAIq7B,kBAAkBC,MAAM;wBACxBC,MAAM;wBACNE,MAAM;;oBAGV,IAAIiC,IAAI,MACJC,YAAYxiC,SAASC,cAAc,WACnCwiC,kBAAkBrB,WAAWP,qBAAqBV,KAAKC,IAAIE,MAAM,GACjEoC,KAAK5qC,KAAK6mC,KAAK4D,IAAI9B,QAAQL,KAC3BuC,KAAK7qC,KAAK6mC,KAAK4D,IAAI1yB,SAASywB,KAAKmC,kBACjC3B,KAAK,GACL8B,KAAK,GACLC,QAAQC,IAAIC;oBAEhBP,UAAU/B,QAAQ+B,UAAU3yB,SAAS0yB;oBACrCM,SAASL,UAAU9B,WAAW;oBAE9B,OAAOI,KAAKR,IAAI;wBACZwC,KAAK;wBACLC,KAAK;wBACL,OAAOD,KAAK1C,IAAI;4BACZyC,OAAOG,UAAU,GAAG,GAAGT,GAAGA;4BAC1BM,OAAOlC,UAAUR,MAAM2C,KAAKhC;4BAC5BN,IAAIG,UAAU6B,WAAW,GAAG,GAAGD,GAAGA,GAAGQ,IAAIH,IAAIF,IAAIC;4BACjDG,MAAMP;4BACNQ,MAAML;;wBAEV5B,MAAMyB;wBACNK,MAAMD;;oBAEVnC,IAAIyC;oBACJT,YAAYK,SAAS;;mBAGxB;gBACDrC,IAAIG,UAAUR,KAAK,GAAG,GAAGM,OAAO5wB;;YAGpCrV,OAAO0oC,mBAAmB1oC,OAAO0oC;YACjCjhC,QAAQG;YAER,OAAOH;;QAGX,SAAS+/B,qCAAqCmB;YAC1C,IAAIvhC,OAAOuhC,WAAWvhC,MAClB8pB,QAAQyX,WAAWzX,OACnBuW,cAAckB,WAAWlB,aACzBC,aAAaiB,WAAWjB,YACxBC,cAAcgB,WAAWhB,aACzBlgC,UAAU,IAAI9L,GAAG+L,WACjB6/B,SAASoB,WAAWpB,QACpBqB,eAAepjC,SAASC,cAAc,WACtCojC,sBAAsBD,aAAa1C,WAAW,OAC9C4C,eAAeH,WAAW3oC,QAC1B4nC,eAAee,WAAWf,cAC1BC,cAAcc,WAAWd;YAE7BC,oBAAoBc,cAAclB,YAAYD,aAAaE;YAE3DmB,aAAazzB,SAASuyB;YACtBkB,aAAa7C,QAAQ4B;YAErBgB,oBAAoB1C,UAAUjV,OAAO,GAAG;YAExCqW;gBACIngC,MAAMA;gBACNiO,QAAQuyB;gBACR1W,OAAOA;gBACP0X,cAAcA;gBACdE,cAAcA;gBACd7C,OAAO4B;eAEN90B,KACG,SAASnL;gBACLkhC,aAAaJ,mBAAmBI,aAAaJ;gBAC7CjhC,QAAQG;eAEZH,QAAQK;YAGhB,OAAOL;;QAOX,SAASqgC,oBAAoB9nC,QAAQimC,OAAO5wB,QAAQsyB;YAChD,QAAQA;cACJ,KAAK;cACL,KAAK;cACL,KAAK;cACL,KAAK;gBACD3nC,OAAOimC,QAAQ5wB;gBACfrV,OAAOqV,SAAS4wB;gBAChB;;cACJ;gBACIjmC,OAAOimC,QAAQA;gBACfjmC,OAAOqV,SAASA;;YAExB,IAAI2wB,MAAMhmC,OAAOkmC,WAAW;YAC5B,QAAQyB;cACJ,KAAK;gBAED3B,IAAI+C,UAAU9C,OAAO;gBACrBD,IAAI1oB,OAAO,GAAG;gBACd;;cACJ,KAAK;gBAED0oB,IAAI+C,UAAU9C,OAAO5wB;gBACrB2wB,IAAIgD,OAAO1rC,KAAK2rC;gBAChB;;cACJ,KAAK;gBAEDjD,IAAI+C,UAAU,GAAG1zB;gBACjB2wB,IAAI1oB,MAAM,IAAI;gBACd;;cACJ,KAAK;gBAED0oB,IAAIgD,OAAO,KAAM1rC,KAAK2rC;gBACtBjD,IAAI1oB,MAAM,IAAI;gBACd;;cACJ,KAAK;gBAED0oB,IAAIgD,OAAO,KAAM1rC,KAAK2rC;gBACtBjD,IAAI+C,UAAU,IAAI1zB;gBAClB;;cACJ,KAAK;gBAED2wB,IAAIgD,OAAO,KAAM1rC,KAAK2rC;gBACtBjD,IAAI+C,UAAU9C,QAAQ5wB;gBACtB2wB,IAAI1oB,OAAO,GAAG;gBACd;;cACJ,KAAK;gBAED0oB,IAAIgD,QAAQ,KAAM1rC,KAAK2rC;gBACvBjD,IAAI+C,WAAW9C,OAAO;gBACtB;;cACJ;gBACI;;;QAOZ,SAASiD,aAAaC,UAAUC;YAC5B,IAAIr1B,OAAO/X;YAEX,IAAI2E,OAAOO,QAAQioC,oBAAoBjoC,MAAM;iBACxC;oBACG,IAAIykC,MAAM,IAAI0D,SACVC,MAAM3oC,OAAO2oC,OAAO3oC,OAAO2oC,IAAIC,kBAAkB5oC,OAAO2oC,MACpD3oC,OAAO6oC,aAAa7oC,OAAO6oC,UAAUD,kBAAkB5oC,OAAO6oC,YAAY;oBAClF,KAAKF,KAAK;wBAAE,MAAMnsC,MAAM;;oBACxBwoC,IAAI8D,MAAMH,IAAIC,gBAAgBJ;oBAC9Bp1B,KAAK3M,OAAO+hC;oBACZA,WAAWxD;;;YAGnB,KAAKwD,SAAStD,iBAAiBsD,SAASpD,eAAe;gBACnDoD,SAASxhC,SAAS;oBACd,IAAI+hC,YAAY31B,KAAK41B;oBACrB,IAAID,WAAW;wBACX31B,KAAK41B,qBAAqB;wBAG1B1kB,WAAW;4BACP,KAAK,IAAIxY,IAAI,GAAG5D,MAAM6gC,UAAUhoC,QAAQ+K,IAAI5D,KAAK4D,KAAK;gCAClDi9B,UAAUj9B;;2BAEf;;;gBAGX08B,SAASthC,UAAUuhC;gBACnBptC,KAAK2tC;;YAET3tC,KAAKmtC,WAAWA;;QAMpBD,aAAa7mC,UAAUunC,SAAS,SAASxhC,QAAQ6L;YAC7CA,UAAUA;YAEV,IAAIF,OAAO/X,MACP6tC,WAAW7tC,KAAKmtC,SAAStD,cACzBiE,YAAY9tC,KAAKmtC,SAASpD,eAC1BE,QAAQhyB,QAAQgyB,OAChB5wB,SAASpB,QAAQoB,QACjB4c,WAAWhe,QAAQge,UACnBD,YAAY/d,QAAQ+d,WACpB4U,YAAY5qC,KAAKoL,QAAQpL,KAAKoL,KAAKlL,SAAS,cAC5CiJ,UAAUiD,OAAOjD,QAAQF,eACzB8kC;YAEJ,IAAI/tC,KAAK2tC,oBAAoB;gBACzB3tC,KAAK2tC,mBAAmB9qC,KAAK;oBAAakV,KAAK61B,OAAOxhC,QAAQ6L;;gBAC9D;;YAGJ,IAAIgyB,UAAU5wB,QAAQ;gBAClBA,SAAUy0B,YAAY7D,QAAQ4D,YAAa;mBACxC,IAAIx0B,WAAW4wB,OAAO;gBACzBA,QAAS4D,WAAWx0B,SAASy0B,aAAc;mBACxC;gBACH7D,QAAQ4D;gBACRx0B,SAASy0B;;YAEb,IAAI7X,YAAYgU,QAAQhU,UAAU;gBAC9BgU,QAAQhU;gBACR5c,SAAUy0B,YAAY7D,QAAQ4D,YAAa;;YAE/C,IAAI7X,aAAa3c,SAAS2c,WAAW;gBACjC3c,SAAS2c;gBACTiU,QAAS4D,WAAWx0B,SAASy0B,aAAc;;YAG/CC;gBAAQ9D,OAAOA;gBAAO5wB,QAAQA;eAC9B1Z,GAAG+C,KAAKuV,SAAS,SAAS+1B,YAAYC;gBAClCF,IAAIC,cAAcC;;YAGtB,IAAI9kC,YAAY,OAAO;iBAClB;oBACG,IAAI+kC,eAAe9hC,OAAOqhC;oBAC1B9C,qBAAqB5yB,KAAKo1B,UAAUp1B,KAAK3M,MAAM2iC,KAAKnD,UAC/C7zB,KAAK,SAAS1S;wBACX+H,OAAOqhC,MAAMppC;wBACb6pC,iBAAiB9hC,OAAOqhC,OAAOrhC,OAAOT;;;mBAG/C,IAAIxC,YAAY,UAAU;gBAC7B0hC,oBAAoB7qC,KAAKmtC,UAAUntC,KAAKoL,MAAMgB,QAAQ2hC,KAAKnD;;YAE/D,WAAW5qC,KAAKmuC,aAAa,YAAY;gBACrCnuC,KAAKmuC,SAAS/hC;;;QAItBzM,GAAGutC,eAAeA;;ICtYtBvtC,GAAG64B,iBAAiB,SAAS1yB;QACzB;QAEA,SAASsoC,MAAMC;YACX,OAAOA,GAAGllC,QAAQF,kBAAkB;;QAGxC,SAASqlC,SAASD;YACd,OAAOA,GAAGllC,QAAQF,kBAAkB;;QAGxC,SAASslC;YACL,OAAO,IAAIlB,QAAQmB,gBAAgB1qC;;QAGvC,SAAS2qC;YACL,IAAIzqC,SAASwF,SAASC,cAAc;YAEpC,OAAOzF,OAAOkmC,cAAclmC,OAAOkmC,WAAW;;QAMlD,SAASwE,wBAAwBC;YAE7B,IAAIC,eAAeD,aAAatpC,MAAM,MAClC3D,OAAOktC,aAAaA,aAAalpC,SAAS,GAAGL,MAAM,KAAK,IACxDspB,YAAYhvB,GAAG8R,aAAa/P;YAEhCitB,YAAYA,aAAaA,UAAU1lB;YAEnC,QAAQ0lB;cACJ,KAAK;cACL,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;cACL,KAAK;gBACD,OAAO;;;QASnB,SAASkgB,cAAc5T;YACnB,IAAI6T,eAAetlC,SAASC,cAAc,MACtCslC,gBAAgBC,gBAAgBC;YAEpCH,aAAaI,OAAOjU;YAEpB8T,iBAAiBD,aAAaK;YAC9BF,aAAaH,aAAaM;YAC1BJ,iBAAiBF,aAAaO;YAE9B,IAAIN,eAAe9lC,kBAAkBtE,OAAO2qC,SAASH,SAASlmC,eAAe;gBACzE,OAAO;;YAGX,IAAI+lC,eAAe/lC,kBAAkBtE,OAAO2qC,SAASD,SAASpmC,eAAe;gBACzE,OAAO;;YAIX,IAAIgmC,eAAetqC,OAAO2qC,SAASF,SAASzvC,GAAGyN,MAAM;gBACjD,OAAO;;YAGX,OAAO;;QAGX,SAASmiC,yBAAyB5F,KAAKl+B;YACnCk+B,IAAIh+B,SAAS;gBACTg+B,IAAIh+B,SAAS;gBACbg+B,IAAI99B,UAAU;gBACdJ,QAAQG,QAAQ+9B;;YAGpBA,IAAI99B,UAAU;gBACV89B,IAAIh+B,SAAS;gBACbg+B,IAAI99B,UAAU;gBACd/F,IAAI,8BAA8B;gBAClC2F,QAAQK,QAAQ69B,KAAK;;;QAI7B,SAAS6F,gCAAgCxrC,QAAQyH;YAO7CzH,OAAO0oC,kBAAkB;gBACrBjhC,QAAQG,QAAQ5H;;;QAQxB,SAASyrC,kCAAkC3uB,aAAarV;YACpD,IAAIikC,aAAatB,MAAMttB,gBAAgBwtB,SAASxtB;YAEhD,IAAIstB,MAAMttB,cAAc;gBACpByuB,yBAAyBzuB,aAAarV;mBAErC,IAAI6iC,SAASxtB,cAAc;gBAC5B0uB,gCAAgC1uB,aAAarV;mBAE5C;gBACDA,QAAQK,QAAQgV;gBAChBhb,IAAInG,GAAG8H,OAAO,kDAAkDqZ,YAAY3X,UAAU;;YAG1F,OAAOumC;;QAKX,SAASC,KAAKjlC,YAAY8W,WAAWvJ;YACjC,IAAI23B,cAAc,IAAIjwC,GAAG+L,WACrBqc,aAAa,IAAIpoB,GAAGkwC,SAASnlC,YAAY5E,MACzCib,UAAU9I,QAAQ8I,SAElBmX,SAASjgB,QAAQigB,UAAU,OAAO,OAAOjgB,QAAQigB,QACjD4X,sBAAsB;gBAClBtuB,UAAU3V,UAAU;gBACpB2V,UAAU7V,SAAS;gBACnB7F,IAAI,oDAAoD;gBACxD8pC,YAAY9jC,QAAQ0V,WAAW;;YAGvCuG,WAAWgoB,gBAAgBh5B,KACvB,SAAS9S;gBAGL,IAAI+rC;oBACIz+B,OAAO;wBACH,OAAO,IAAI5R,GAAG+L,UAAUE;;mBAGhCqkC,OAAO/X,SAAS,IAAIv4B,GAAGuwC,KAAKxlC,YAAY5E,OAAOkqC,WAC/CG,QAAQ,IAAIxwC,GAAGutC,aAAaxiC,YAAYolC;gBAE5C,IAAIL,kCAAkCjuB,WAAWouB,cAAc;oBAC3DK,KAAK1+B,QAAQwF,KACT,SAASk5B;wBACL,IAAItE,cAAcsE,QAAQA,KAAKG;wBAE/BD,MAAMvC,OAAOpsB;4BACTyU,UAAUlV;4BACViV,WAAWjV;4BACX4qB,aAAaA;4BACb1nC,MAAMA;4BACNsnC,QAAQtzB,QAAQgJ;;uBAIxB,SAASovB;wBACLvqC,IAAInG,GAAG8H,OAAO,kEAAkE4oC;wBAEhFF,MAAMvC,OAAOpsB;4BACTyU,UAAUlV;4BACViV,WAAWjV;4BACX9c,MAAMA;4BACNsnC,QAAQtzB,QAAQgJ;;;;eAOpC;gBACInb,IAAI;gBACJ8pC,YAAY9jC,QAAQ0V,WAAW;;YAIvC,OAAOouB;;QAGX,SAASU,yBAAyBrV,KAAKsV,aAAaZ,MAAM5uB,SAASE;YAC/D,IAAIuvB,UAAU,IAAInD,SACdoD,gBAAgB,IAAI9wC,GAAG+L;YAE3B+jC,kCAAkCe,SAASC;YAE3C,IAAI5B,cAAc5T,MAAM;gBACpBuV,QAAQhC,cAAc;;YAG1BgC,QAAQ/C,MAAMxS;YAEdwV,cAAc15B,KACV,SAAS25B;gBACLjB,kCAAkCc,aAAaZ;gBAE/C,IAAIQ,QAAQ,IAAIxwC,GAAGutC,aAAasD;gBAChCL,MAAMvC,OAAO2C;oBACTta,UAAUlV;oBACViV,WAAWjV;oBACX9c,MAAMyqC,wBAAwBzT;oBAC9BsQ,QAAQtqB;;eAIhB0uB,KAAK7jC;;QAIb,SAAS6kC,+BAA+B1V,KAAK0O,KAAKgG,MAAM5uB;YACpD0uB,kCAAkC9F,KAAKgG;YAKvChwC,GAAGgqC,KAAK1oC;gBACJg1B,UAAUlV,UAAU;gBACpBiV,WAAWjV,UAAU;;YAGzB4oB,IAAI8D,MAAMxS;;QAWd,SAAS2V,YAAY3V,KAAKzZ,WAAWvJ;YACjC,IAAI03B,OAAO,IAAIhwC,GAAG+L,WACd4V,QAAQrJ,QAAQqJ,OAChBP,UAAUO,QAAQrJ,QAAQ8I,UAAU;YAGxC,IAAIO,SAAS8sB,MAAM5sB,YAAY;gBAG3B,IAAIitB,qBAAqB;oBAIrB,IAAII,cAAc5T,SAASsT,sBAAsB;wBAC7CoC,+BAA+B1V,KAAKzZ,WAAWmuB,MAAM5uB;2BAEpD;wBACDuvB,yBAAyBrV,KAAKzZ,WAAWmuB,MAAM5uB;;uBAGlD;oBACD4vB,+BAA+B1V,KAAKzZ,WAAWmuB,MAAM5uB;;mBAIxD,IAAIutB,SAAS9sB,YAAY;gBAC1B8uB,yBAAyBrV,KAAKzZ,WAAWmuB,MAAM5uB;mBAG9C,IAAI0uB,kCAAkCjuB,WAAWmuB,OAAO;gBACzDnuB,UAAUisB,MAAMxS;;YAGpB,OAAO0U;;QAGXhwC,GAAG6B,OAAOxB;YAWNyhB,UAAU,SAASovB,eAAervB,WAAWvJ;gBACzC,IAAItY,GAAGwH,SAAS0pC,gBAAgB;oBAC5B/qC,IAAI;oBACJ,OAAO8qC,YAAYC,eAAervB,WAAWvJ;uBAE5C;oBACDnS,IAAI;oBACJ,OAAO6pC,KAAKkB,eAAervB,WAAWvJ;;;;QAMlDjY,KAAK8wC;QACL9wC,KAAK8wC,SAAS1C,QAAQA;QACtBpuC,KAAK8wC,SAASxC,WAAWA;QACzBtuC,KAAK8wC,SAASjC,gBAAgBA;QAC9B7uC,KAAK8wC,SAASpC,0BAA0BA;;IChT5C/uC,GAAGuwC,OAAO,SAASxlC,YAAY5E;QAC3B;QAGA,IAAIirC,YAAW,OACXC;YACIC;gBACIvvC,MAAM;gBACNsJ,OAAO;;;QAKnB,SAASkmC,kBAAkBC;YACvB,IAAI7uC,SAAS,GACT8uC,MAAM;YAEV,OAAOD,IAAIzrC,SAAS,GAAG;gBACnBpD,UAAUq/B,SAASwP,IAAIjpC,UAAU,GAAG,IAAI,MAAM5G,KAAK8vC,IAAI,GAAGA;gBAC1DD,MAAMA,IAAIjpC,UAAU,GAAGipC,IAAIzrC;gBAC3B0rC,OAAO;;YAGX,OAAO9uC;;QAKX,SAAS+uC,WAAWC,QAAQ7lC;YACxB,IAAI8lC,YAAYD,QACZE,aAAa/lC;YACjB,IAAI8lC,cAAcztC,WAAW;gBACzBytC,YAAY;gBACZC,aAAa,IAAI7xC,GAAG+L;;YAGxB/L,GAAGwL,cAAcT,YAAY6mC,WAAW,GAAGx6B,KAAK,SAASo6B;gBACrD,IAAIh9B,QAAQ,cAAcvQ,KAAKutC,MAC3BM;gBAEJ,IAAIt9B,OAAO;oBACP,IAAIA,MAAM,OAAO,KAAK;wBAClBs9B,gBAAgB9P,SAASwP,IAAItpC,MAAM,GAAG,IAAI;wBAC1CwpC,WAAWE,YAAYE,gBAAgB,GAAGD;2BAEzC;wBACDA,WAAW5lC,QAAQ2lC;;uBAGtB;oBACDC,WAAW1lC,QAAQ;;;YAI3B,OAAO0lC;;QAIX,SAASE;YACL,IAAIjmC,UAAU,IAAI9L,GAAG+L;YAErB/L,GAAGwL,cAAcT,YAAY,GAAG,GAAGqM,KAAK,SAASo6B;gBAC7C,IAAIA,IAAI7rC,QAAQ,YAAY,GAAG;oBAC3BmG,QAAQK,QAAQ;uBAEf;oBACDulC,aAAat6B,KAAK,SAASu6B;wBACvB7lC,QAAQG,QAAQ0lC;uBAEpB,SAAStnC;wBACLyB,QAAQK,QAAQ9B;;;;YAK5B,OAAOyB;;QAIX,SAASkmC,eAAeC;YACpB,IAAInmC,UAAU,IAAI9L,GAAG+L;YAErB/L,GAAGwL,cAAcT,YAAYknC,YAAY,IAAI,GAAG76B,KAAK,SAASo6B;gBAC1D1lC,QAAQG,QAAQulC,QAAQ;;YAG5B,OAAO1lC;;QAIX,SAASomC,iBAAiBD,WAAWE;YACjC,IAAIrmC,UAAU,IAAI9L,GAAG+L;YAErB/L,GAAGwL,cAAcT,YAAYknC,YAAY,IAAI,GAAG76B,KAAK,SAASo6B;gBAC1D,IAAIW,cAAc;oBACd,OAAOrmC,QAAQG,QAAQslC,kBAAkBC;uBAExC;oBACD1lC,QAAQG,QAAQ+1B,SAASwP,KAAK;;;YAItC,OAAO1lC;;QAIX,SAASsmC,OAAOH,WAAWI;YACvB,IAAIV,SAASM,YAAY,IACrB5mC,QAAQgnC,aAAa;YAEzB,OAAOryC,GAAGwL,cAAcT,YAAY4mC,QAAQtmC;;QAIhD,SAASinC,cAAcC;YACnB,IAAI33B,cACA+2B,SAAS;YAEb,OAAOA,SAAS,MAAMY,OAAOxsC,QAAQ;gBACjC6U,QAAQ1X,KAAKqvC,OAAOrqC,MAAMypC,QAAQA,SAAS;gBAC3CA,UAAU;;YAGd,OAAO/2B;;QAIX,SAAS43B,aAAaL,cAAcE;YAChC,IAAII,iBAAiB,IACjBC,aAAa1yC,GAAG6B,WAAWuvC,UAC3BuB;YAEJ3yC,GAAG+C,KAAKsvC,YAAY,SAASrvC,KAAKi2B;gBAC9B,IAAI2Z,QAAQ3Z,MAAM/wB,MAAM,GAAG,IACvB2S,KAAKs3B,eAAeZ,kBAAkBqB,SAAS5Q,SAAS4Q,OAAO,KAC/DC,gBAAgBH,WAAW/sC,QAAQkV,KACnCi4B,WAAWtpC,SAASupC;gBAExB,IAAIF,iBAAiB,GAAG;oBACpBrpC,UAAU6nC,SAASx2B,IAAI9Y;oBACvBgxC,eAAe1B,SAASx2B,IAAIxP;oBAC5BynC,YAAY7Z,MAAM/wB,MAAMuqC,gBAAgBA,iBAAkBM,eAAe;oBACzEJ,KAAKnpC,WAAW2oC,eAAeZ,kBAAkBuB,aAAa9Q,SAAS8Q,WAAW;oBAElFJ,WAAWn2B,OAAOs2B,eAAe;;gBAGrC,IAAIH,WAAW3sC,WAAW,GAAG;oBACzB,OAAO;;;YAIf,OAAO4sC;;QAGX3yC,GAAG6B,OAAOxB;YAONuR,OAAO;gBACH,IAAIohC,SAAS,IAAIhzC,GAAG+L,WAChBknC,iBAAiB,SAAS7sC;oBACtBD,IAAInG,GAAG8H,OAAO,mCAAmC1B;oBACjD4sC,OAAO7mC,QAAQ/F;;gBAGvB2rC,gBAAgB36B,KAAK,SAAS87B;oBAC1B/sC,IAAInG,GAAG8H,OAAO,oDAAoDiD,WAAWhJ,SAASoC,YAAY,SAAS4G,WAAWhJ;oBAEtHiwC,eAAekB,YAAY97B,KAAK,SAAS+6B;wBAErChsC,IAAInG,GAAG8H,OAAO,gCAAgCqqC,eAAe,WAAW;wBAExED,iBAAiBgB,YAAYf,cAAc/6B,KAAK,SAAS+7B;4BAErDhtC,IAAInG,GAAG8H,OAAO,mCAAmCqrC;4BAEjDf,OAAOc,YAAYC,eAAe/7B,KAAK,SAASm7B;gCAC5C,IAAIF,aAAaC,cAAcC,SAC3Ba,YAAYZ,aAAaL,cAAcE;gCAE3ClsC,IAAI;gCAEJ6sC,OAAO/mC,QAAQmnC;+BAChBH;2BACJA;uBACJA;mBACJA;gBAEH,OAAOD;;;QAKf3yC,KAAK8wC;QACL9wC,KAAK8wC,SAASI,oBAAoBA;;IC7MtCvxC,GAAGkwC,WAAW,SAASnlC,YAAY5E;QAC/B;QAEA,SAASktC,eAAeC,YAAYC;YAChC,IAAIC,eAAe,OACfC,uBAAuBrjC,OAAOkjC;YAElCtzC,GAAG+C,KAAK0wC,mBAAmB,SAASzwC,KAAK0wC;gBACrC,IAAIH,kBAAkB5tC,QAAQ+tC,0BAA0B,GAAG;oBACvDF,eAAe;oBACf,OAAO;;;YAIf,OAAOA;;QAGXxzC,GAAG6B,OAAOxB;YASN+vC,eAAe;gBACX,IAAIh4B,OAAO/X,MACP+nB,aAAa,IAAIpoB,GAAG+L,WACpB4nC,cAAc,OACd5xC,OAAOgJ,WAAWhJ,SAASoC,YAAY,SAAS4G,WAAWhJ;gBAE/DoE,IAAInG,GAAG8H,OAAO,iEAAiE/F;gBAE/EoE,IAAI;gBAEJ,IAAI9F,KAAKuzC,qBAAqB;oBAC1BztC,IAAI;oBAEJnG,GAAGwL,cAAcT,YAAY,GAAG,GAAGqM,KAAK,SAASo6B;wBAC7CxxC,GAAG+C,KAAKqV,KAAKy7B,wBAAwB,SAASvvC,MAAM+G;4BAChD,IAAIgoC,eAAehoC,OAAOmmC,MAAM;gCAG5B,IAAIltC,SAAS,gBAAgBtE,GAAGkT,kBAAkByD,cAAc;oCAC5Dg9B,cAAc;oCACdvrB,WAAWnc,QAAQ3H;;gCAGvB,OAAO;;;wBAIf6B,IAAInG,GAAG8H,OAAO,kDAAkD/F,MAAM4xC,cAAc,KAAK;wBAEzF,KAAKA,aAAa;4BACdvrB,WAAWjc;;uBAGnB;wBACIhG,IAAI,iCAAiCpE,OAAO;wBAC5CqmB,WAAWjc;;uBAGd;oBACDic,WAAWjc;;gBAGf,OAAOic;;YAWXwrB,mBAAmB;gBACf,IAAIE,WAAW/oC,WAAWxK,MAEtBwzC,oBAAoB/zC,GAAG2F,QAAQc,OAAOo5B,KAAKx/B,KAAKwzC,yBAAyBC,aAAa,GACtFH,cAAc,OACd5xC,OAAOgJ,WAAWhJ,SAASoC,YAAY,SAAS4G,WAAWhJ;gBAE/D,IAAIgyC,mBAAmB;oBACnB,IAAID,aAAa,cAAc;wBAC3BH,cAAc3zC,GAAGkT,kBAAkByD;2BAElC;wBACDg9B,cAAc;;;iBAIrBA,eAAextC,IAAIpE,OAAO;gBAE3B,OAAO4xC;;;;IAKnB3zC,GAAGkwC,SAASxpC,UAAUmtC;QAClBG,cAAc;QACdC,aAAa;QACbC,aAAa;QACbC,aAAa;QACbC,gBAAe,YAAY;;ICpG/Bp0C,GAAGq1B,kBAAkB,SAAS5pB,MAAMtF;QAChC;QAMA,SAASkuC,iBAAiBC;YACtB,IAAIC,aAAa;YAEjBv0C,GAAG+C,KAAKuxC,QAAQ,SAASE,OAAOztC;gBAC5B,IAAIA,QAAQ,GAAG;oBACXwtC,aAAa;oBACb,OAAO;;;YAIf,OAAOA;;QAQX,SAASE;YACL,IAAIC,oBAAoB,IAAI10C,GAAG+L;YAE/B,IAAI/L,GAAGkwC,SAASzkC,MAAMtF,KAAKiqC,gBAAgBh5B,KAAK;gBAC5C,IAAIme,QAAQ,IAAImY,SACZpS,MAAMt2B,OAAO2oC,OAAO3oC,OAAO2oC,IAAIC,kBAAkB5oC,OAAO2oC,MAClD3oC,OAAO6oC,aAAa7oC,OAAO6oC,UAAUD,kBAAkB5oC,OAAO6oC,YAC9D;gBAEV,IAAIvS,KAAK;oBACL/F,MAAMrpB,UAAU;wBACZ/F,IAAI,6DAA6D;wBACjEuuC,kBAAkBvoC;;oBAGtBopB,MAAMvpB,SAAS;wBACX0oC,kBAAkBzoC;4BACdq+B,OAAOjqC,KAAKiqC;4BACZ5wB,QAAQrZ,KAAKqZ;;;oBAIrB6b,MAAMuY,MAAMxS,IAAIsS,gBAAgBniC;uBAE/B;oBACDtF,IAAI,gEAAgE;oBACpEuuC,kBAAkBvoC;;eAEvBuoC,kBAAkBvoC;YAErB,OAAOuoC;;QASX,SAASC,gBAAgBL,QAAQM;YAC7B,IAAIC;YAEJ70C,GAAG+C,KAAKuxC,QAAQ,SAASQ,WAAWC;gBAChC,IAAIA,aAAa,GAAG;oBAChB,IAAIC,eAAe,0BAA0B/wC,KAAK6wC,YAC9CG,oBAAoBD,aAAa,GAAGjlC,OAAO,GAAGzG,gBAAgB0rC,aAAa,GAAG9sC,MAAM,IACpFgtC,cAAcN,WAAWK;oBAG7B,QAAQD,aAAa;sBACjB,KAAK;wBACD,IAAIE,cAAcH,YAAY;4BAC1BF,eAAeC;4BACf,OAAO;;wBAEX;;sBACJ,KAAK;wBACD,IAAII,cAAcH,YAAY;4BAC1BF,eAAeC;4BACf,OAAO;;wBAEX;;;;YAKhB,OAAOD;;QAWXx0C,KAAKi1B,WAAW,SAASgf;YACrB,IAAIa,mBAAmB,IAAIn1C,GAAG+L;YAE9B5F,IAAI;YAEJ,IAAIkuC,iBAAiBC,SAAS;gBAC1BG,iBAAiBr9B,KAAK,SAASw9B;oBAC3B,IAAIC,eAAeF,gBAAgBL,QAAQM;oBAE3C,IAAIC,cAAc;wBACdM,iBAAiBhpC,QAAQ0oC;2BAExB;wBACDM,iBAAiBlpC;;mBAEtBkpC,iBAAiBlpC;mBAEnB;gBACDkpC,iBAAiBlpC;;YAGrB,OAAOkpC;;;IC7Hfn1C,GAAGs0B,UAAU,SAAS5Y;QAClB;QAEA,IAAIpD;YACA8F,UAAU;YACVD;YACA+I;YACAG;YACAmN,eAAe,SAASzO;YACxB5f,KAAK,SAASC,SAASC;;QAG3BrG,GAAG6B,OAAOyW,SAASoD,MAAM;QAEzB,SAAS05B,oBAAoBhkB;YACzB,IAAIpxB,GAAG8G,QAAQsqB,WAAW;gBACtB,OAAO;;YAGX9Y,QAAQnS,IAAI,qCAAqC;;QAGrD,SAASkvC,gBAAgBC,WAAWrpC,SAASwb,UAAU3b;YACnD,IAAIypC,mBAAmB;YAEvBtpC,UAAUA,WAAWmpC,oBAAoBE;YAEzC,IAAIrpC,SAAS;gBACTjM,GAAG+C,KAAKuyC,WAAW,SAAStyC,KAAK86B;oBAE7B,IAAIA,SAAS9iB,QAAQ,MAAM;wBACvBu6B,mBAAmB;wBACnBj9B,QAAQnS,IAAInG,GAAG8H,OAAO,qEAAqE9E,MAAM;2BAEhG,IAAI86B,SAAS/7B,QAAQ,MAAM;wBAC5BwzC,mBAAmB;wBACnBj9B,QAAQnS,IAAInG,GAAG8H,OAAO,qEAAqE9E,MAAM;2BAEhG;wBACD;4BACIsV,QAAQkc,cAAcsJ;4BACtB,OAAO;0BAEX,OAAO0X;4BACHD,mBAAmB;4BACnBj9B,QAAQnS,IAAIqvC,IAAIpvC,SAAS;;;oBAIjC,OAAO;;;YAIf0F,QAAQG,YAAYspC,mBAAmB,YAAY,WAAWD,WAAW7tB;;QAK7EpnB,KAAKo0B,UAAU;YAEX,IAAIghB,gBAAgB,IAAIz1C,GAAG+L,WACvB2pC,0BAA0B,SAAStkB,UAAUnlB,SAASwb;gBAClD4tB,gBAAgBjkB,UAAUnlB,SAASwb,UAAUguB;eAEjDE,mBAAmB31C,GAAG6B,WAAWyW,UACjCsxB,YAAY,IAAI5pC,GAAG41C,qBACf51C,GAAG6B,OAAO8zC;gBAAmB1qB,YAAYyqB;;YAGjD9L,UAAUiM;YAEV,OAAOJ;;;ICrEfz1C,GAAG41C,uBAAuB,SAASl6B;QAC/B;QAEA,IAAIkuB,WACAtxB;YACI8F,UAAU;YACV8I;YACA/I;YACAkJ;gBACIqI,UAAU;gBACVyI,iBAAiB;;YAErBlN,YAAY,SAASmG,UAAUnlB,SAASwb;YACxCthB,KAAK,SAAS4B,KAAK1B;;QAG3BrG,GAAG6B,OAAOyW,SAASoD;QAEnB,SAASuP,WAAWpQ,IAAI4M,UAAUC;YAC9B,IAAI0J,WAAW;YAGf,IAAI3J,SAASquB,gBAAgB,MAAM;gBAC/B;oBACI1kB,WAAWpxB,GAAGyR,UAAUgW,SAASquB;kBAErC,OAAON;oBACHl9B,QAAQnS,IAAI,uCAAuCqvC,IAAIpvC,SAAS;oBAChEshB,UAAU;;;YAIlBpP,QAAQ2S,WAAWmG,WAAW1J,SAASD;;QAG3CmiB,YAAY5pC,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGk5B;YAC/BI,cAAc;YACdC,gBAAe;YACf3S,QAAQ;YACRQ;gBACI9E,KAAK;oBACD,OAAOhK,QAAQ8F;;;YAGvB8I,eAAe5O,QAAQ4O;YACvB/gB,KAAKmS,QAAQnS;YACb8kB,YAAYA;YACZ5D,MAAM/O,QAAQ+O;;QAGlBrnB,GAAG6B,OAAOxB;YACNw1C,aAAa;gBACT,IAAI13B,SAASne,GAAG6B,WAAWyW,QAAQ6F;gBAEnC7F,QAAQnS,IAAI;gBAEZyjC,UAAUjN,cAAc,kBACnBK,WAAW7e,QACXmf,kBACAtB;;;;ICzDjBh8B,GAAGukB,SAAS,SAAS7I,MAAMvV;QACvB;QAEA,IAAIiS,OAAO/X,MACPihB,uBAAuB5F,KAAK2c,eAC5B0d,kBAAkBr6B,KAAK4c,cACvBC,SAAS7c,KAAK6c,QACdC,cAAc9c,KAAK8c,aACnBC,iBAAiB/c,KAAK+c,iBAAiB,KACvCud,oBAAoBt6B,KAAKgd,aACzBC,cAAcjd,KAAKid,aACnBC,QAAQv4B,KAAK41C,gBAAgBv6B,KAAKkd;QAGtC54B,GAAG6B,OAAOxB;YAGNogB,SAASzgB,GAAGkT,kBAAkBwD,WAAWkiB,MAAM7yB,SAAS;YAExDmwC,gBAAgB,SAASC,kBAAkBC,kBAAkBC;gBACzD,IAAIj+B,OAAO/X,MACPi2C,cACAC,eAAeF,uBAAuB5qC,OAAO4qC,uBAAuB5qC,OAAO4qC,wBAC3EjuB,aAAa,IAAIpoB,GAAGkwC,SAASqG,cAAcpwC;gBAG/C,IAAIiiB,WAAWwrB,qBAAqB;oBAEhC5zC,GAAG+C,KAAK61B,OAAO,SAAS51B,KAAKwzC;wBACzB,IAAIC,aAAar+B,KAAKs+B;4BAClBle,aAAaA;4BACbme,eAAeH,WAAWj2C;4BAC1Bq2C,SAASL,aAAah2C;;wBAG1B+1C,QAAQpzC;4BACJ8X,MAAMhb,GAAGoN;4BACTrL,MAAMqW,KAAKy+B,SAAST;gCAChBr0C,MAAMy0C,WAAWz0C;gCACjBxB,MAAMk2C;gCACNG,SAASL,aAAah2C;;4BAE1BkL,MAAM,IAAIzL,GAAG8X,UAAUy+B,cACvBv2C,GAAGgQ,KAAKoI,KAAK0+B,sBAAsB1+B;gCAC/BkJ,sBAAsBA;gCACtBF,SAASo1B,WAAWp1B;gCACpBmX,QAAQA;gCACRh4B,MAAMk2C;gCACNlyC,SAASk0B;gCACTse,YAAYf;gCACZrd,aAAaA;gCACbxyB,KAAKA;;;;oBAKjBmwC,QAAQpzC;wBACJ8X,MAAMm7B;wBACNp0C,MAAMq0C;wBACNv6B,MAAM06B,aAAa16B;wBACnBpQ,MAAMsqC,kBAAkBQ,eAAe;;uBAG1C;oBACDD,QAAQpzC;wBACJ8X,MAAMm7B;wBACNp0C,MAAMq0C;wBACNv6B,MAAM06B,aAAa16B;wBACnBpQ,MAAM8qC;;;gBAId,OAAOD;;YAGXvd,eAAe,SAASnZ,MAAM7d,MAAMiZ,MAAMa,MAAMiT,UAAUhT,SAASiL,eAAeiwB;gBAC9E,IAAI5+B,OAAO/X,MACPyY,WAAW8G,KAAKyG,cAAezG,KAAKnU,QAAQmU,KAAKnU,KAAK4a,YACtD4wB,gBACAC,aAAa,MACbtoB,mBAAmBooB,IAAIpoB,kBACvBrO,aAAay2B,IAAIz2B,YACjB4G,cAAc6vB,IAAI7vB,aAClBpL,eAAe/b,GAAGoN;gBAEtBpN,GAAG+C,KAAKqV,KAAK89B,eAAel7B,MAAMjZ,MAAM6d,OAAO,SAAS5c,KAAKm0C;oBACzD,IAAIC,WAAWD,OAAOt7B,MAClBhB;oBAEJ,IAAIs8B,OAAO1rC,gBAAgBzL,GAAG8X,WAAW;wBACrCs/B,YAAY;;oBAGhBv8B,KAAK0F,WAAW9E;wBACZT,MAAMm8B,OAAOn8B;wBACbjZ,MAAMo1C,OAAOp1C;wBACb8Z,MAAMu7B;wBACNt7B,SAASA;wBACTC,cAAcA;;oBAGlB,IAAIo7B,OAAO1rC,gBAAgBzL,GAAG8X,WAAW;wBACrCm/B,UAAU/zC,KAAK2X;2BAEd;wBACDq8B,aAAar8B;;oBAGjB,IAAIs8B,OAAO1rC,MAAM;wBACbmjB,iBAAiB/T,IAAIs8B,OAAO1rC;wBAC5BqjB,SAAS5rB;4BAAM2X,IAAIA;4BAAI+E,MAAMu3B,OAAO1rC;;2BAEnC;wBACD8U,WAAWpE,UAAUtB,IAAI7a,GAAGkb,OAAOmC;;;gBAO3C,IAAI65B,eAAe,MAAM;oBACrBl3C,GAAG+C,KAAKk0C,WAAW,SAASj0C,KAAKq0C;wBAC7B,IAAIl5B;4BACAm5B,cAAc/2B,WAAWtE;gCAAUpB,IAAIq8B;+BAAal8B;4BACpDu8B,cAAch3B,WAAWtE;gCAAUpB,IAAIq8B;+BAAar7B;;wBAKxDsC,OAAO4I,iBAAiBxG,WAAWtE;4BAAUpB,IAAIw8B;2BAAWr8B;wBAE5DuF,WAAWxD,YAAYs6B,UAAUH;wBACjC/vB,YAAY+B,YAAYmuB,UAAUl5B;;oBAKtC,IAAI84B,UAAUlxC,QAAQ;yBACjB;4BACG,IAAIyxC;4BACJA,MAAMzwB,iBAAiBxG,WAAWtE;gCAAUpB,IAAIq8B;+BAAal8B;4BAC7DmM,YAAY+B,YAAYguB,YAAYM;;;;;;;IAQ5Dx3C,GAAG6B,OAAO7B,GAAGukB,OAAO7d;QAChB2d,YAAY,SAASxJ,IAAIyJ,OAAO0yB;YAC5B;YAEA,KAAKh3C,GAAGkT,kBAAkBwD,SAAS;gBAC/B,MAAM,IAAI1W,GAAGwB,MAAM;;YAGvB,IAAIi2C,gBAAgB,IAAIz3C,GAAG+L,WACvB5F,MAAM6wC,IAAI7wC,KACVyZ,OAAOo3B,IAAIp1B,QAAQ/G,KACnB0F,aAAay2B,IAAIz2B,WAAWtE;gBAAUpB,IAAIA;gBAC1C9Y,OAAOwe,cAAcA,WAAWxe,MAChCiZ,OAAOuF,cAAcA,WAAWvF,MAChC08B;gBACIrf,eAAe/T,MAAM+T;gBACrBC,cAAc;gBACdC,QAAQjU,MAAMiU;gBACdC,aAAalU,MAAM/jB,QAAQ;gBAC3Bk4B,gBAAgBnU,MAAM/f;gBACtByxC,mBAAmB;gBACnBpd;oBAAS72B,MAAM;oBAAIqf,SAASkD,MAAMlD;;eAEtCu2B,SAAS,IAAI33C,GAAGukB,OAAOmzB,gBAAgBvxC;YAE3C,KAAKnG,GAAGukB,WAAWvkB,GAAGkT,kBAAkBkD,kBAAkBwJ,MAAM;gBAC5D63B,cAActrC;gBAEdhG,IAAI,mDAAmD0U,KAAK,QACxD,qFAAqF;mBAExF;gBACA7a,GAAGgQ,KAAK;oBAEL,IAAImnC,SAASQ,OAAOzB,eAAel7B,MAAMjZ,MAAM6d,MAAM;oBAErD,IAAIu3B,UAAUA,OAAO1rC,gBAAgBzL,GAAG8X,WAAW;wBAC/Cq/B,OAAO1rC,KAAKwM,SAASb,KAAKqgC,cAAcxrC,SAASwrC,cAActrC;2BAE9D;wBACDhG,IAAI0U,KAAK,6BAA6B;wBACtC48B,cAActrC;;mBAEnB9L;;YAGP,OAAOo3C;;QAKXf,sBAAsB,SAASh7B;YAC3B;YAEA,IAAIi7B,gBAAgBj7B,KAAKi7B,eACrBne,cAAc9c,KAAK8c,aACnBof,gBAAgBl8B,KAAKk7B;YAIzB,KAAKpe,gBAAgBme,eAAe;gBAChC,IAAIiB,kBAAkB,cAAc;oBAChC,OAAO;;gBAEX,OAAOA;;YAIX,KAAKjB,eAAe;gBAChB,OAAOne;;YAIX,IAAIx4B,GAAG2F,QAAQc,OAAOo5B,KAAK7/B,GAAGkwC,SAASxpC,UAAUmtC,yBAAyB8C,kBAAkB,GAAG;gBAC3F,IAAIA,kBAAkB,cAAc;oBAChC,OAAO32C,GAAGkT,kBAAkByD,eAAeggC,gBAAgBne;;gBAG/D,OAAOme;;YAGX,OAAOne;;QAIXqe,UAAU,SAASj7B,cAAci8B;YAC7B;YAEA,IAAIC,aAAal8B,aAAa3J,YAAY,MACtC8lC,cAAcF,wBAAwBt3C,QAAQ,aAC9Cq3C,gBAAgBC,wBAAwBjB,SACxCoB,aAAa,IACbC,YAAYj4C,GAAG8R,aAAa8J,eAC5Bs8B,gBAAgB;YAEpB,IAAIL,wBAAwB91C,QAAQ81C,wBAAwB91C,KAAK8F,OAAO9B,QAAQ;gBAC5EmyC,gBAAgB,OAAOL,wBAAwB91C,OAAO;;YAG1D,IAAI+1C,cAAc,GAAG;gBACjBE,aAAap8B,aAAa1J,OAAO,GAAG4lC;gBAEpC,IAAIF,kBAAkBG,aAAa;oBAC/BE,YAAYF,YAAYryC,MAAM,KAAK;;gBAGvCsyC,cAAcE,gBAAgB,MAAMD;mBAEnC;gBACDD,aAAap8B,eAAes8B;;YAGhC,OAAOF;;QAIX/B,iBAAiB,SAASrd;YACtB;YAEAA,QAAQ54B,GAAG6B,WAAW+2B;YAEtB,OAAOA,MAAMuf,KAAK,SAASC,GAAGC;gBAC1B,IAAID,EAAEh3B,UAAUi3B,EAAEj3B,SAAS;oBACvB,OAAO;;gBAEX,IAAIg3B,EAAEh3B,UAAUi3B,EAAEj3B,SAAS;oBACvB,QAAQ;;gBAEZ,OAAO;;;QAIf01B,sBAAsB,SAASp7B,MAAM48B;YACjC;YAEA,IAAIlgC,OAAO/X,MACPihB,uBAAuB5F,KAAK4F,sBAC5Bnb,MAAMuV,KAAKvV,KACXib,UAAU1F,KAAK0F,SACfmX,SAAS7c,KAAK6c,QACdh4B,OAAOmb,KAAKnb,MACZgE,UAAUmX,KAAKnX,SACfwyC,aAAar7B,KAAKq7B,YAClBpe,cAAcjd,KAAKid,eAAe2f,WAAW/3C,SAAS,gBAAgBA,SAAS,cAC/Ek3C,gBAAgB,IAAIz3C,GAAG+L,WACvBwsC,iBAAiB,IAAIv4C,GAAG64B,eAAe1yB,MACvC9B,SAASwF,SAASC,cAAc;YAEpC3D,IAAI,+CAA+CmyC,WAAWv2C;YAE9Dw2C,eAAez2B,SAASw2B,YAAYj0C;gBAAS+c,SAASA;gBAASmX,QAAQA;gBAAQjX,sBAAsBA;eAAuBlK,KAAK;gBAC7H,IAAIohC,qBAAqBn0C,OAAOI,UAAUlE,MAAMgE,UAC5Ck0C,gBAAgB;oBACZtyC,IAAI,2CAA2CmyC,WAAWv2C;oBAC1D,IAAI0J,OAAOzL,GAAGwE,cAAcg0C;oBAC5Bf,cAAcxrC,QAAQR;;gBAG9B,IAAIktB,aAAa;oBACbvgB,KAAKsgC,kBAAkBJ,YAAYE,oBAAoBryC,KAAKiR,KAAK,SAASuhC;wBACtEH,qBAAqBG;wBACrBF;uBAEJ;wBACItyC,IAAI,yFAAyF;wBAC7FsyC;;uBAGH;oBACDA;;eAEL;gBACCtyC,IAAI,mDAAmDmyC,WAAWv2C,MAAM;gBACxE01C,cAActrC,QAAQ4qC;;YAG1B,OAAOU;;QAIXiB,mBAAmB,SAASE,eAAeJ,oBAAoBryC;YAC3D;YAEA,IAAI0yC,SAAS,IAAIhtC,cACbitC,kBAAkB,IAAI94C,GAAG+L,WACzBgtC,uBAAuB;YAE3BF,OAAO7sC,SAAS;gBACZ+sC,uBAAuBF,OAAOl2C;gBAC9Bm2C,gBAAgB7sC,QAAQjM,GAAGg5C,aAAalM,QAAQiM,sBAAsBP;;YAG1EK,OAAO3sC,UAAU;gBACb/F,IAAI,qBAAqByyC,cAAc72C,OAAO,4DAA4D;gBAC1G+2C,gBAAgB3sC;;YAGpB0sC,OAAOI,cAAcL;YAErB,OAAOE;;QAGXI,gBAAgB,SAASx0C;YACrB;YAEA,IAAIE,YAAYa,YAAYd,aAAaa;YAGzC,IAAId,QAAQgB,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cf,aAAagB,KAAKlB,QAAQgB,MAAM,KAAK;mBAEpC;gBACDd,aAAaiB,UAAUnB,QAAQgB,MAAM,KAAK;;YAI9CD,aAAaf,QAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBf,cAAc,IAAImB,YAAYlB,WAAWmB;YACzCP,WAAW,IAAIQ,WAAWrB;YAC1B3E,GAAG+C,KAAK6B,YAAY,SAAS5B,KAAKiD;gBAC9BT,SAASxC,OAAOiD,UAAUC,WAAW;;YAGzC,OAAO7F,KAAK84C,YAAYx0C,aAAac;;QAGzC0zC,aAAa,SAASr0C,MAAMR;YACxB;YAEA,IAAIS,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;YAErC,IAAIK,aAAa;gBACbA,YAAYC,OAAOP;gBACnB,OAAOM,YAAYE,QAAQhB;mBAE1B;gBACD,OAAO,IAAIiB,OAAMT;oBAAQvE,MAAM+D;;;;;IChZ3CtE,GAAGg5C,eAAe;QAGjB,IAAIA;QAEDA,aAAaI,UAAU,qBACF,qBACA,qBACA,qBACA;QAErBJ,aAAaK,WAAW,SAASzvC;YAE7B,IAAI0vC,SAAS,IACTC,MAAMC,MAAMC,OAAO,IACnBC,MAAMC,MAAMC,MAAMC,OAAO,IACzB/oC,IAAI;YAER,GAAG;gBACCyoC,OAAO3vC,MAAMkH;gBACb0oC,OAAO5vC,MAAMkH;gBACb2oC,OAAO7vC,MAAMkH;gBAEb4oC,OAAOH,QAAQ;gBACfI,QAASJ,OAAO,MAAM,IAAMC,QAAQ;gBACpCI,QAASJ,OAAO,OAAO,IAAMC,QAAQ;gBACrCI,OAAOJ,OAAO;gBAEd,IAAIK,MAAMN,OAAO;oBACdI,OAAOC,OAAO;uBACV,IAAIC,MAAML,OAAO;oBACrBI,OAAO;;gBAGVP,SAASA,SACNj5C,KAAK+4C,QAAQrpC,OAAO2pC,QACpBr5C,KAAK+4C,QAAQrpC,OAAO4pC,QACpBt5C,KAAK+4C,QAAQrpC,OAAO6pC,QACpBv5C,KAAK+4C,QAAQrpC,OAAO8pC;gBACvBN,OAAOC,OAAOC,OAAO;gBACrBC,OAAOC,OAAOC,OAAOC,OAAO;qBACvB/oC,IAAIlH,MAAM7D;YAEnB,OAAOuzC;;QAGXN,aAAalM,UAAU,SAASiN,gBAAgBC;YAE5C,IAAIC,uBAAuB;YAE3B,KAAKF,eAAevlC,MAAMylC,uBAC1B;gBACC,OAAOD;;YAGR,IAAIE,WAAW75C,KAAK85C,SAASJ,eAAex3C,QAAQ03C,sBAAsB;YAC1E,IAAIG,WAAW/5C,KAAKg6C,eAAeH;YAEnC,IAAI3kB,QAAQl1B,KAAKi6C,iBAAiBN,mBAAmBI;YAErD,OAAOH,uBAAuB55C,KAAKg5C,SAAS9jB;;QAKhDyjB,aAAasB,mBAAmB,SAASN,mBAAmBI;YAEpD,IAAIG,YAAYl6C,KAAKm6C,aAAaJ,WAC9BK,gBAAgBp6C,KAAKq6C,WAAWV,mBAAmBO,YACnDI,UAAU,IAAI30C,WAAWy0C;YAE7B,OAAOE;;QAIf3B,aAAawB,eAAe,SAASJ;YAE7B,IAAIQ;YACJ,KAAK,IAAIC,IAAI,GAAGA,IAAIT,SAASr0C,QAAQ80C,KACrC;gBACID,MAAMR,SAASS;gBACf,IAAID,IAAI,MAAM,MAAMA,IAAI,MAAM,KAC9B;oBACI,OAAOA;;;YAGf;;QAIR5B,aAAa0B,aAAa,SAASV,mBAAmBO;YAE9C,IAAIO,YAAYd,kBAAkBz3C,QAAQ,2BAA2B,KACjEw4C,MAAM16C,KAAK85C,SAASW,YACpBE,gBAAgBD,IAAIp1C,QAAQ,KAAI,IAChCs1C,MAAMF,IAAI7yC,MAAM,GAAG8yC,gBACnBE,MAAMH,IAAI7yC,MAAM8yC,gBAChBG,QAAQF;YAEZE,QAAQA,MAAM/qC,OAAOmqC;YACrBY,QAAQA,MAAM/qC,OAAO8qC;YACtB,OAAOC;;QAKdnC,aAAaqB,iBAAiB,SAASe;YAEnC,IAAIC,OAAO,GACPjB;YAEJ,OAAO,GACP;gBACI,IAAIgB,cAAcC,SAAS,MAAMD,cAAcC,OAAO,MAAM,KAAI;oBAAC;;gBACjE,IAAID,cAAcC,SAAS,MAAMD,cAAcC,OAAO,MAAM,KAC5D;oBACIA,QAAQ;uBAGZ;oBACI,IAAIt1C,SAASq1C,cAAcC,OAAO,KAAK,MAAMD,cAAcC,OAAO,IAC9DC,WAAWD,OAAOt1C,SAAS,GAC3B60C,MAAMQ,cAAclzC,MAAMmzC,MAAMC;oBACpClB,SAASl3C,KAAK03C;oBACdS,OAAOC;;gBAEX,IAAID,OAAOD,cAAcr1C,QAAO;oBAAC;;;YAGrC,OAAOq0C;;QAKXpB,aAAamB,WAAW,SAASvwC;YAE7B,IAAI0vC,SAAS,IACTC,MAAMC,MAAMC,OAAO,IACnBC,MAAMC,MAAMC,MAAMC,OAAO,IACzB/oC,IAAI,GACJiqC;YAGJ,IAAIQ,aAAa;YACjB,IAAIA,WAAWt3C,KAAK2F,QAAQ;gBACxB,MAAM,IAAIpI,MAAM,8DACZ;;YAERoI,QAAQA,MAAMrH,QAAQ,uBAAuB;YAE7C,GAAG;gBACCm3C,OAAOr5C,KAAK+4C,QAAQzzC,QAAQiE,MAAMmG,OAAOe;gBACzC6oC,OAAOt5C,KAAK+4C,QAAQzzC,QAAQiE,MAAMmG,OAAOe;gBACzC8oC,OAAOv5C,KAAK+4C,QAAQzzC,QAAQiE,MAAMmG,OAAOe;gBACzC+oC,OAAOx5C,KAAK+4C,QAAQzzC,QAAQiE,MAAMmG,OAAOe;gBAEzCyoC,OAAQG,QAAQ,IAAMC,QAAQ;gBAC9BH,QAASG,OAAO,OAAO,IAAMC,QAAQ;gBACrCH,QAASG,OAAO,MAAM,IAAKC;gBAE3BkB,IAAI73C,KAAKq2C;gBAET,IAAIK,QAAQ,IAAI;oBACbmB,IAAI73C,KAAKs2C;;gBAEZ,IAAIK,QAAQ,IAAI;oBACbkB,IAAI73C,KAAKu2C;;gBAGZF,OAAOC,OAAOC,OAAO;gBACrBC,OAAOC,OAAOC,OAAOC,OAAO;qBAEvB/oC,IAAIlH,MAAM7D;YAEnB,OAAOg1C;;QAIX,OAAO/B;;IC7KXh5C,GAAGg5B,gBAAgB,SAASvpB,UAAUmT;QAClC;QAEA,IAAI44B,sBACAC,cAAc,GACdC,YAAY,GAEZC,kBAAkB,GAClBC,iBAAiB,GACjBC,gBAAgB,SAAS/wB,QAAQC;YAC7B,IAAID,WAAW6wB,kBAAkB5wB,UAAU6wB,eAAe;gBACtDnsC,SAASqb,QAAQC;;YAGrB4wB,iBAAiB7wB;YACjB8wB,gBAAgB7wB;WAQpB+wB,mBAAmB,SAAS/pB,QAAQgqB;YAChC,IAAIC,OAAO;YAEXh8C,GAAG+C,KAAKgvB,QAAQ,SAAS/uB,KAAKi5C;gBAC1B,IAAIj8C,GAAG2F,QAAQo2C,WAAWE,aAAa,GAAG;oBACtCD,OAAO;oBACP,OAAO;;;YAIf,OAAOA;WAGX7wB,WAAW,SAAStQ;YAChBqhC,oBAAoBrhC,KAAK,IAAI;mBACtB2gC,gBAAgB3gC;WAG3BmX,gBAAgB,SAASF,YAAYC,QAAQgqB;YACzC,IAAIhqB,OAAOhsB,WAAW,KAAK+1C,iBAAiB/pB,QAAQgqB,YAAY;gBAC5DF,cAAcH,WAAWA;gBACzBr7C,KAAK8Z;;WAIbgiC,QAAQ,SAASthC;YACb,IAAIgB,OAAO+G,QAAQ/H;YAGnB,IAAIgB,OAAO,GAAG;gBACVqgC,oBAAoBrhC,IAAI,GAAGgB;gBAC3B2/B,gBAAgB3gC;oBAAOiQ,QAAQ;oBAAGC,OAAOlP;;;WAYjDqgC,sBAAsB,SAASrhC,IAAIuhC,WAAWC;YAC1C,IAAIC,YAAYd,gBAAgB3gC,MAAM2gC,gBAAgB3gC,IAAIiQ,SAAS,GAC/DyxB,WAAWf,gBAAgB3gC,MAAM2gC,gBAAgB3gC,IAAIkQ,QAAQ;YAEjE,IAAIqxB,eAAe,KAAKC,cAAc,GAAG;gBACrCZ,eAAea;gBACfZ,aAAaa;mBAEZ;gBACD,IAAIH,WAAW;oBACXX,eAAeW,YAAYE;;gBAE/B,IAAID,UAAU;oBACVX,aAAaW,WAAWE;;;YAIhCV,cAAcJ,aAAaC;;QAGnC17C,GAAG6B,OAAOxB;YAEN2xB,eAAeA;YAGfhW,gBAAgB,SAASnB,IAAIwB,WAAWD;gBACpC,IAAIA,cAAcpc,GAAGkb,OAAOqC,YAAYnB,cAAcpc,GAAGkb,OAAOmC,UAAU;oBACtE8N,SAAStQ;uBAER,IAAIuB,cAAcpc,GAAGkb,OAAOS,YAAY;oBACzCwgC,MAAMthC;;;YAKd8X,sBAAsB,SAAS9X,IAAIiQ,QAAQC;gBACvCmxB,oBAAoBrhC,IAAIiQ,QAAQC;gBAChCywB,gBAAgB3gC;oBAAOiQ,QAAQA;oBAAQC,OAAOA;;;YAIlD6J,WAAW,SAAS/Z;gBAChBshC,MAAMthC;;YAGVV,OAAO;gBACHqhC;gBACAC,cAAc;gBACdC,YAAY;;;;ICzHxB17C,GAAG6nB,eAAe,SAAS1P;QACvB;QAEA,IAAIG,SAASkkC;QAEblkC;YACIwP,eAAe;YACftB;gBACIrgB,KAAK,SAASC,SAASC;gBACvB2hB,eAAe,SAASvc;;;QAIhC,SAASgxC,QAAQn1C;YACb,OAAOA,KAAK/G,QACR+G,KAAK/G,KAAKoF,QAAQ,cAAc;;QAGxC,SAAS+2C;YACLF,qBAAqBx8C,GAAGsY,QAAQwP,eAAexnB,OAAO,SAAS,SAAS8zB;gBACpE,IAAIuoB,gBAAgBvoB,MAAMuoB;gBAE1B,IAAIA,eAAe;oBACf38C,GAAG+C,KAAK45C,cAAcnyC,OAAO,SAASxH,KAAKsE;wBACvC,IAAIm1C,QAAQn1C,OAAO;4BACf,IAAImE,OAAOnE,KAAKs1C;4BAChBtkC,QAAQkO,UAAUwB,cAAcvc;;;;;;QAOpD,SAASoxC;YACL,IAAIL,oBAAoB;gBACpBA;;;QAIRx8C,GAAG6B,OAAOyW,SAASH;QACnBukC;QAEA18C,GAAG6B,OAAOxB;YACN8Z,OAAO;gBACH0iC;;;;ICpCZ78C,GAAGmvB,cAAc,SAAS7W,SAASwkC,aAAa32C;QAC5C;QACA,IAAIiS,OAAQ/X,MACR+3B,kBAAkB9f,QAAQ8f,iBAC1B2kB,SAASzkC,QAAQrY,SACjBqvB,aAAahX,QAAQgX;QAGzBtvB,GAAG6B,OAAOxB;YAINmvB,aAAa;YAIbD,eAAeD;YAGfF,gBAAgB;YAGhBC,uBAAuB;gBAEnB,IAAI0tB,UAAU,MAAM;oBAChB,OAAO;;gBAGX,OAAO3kC,KAAK4kC,UAAUD;;;QAK9B,SAASE,qBAAqBF;YAC1B,IAAIA,OAAO74C,aAAa,WAAW;gBAC/BkU,KAAKoX,cAAcutB,OAAO74C,aAAa;;;QAM/C,SAASg5C,aAAaH,QAAQI;YAC1B,IAAIJ,OAAOK,kBAAkBL,OAAOK,iBAAiB;gBACjDj3C,IAAI,0DAA0D;gBAC9Dg3C;mBAEC;gBACD,OAAO;;;QAKf,SAASE,oBAAoBN;YACzB,IAAII,eAAeJ,OAAOO;YAG1Bt9C,GAAG+8C,QAAQz8C,OAAO,UAAU,SAAS8zB;gBACjCA,QAAQA,SAASpvB,OAAOovB;gBAExB,IAAIA,MAAMnlB,gBAAgB;oBACtBmlB,MAAMnlB;uBAEL;oBACDmlB,MAAMjlB,cAAc;;gBAGxB+tC,aAAaH,QAAQI,iBAAiBL;;YAK1CC,OAAOO,SAAS;gBACZJ,aAAaH,QAAQI,iBAAiBL;;;QAM9C,SAASS,gBAAgBR;YACrB,IAAIA,QAAQ;gBACR,IAAI/8C,GAAGwH,SAASu1C,SAAS;oBACrBA,SAASlzC,SAASg7B,eAAekY;;gBAGrC,IAAIA,QAAQ;oBACR52C,IAAI;oBACJ82C,qBAAqBF;oBACrB3kB,mBAAmBilB,oBAAoBN;;;YAI/C,OAAOA;;QAGXA,SAASQ,gBAAgBR;QACzB18C,KAAK+uB,mBAAmB2tB;;IAG5B/8C,GAAG6B,OAAO7B,GAAGmvB,YAAYzoB;QAGrBs2C,WAAW,SAAS1rC;YAChB;YACA,IAAIf,UACAitC,oBAAoB,SAASj9C;gBACzB,IAAIk9C,oBACA,UACA,SACA,SACA;gBAGJ,OAAOz9C,GAAG2F,QAAQ83C,iBAAiBl9C,KAAK+I,iBAAiB;eAE7Do0C,kBAAkB,SAASn9C;gBACvB,OAAOP,GAAG2F,UAAS,YAAY,WAAUpF,KAAK+I,kBAAkB;eAEpEq0C,cAAc,SAASjP;gBACnB,IAAIgP,gBAAgBhP,GAAGnuC,UAAUmuC,GAAGkP,SAAS;oBACzC,OAAO;;gBAGX,OAAOlP,GAAGr6B,YAAYq6B,GAAGnuC,KAAK+I,kBAAkB;eAEpDu0C,cAAc,SAASC;gBACnB,IAAI/2C,QAAQ;gBAEZ/G,GAAG+C,KAAK/C,GAAG89C,QAAQ16C,YAAY,SAASJ,KAAKK;oBACzC,IAAIA,MAAMmG,QAAQF,kBAAkB,YAAYjG,MAAM06C,UAAU;wBAC5Dh3C,QAAQ1D,MAAM0D;wBACd,OAAO;;;gBAIf,OAAOA;;YAGf/G,GAAG+C,KAAKuO,KAAK0sC,UAAU,SAASh7C,KAAK0rC;gBACjC,KAAK1uC,GAAGiJ,QAAQylC,IAAI,SAASA,GAAGllC,QAAQF,kBAAkB,eACtDk0C,kBAAkB9O,GAAGnuC,UACpBo9C,YAAYjP,KAAK;oBAElBn+B,IAAIm+B,GAAG3sC,QAAQ2sC,GAAG3nC;uBAEjB,IAAI2nC,GAAGllC,QAAQF,kBAAkB,aAAaq0C,YAAYjP,KAAK;oBAChE,IAAI3nC,QAAQ82C,YAAYnP;oBAExB,IAAI3nC,UAAU,MAAM;wBAChBwJ,IAAIm+B,GAAG3sC,QAAQgF;;;;YAK3B,OAAOwJ;;;ICzJfvQ,GAAG2iC,cAAc3iC,GAAG2iC;IACpB3iC,GAAG2iC,YAAYyB,oBAAoB,SAAS9rB,SAASslB;QACjD;QAEA,IAAInP,UAAUpuB,MACVqgB,UAAUkd,MAAMld,SAChByC,UAAUya,MAAMza,SAChBhd,MAAMy3B,MAAMz3B;QAKhB,SAAS83C,qBAAqBpjC,IAAI+pB;YAG9B,IAAIxT,UAAU8sB,KAAKC;YAGnB;gBAEID,MAAMtZ,OAAOa,mBAAmBb,OAAOwZ,cAAcv0C;gBACrDs0C,YAAYD,IAAIhZ,KAAK31B;gBAErBpJ,IAAI;gBACJA,IAAI,iBAAiBg4C;gBAErB,IAAIA,aAAaA,UAAU3pC,MAAM,WAAW;oBACxC2pC,YAAYD,IAAIhZ,KAAK5hC,WAAWA,WAAW+6C;;gBAG/CjtB,WAAW3C,QAAQ2W,mBAAmB+Y;cAE1C,OAAO9zC;gBACHlE,IAAI,0DAA0DkE,MAAMjE,UAAU,KAAK;gBACnFgrB;oBAAYnlB,SAAS;;;YAGzB,OAAOmlB;;QAMX,SAASktB,WAAWzjC,IAAI+pB;YACpB,IAAIzmB,SAAS7F,QAAQ6O,YAAY7E,IAAIzH,KACjC+L,SAAStO,QAAQsO,OAAOtd,kBAAkB,QAAQ,QAAQ,QAC1D8U,WAAW9F,QAAQ8O,cAAc9E,IAAIzH,KACrC9Y,OAAO2e,QAAQ7F;YAEnBsD,OAAO7F,QAAQ2O,YAAY9D,QAAQtI;YACnCsD,OAAO7F,QAAQ2d,iBAAiBl0B;YAEhC,OAAO0sB,QAAQkX;gBACX/e,QAAQA;gBACRxI,UAAUA;gBACVD,QAAQA;gBACRgY,cAAc7d,QAAQ6d;gBACtByP,YAAYhB,OAAO7iC;;;QAI3B1B,KAAKgiC,aAAa,SAASxnB;YACvB,IAAIjR,QAAQ6kB,QAAQ5U,SAASgB,KACzB+pB,SAASnW,QAAQiX,cAAc7qB,KAC/B/O,UAAU,IAAI9L,GAAG+L,WACjBuF;YAEJA,OAAOgtC,WAAWzjC,IAAI+pB;YACtBtzB,KAAKE,YAAY5H;YAEjB6kB,QAAQ8W,iBAAiBX,QAAQ,SAAS2Z;gBACtCp4C,IAAI;gBAEJ,IAAIirB,WAAWmtB,sBAAsBA,sBAAsBN,qBAAqBpjC,IAAI+pB;gBAEpFnW,QAAQ6W,iBAAiBzqB;gBAGzB,KAAKvC,QAAQ+O,KAAKqI,UAAU;oBACxB1vB,GAAG4kC,QAAQxjC;;gBAGf,IAAIgwB,SAASnlB,SAAS;oBAClBH,QAAQG,QAAQmlB;uBAEf;oBACDtlB,QAAQK,QAAQilB;;;YAIxBjrB,IAAI,gCAAgC0U;YACpCvJ,KAAKgsC;YACLt9C,GAAGsR,MAAMlQ;YAET,OAAO0K;;QAGX9L,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGokC;YACnB9rB;gBACImsB,QAAQnsB,QAAQ+O,KAAKqI;gBACrBvF,WAAW7R,QAAQ6R;;YAGvByT;gBACIzS,UAAU7S,QAAQ6S;gBAClBzK,SAASA;gBACTyC,SAASA;gBACThd,KAAKA;;;;IC5GjBnG,GAAG2iC,cAAc3iC,GAAG2iC;IACpB3iC,GAAG2iC,YAAYmD,mBAAmB,SAASpqB,MAAMkiB;QAC7C;QAEA,IAAInP,UAAUpuB,MACVqgB,UAAUkd,MAAMld,SAChBkC,UAAUgb,MAAMhb,SAChBO,UAAUya,MAAMza,SAChBhd,MAAMy3B,MAAMz3B,KACZq4C,YAAY9iC,KAAKwa,kBAAkBxa,KAAKya,cAExCsoB,4BAA4B,SAAS5jC,IAAIsD,QAAQwN;YAC7C,IAAI9P,OAAO+G,QAAQ/H,KACf9Y,OAAO2e,QAAQ7F;YAEnBsD,OAAOzC,KAAK/F,SAAS8hB,WAAWC,aAAa/L,UAAUqc;YACvD7pB,OAAOzC,KAAK/F,SAAS8hB,WAAWE,kBAAkBhM,UAAU3gB;YAC5DmT,OAAOzC,KAAK/F,SAAS8hB,WAAWG,aAAajM,UAAU9P;YACvDsC,OAAOzC,KAAK/F,SAAS8hB,WAAWK,cAAcnM,UAAUsc;YACxD9pB,OAAOzC,KAAK0a,qBAAqBva;YAMjC,IAAI2iC,WAAW;gBACXrgC,OAAOzC,KAAKua,iBAAiBl0B;;WAIrC28C,yBAAyB,IAAI1+C,GAAG2iC,YAAYgc;YACxCt3B,MAAM3L,KAAK2L;YACXjJ,UAAU1C,KAAK/F,SAAS1J,QAAQmS;YAChCjY,KAAKA;YAGTy4C,iCAAiC,SAAS/jC,IAAIlG;YAC1C,IAAI7I,UAAU,IAAI9L,GAAG+L;YAErB4I,IAAIgnB,qBAAqB;gBACrB,IAAIhnB,IAAIwnB,eAAe,GAAG;oBACtB,IAAIx5B,SAASk8C,wBAAwBhkC,IAAIlG;oBAEzC,IAAIhS,OAAOsJ,SAAS;wBAChBH,QAAQG,QAAQtJ,OAAOyuB,UAAUzc;2BAEhC;wBACD7I,QAAQK,QAAQxJ,OAAOyuB,UAAUzc;;;;YAK7C,OAAO7I;WAGXgzC,0BAA0B,SAASjkC;YAC/B,IAAIsD,SAASzC,KAAKyL,YAAY7E,IAAIzH,KAC9B9Y,OAAO2e,QAAQ7F,KACfgB,OAAO+G,QAAQ/H;YAEnBsD,OAAOzC,KAAKuL,YAAY9D,QAAQtI;YAChCsD,OAAOzC,KAAKua,iBAAiBl0B;YAC7Boc,OAAOzC,KAAK0a,qBAAqBva;YACjCsC,OAAOzC,KAAK/F,SAAS8hB,WAAWK,cAAcrJ,QAAQgS,gBAAgB5lB;YAEtE,OAAOsD;WAGX4gC,wBAAwB,SAASpqC,KAAKyc;YAClC,OAAOpxB,GAAG2F,UAAS,KAAK,KAAK,KAAK,KAAK,OAAMgP,IAAIuG,UAAU,MACtDkW,SAASnlB,WACVmlB,SAASjX;WAGjB0kC,0BAA0B,SAAShkC,IAAIlG;YACnC,IAAIyc;YAEJjrB,IAAI,wCAAwC0U;YAC5C1U,IAAI,oBAAoBwO,IAAImhC;YAE5B1kB,WAAW4tB,cAAc,MAAMrqC;YAE/B;gBACI1I,UAAU8yC,sBAAsBpqC,KAAKyc;gBACrCA,UAAUA;;WAKlB4tB,gBAAgB,SAAS90C,QAAQyK;YAC7B,IAAIyc;YAEJ;gBACIjrB,IAAInG,GAAG8H,OAAO,6CAA6C6M,IAAIuG,QAAQvG,IAAImhC;gBAC3E1kB,WAAWpxB,GAAGyR,UAAUkD,IAAImhC;cAEhC,OAAOzrC;gBACHH,UAAU/D,IAAI,uDAAuDkE,MAAMjE,UAAU,KAAK;;YAG9F,OAAOgrB;WAGX6tB,4BAA4B,SAASpkC;YACjC,IAAI/O,UAAU,IAAI9L,GAAG+L;YAErB2yC,uBAAuBQ,SACfrkC,IACA4T,QAAQgZ,WAAW5sB,KACnBikC,wBAAwBjkC,KACxBa,KAAKwL,cAAc5E,IAAIzH,KAE1BzD,KAAK,SAASzC;gBACX7I,QAAQG,QAAQ+yC,cAAc,OAAOrqC,MAAMA;eAC5C,SAASA;gBACR7I,QAAQK,QAAQ6yC,cAAc,OAAOrqC,MAAMA;;YAGnD,OAAO7I;WAGXqzC,8BAA8B,SAAShhC,QAAQxJ,KAAK5J,YAAY8P;YAC5D,IAAI1J,WAAW,IAAInH,YACf4c,SAASlL,KAAKkL,QACdxI,WAAW1C,KAAK0L,cAAc9E,IAAIzH,KAClC9Y,OAAO2e,QAAQ7F,KACfgB,OAAO+G,QAAQ/H;YAEnBsD,OAAOzC,KAAKuL,YAAY9D,QAAQtI;YAChCsD,OAAOzC,KAAKua,iBAAiBl0B;YAE7B,IAAIy8C,WAAW;gBACXrgC,OAAOzC,KAAK0a,qBAAqBva;;YAIrC,KAAKH,KAAKya,cAAc;gBACpB,KAAKqoB,WAAW;oBACZrgC,OAAOzC,KAAKyO,aAAapoB;;gBAE7Bqc,WAAWpe,GAAGsQ,QAAQ6N,QAAQC;;YAGlCzJ,IAAImnB,KAAKlV,QAAQxI,UAAU;YAE3B,IAAI1C,KAAK2L,KAAKqI,YAAYhU,KAAK2L,KAAK8Q,iBAAiB;gBACjDxjB,IAAIC,kBAAkB;;YAG1B,IAAI4pC,WAAW;gBACX,IAAI9iC,KAAKya,cAAc;oBACnBn2B,GAAGkR,aAAaiN,QAAQhN;;gBAG5BA,SAAS9L,OAAOqW,KAAKyO,WAAWpf;gBAChC,OAAOoG;;YAGX,OAAOpG;WAGXq0C,mBAAmB,SAASvkC,IAAIlG;YAC5B,IAAI0qC,eAAe3jC,KAAKwL,cAAc5E,IAAIzH,KACtC9P,aAAa0jB,QAAQ7M,QAAQ/G;YAEjClG,IAAI6nB,iBAAiB,UAAU;YAC/B7nB,IAAI6nB,iBAAiB,oBAAoB;YACzC7nB,IAAI6nB,iBAAiB,iBAAiB;YAEtC,KAAKgiB,WAAW;gBACZ7pC,IAAI6nB,iBAAiB,gBAAgB;gBAErC7nB,IAAI6nB,iBAAiB,eAAezxB,WAAWxK;;YAGnDP,GAAG+C,KAAKs8C,cAAc,SAASt9C,MAAMkB;gBACjC0R,IAAI6nB,iBAAiBz6B,MAAMkB;;;QAIvCjD,GAAG6B,OAAOxB;YACNygC,aAAa,SAASjmB,IAAI6jB,UAAUzG;gBAChC,IAAItM,YAAY8C,QAAQkQ,cAAc9jB,IAAI6jB,WACtC/pB,MAAM8Z,QAAQgZ,WAAW5sB,IAAI6jB,WAC7B7iB,OAAO+G,QAAQ/H,KACf/O,SAASwzC,QAAQnhC;gBAErBrS,UAAU8yC,+BAA+B/jC,IAAIlG;gBAC7C8Z,QAAQqa,yBAAyBjuB,IAAI6jB,UAAU/S,UAAU9P;gBACzDsC,SAASzC,KAAKyL,YAAY7E,IAAIzH;gBAC9B4jC,0BAA0B5jC,IAAIsD,QAAQwN;gBAEtC,IAAIsM,UAAU;oBACV9Z,OAAOzC,KAAKjF,OAAOghB,WAAWQ,YAAY;;gBAG9CqnB,SAASH,4BAA4BhhC,QAAQxJ,KAAKgX,UAAUlgB,MAAMoP;gBAClEukC,iBAAiBvkC,IAAIlG;gBACrBA,IAAIqnB,KAAKsjB;gBAET,OAAOxzC;;YAGXu2B,YAAY,SAASxnB;gBACjB,IAAI9P,aAAa0jB,QAAQ7M,QAAQ/G,KAC7B/O,SAAS6I,KAAKwJ,QAAQmhC;gBAE1B3qC,MAAM8Z,QAAQgZ,WAAW5sB;gBACzB4T,QAAQqa,yBAAyBjuB;gBACjC/O,UAAU8yC,+BAA+B/jC,IAAIlG;gBAC7CwJ,SAASzC,KAAKyL,YAAY7E,IAAIzH;gBAC9BykC,SAASH,4BAA4BhhC,QAAQxJ,KAAK5J,YAAY8P;gBAC9DukC,iBAAiBvkC,IAAIlG;gBACrBA,IAAIqnB,KAAKsjB;gBAET,OAAOxzC;;;QAIf9L,GAAG6B,OAAOxB,MAAM,IAAIL,GAAG8lC;YACnBxtB,SAAStY,GAAG6B;gBAAQ4oB,WAAW;eAAgB/O;YAC/CkiB,OAAO59B,GAAG6B;gBAAQugB,aAAa1G,KAAK0L,cAAc9E;eAAMsb;;QAG5D59B,GAAGwM,SAASnM,MAAM,SAASsM;YACvB;gBACIqyB,gBAAgB,SAASnkB;oBACrB,IAAIa,KAAK/F,SAAS1J,QAAQmS,UAAU;wBAChC,OAAO6gC,0BAA0BpkC;2BAEhC;wBACD,OAAOlO,OAAOqyB,eAAenkB,IAAI7a,GAAGgQ,KAAKgvC,eAAe3+C,MAAM;;;;;;ICvOlFL,GAAG2iC,YAAYgc,6BAA6B,SAASxmC;QACjD;QAEA,IAAIyxB,WACAhjB,SAAS,QACTtO;YACI+O;gBACIsI,UAAU;gBACVD,UAAU;gBACVyI,iBAAiB;;YAErB/Z,UAAU;YACVjY,KAAK,SAAS4B,KAAK1B;WAEvBk5C,eACAC;YACIl9B,KAAK,SAASzH;gBACV,OAAOvC,QAAQ8F;;;QAI3Bpe,GAAG6B,OAAOyW,SAASH;QAEnByxB,YAAY5pC,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGk5B;YAC/BI,cAAc;YACdC,gBAAe3S;YACfA,QAAQA;YACRQ,eAAeo4B;YACf9lB,oCAAoC;YACpCrS,MAAM/O,QAAQ+O;YACdlhB,KAAKmS,QAAQnS;YACb8kB,YAAY,SAASpQ,IAAIlG,KAAK+S;gBAC1B,IAAI5b,UAAUyzC,SAAS1kC;uBAEhB0kC,SAAS1kC;gBAEhB,IAAI6M,SAAS;oBACT5b,QAAQK,QAAQwI;uBAEf;oBACD7I,QAAQG,QAAQ0I;;;;QAK5B3U,GAAG6B,OAAOxB;YACN6+C,UAAU,SAASrkC,IAAIlG,KAAKwJ,QAAQsG;gBAChC,IAAI3Y,UAAU,IAAI9L,GAAG+L;gBAErBuM,QAAQnS,IAAI,4CAA4C0U;gBAExD0kC,SAAS1kC,MAAM/O;gBAEf89B,UAAUjN,cAAc9hB,IACnBmiB,WAAW7e,QACXgf,YAAY1Y,SACZuX,KAAKrnB;gBAEV,OAAO7I;;;;ICjEnB9L,GAAGy/C,cAAc,SAAStnC;QACtB;QAEA,IAAIG,SACAonC,wBAAwB,gBACxBC,yBAAyB,oBACzBC,sBACAC,mBACAxnC,iBAAiB,IAAIrY,GAAGsS;QAE5BgG;YACIwnC;YACAC,oBAAoB;YACpBh2B;gBACIi2B,YAAY;;YAEhBx5B,WAAW,IAAIxmB,GAAGy/C,YAAYj5B;;QAGlCxmB,GAAG6B,OAAOyW,SAASH,GAAG;QAEtB,SAAS8nC,mBAAmBtgC,OAAOugC;YAE/B,IAAIC,eAAel4C,MAAMvB,UAAUwB,MAAMtB,KAAK+Y;YAE9CrH,QAAQkO,UAAU45B,QAAQ,aAAazgC,MAAM5Z,SAAS;YACtDm6C,eAAeG,aAAa;YAC5B/nC,QAAQkO,UAAU85B,+BAA+BH,cAAcD,eAAeK;;QAGlF,SAASC,iBAAiBvnB;YACtB,IAAIwnB,oBAAoB,IAAIzgD,GAAG+L;YAE/B,IAAIktB,MAAMxwB,QAAQ;gBACdwwB,MAAMrZ,KAAK,SAASA;oBAChB,IAAI7d,OAAOk3B,MAAMl3B,MACb2+C,WAAWznB,MAAMynB,UACjBC,wBAAwBD,SAAS/6C,QAAQ5D;oBAG7C2+C,WAAWA,SAASxuC,OAAO,GAAGyuC;oBAG9B,IAAID,SAAS3wC,OAAO,OAAO,KAAK;wBAC5B2wC,WAAWA,SAASxuC,OAAO;;oBAG/B0N,KAAKghC,SAASF;oBACdb,aAAa38C,KAAK0c;oBAClB6gC,kBAAkBx0C;mBAEtB,SAAS40C;oBACLvoC,QAAQkO,UAAU45B,QAAQ,sBAAsBnnB,MAAMynB,WAAW,wBAAwBG,UAAU7wB,OAAO,KAAK;oBAC/GywB,kBAAkBt0C;;mBAGrB,IAAI8sB,MAAM6nB,aAAa;gBACxBC,oBAAoB9nB,OAAO7hB,KACvB,SAAS4pC,eAAepmC;oBACpB,IAAIqmC,cAAcrmC,QAAQ7U;oBAE1B/F,GAAG+C,KAAK6X,SAAS,SAAS5X,KAAKi2B;wBAC3BunB,iBAAiBvnB,OAAOphB,KAAK;4BACzBopC,eAAe;4BAEf,IAAIA,gBAAgB,GAAG;gCACnBR,kBAAkBx0C;;;;oBAK9B,KAAK2O,QAAQ7U,QAAQ;wBACjB06C,kBAAkBx0C;;mBAI1B,SAASi1C,YAAYL;oBACjBvoC,QAAQkO,UAAU45B,QAAQ,sBAAsBnnB,MAAMynB,WAAW,wBAAwBG,UAAU7wB,OAAO,KAAK;oBAC/GywB,kBAAkBt0C;;;YAK9B,OAAOs0C;;QAIX,SAASM,oBAAoB9nB,OAAO4f,QAAQsI,cAAcC;YACtD,IAAIt1C,UAAUs1C,mBAAmB,IAAIphD,GAAG+L,WACpCs1C,YAAYxI,UAAU5f,MAAMqoB;YAEhCD,UAAUE,YACN,SAASC,YAAY5mC;gBACjB,IAAI6mC,aAAaN,eAAeA,aAAa/wC,OAAOwK,WAAWA;gBAE/D,IAAIA,QAAQ7U,QAAQ;oBAChBujB,WAAW;wBACPy3B,oBAAoB9nB,OAAOooB,WAAWI,YAAY31C;uBACnD;uBAEF;oBACDA,QAAQG,QAAQw1C;;eAIxB31C,QAAQK;YAGZ,OAAOL;;QAGX,SAAS41C,mBAAmBn3C,cAAc21C;YACtC,IAAIyB,4BACAC,4BAA4B,IAAI5hD,GAAG+L;YAEvCuM,QAAQkO,UAAUq7B;YAClB3B,eAAeG,aAAa;YAE5B,IAAI91C,aAAaoV,MAAM5Z,SAAS,MAAMuS,QAAQynC,oBAAoB;gBAC9DznC,QAAQkO,UAAU85B;gBAClBhoC,QAAQkO,UAAUs7B,UAAU,qBAAqB;gBACjD5B,eAAeG,aAAa;gBAC5BuB,0BAA0Bz1C;mBAEzB;gBACD0zC;gBAEA,IAAI7/C,GAAGsK,sBAAsBC,eAAe;oBACxCvK,GAAG+C,KAAKwH,aAAaC,OAAO,SAASxH,KAAKsE;wBACtC,IAAI2xB,QAAQ3xB,KAAKmD;wBAEjB,IAAIwuB,OAAO;4BAEP,IAAIA,MAAMxwB,QAAQ;gCACdo3C,aAAa38C,KAAKoE,KAAKs1C;mCAGtB;gCACD+E,sBAAsBz+C,KAAKs9C,iBAAiBvnB,OAAOphB,KAAK;oCACpD8pC,sBAAsBzf;oCACtB,IAAIyf,sBAAsB57C,WAAW,GAAG;wCACpC67C,0BAA0B31C;;;;;;uBAO7C;oBACD4zC,eAAet1C,aAAaoV;;gBAGhC,IAAIgiC,sBAAsB57C,WAAW,GAAG;oBACpC67C,0BAA0B31C;;;YAIlC,OAAO21C;;QAGX,SAASG,cAAcC;YACnB,IAAIC,WAAW,IAAIjiD,GAAGkiD;gBAClBxC,uBAAuBA;gBACvBz/C,SAAS+hD;gBACTG,SAAS,SAASjzC;oBACdlP,GAAGgiD,UAAU3/C,SAASiW,QAAQyR,QAAQi2B;oBACtC9wC,EAAEkzC;;gBAENC,uBAAuB,SAASnzC;oBAC5BlP,GAAGgiD,UAAU1/C,YAAYgW,QAAQyR,QAAQi2B;;gBAE7CsC,QAAQ,SAASpzC;oBACbwyC,mBAAmBxyC,EAAE3E,cAAc03C,UAAU7qC,KACzC;wBACI6oC,mBAAmBJ,cAAcoC;uBAErC;wBACI3pC,QAAQkO,UAAU45B,QAAQ,uEAAuE;;;;YAMjH/nC,eAAe1F,YAAY;gBACvBsvC,SAASzvC;;YAGbxS,GAAGgiD,UAAUl+C,aAAa67C,2BAA2B3/C,GAAGgiD,UAAU9hD;YAElE0/C,gBAAgB18C,KAAK++C;YAErB,OAAOA;;QAGX,SAASM,WAAWC;YAChB,IAAIC;YAEJziD,GAAG+C,KAAKy/C,UAAUj4C,aAAam4C,OAAO,SAAS7yC,KAAK5M;gBAChD,IAAIA,QAAQ,SAAS;oBACjBw/C,WAAW;oBACX,OAAO;;;YAIf,OAAOA;;QAWX,SAASE,mBAAmBzzC;YACxB,IAAIlP,GAAGqO,WAAW;gBACd,QAAQa,EAAE0zC;;YAGd,IAAI5iD,GAAGiO,UAAU;gBACb,OAAOiB,EAAE2rC,IAAI,KAAK3rC,EAAE2zC,IAAI;;YAG5B,OAAO3zC,EAAE2rC,MAAM,KAAK3rC,EAAE2zC,MAAM;;QAGhC,SAASC;YACL,IAAIC,YAAYzqC,QAAQwnC,kBAEpBkD,qBAAqB;gBACjB15B,WAAW;oBACPtpB,GAAG+C,KAAKggD,WAAW,SAAS//C,KAAKi/C;wBAC7BjiD,GAAGiiD,UAAUn+C,aAAa67C,2BAA2B3/C,GAAGiiD,UAAU/hD;wBAClEF,GAAGiiD,UAAU3/C,YAAYgW,QAAQyR,QAAQi2B;;mBAE9C;;YAGXhgD,GAAG+C,KAAKggD,WAAW,SAAS//C,KAAKi/C;gBAC7B,IAAI/B,iBAAiB6B,cAAcE;gBAGnC,IAAIc,UAAUh9C,UAAU/F,GAAGkT,kBAAkB+C,UAAU;oBACnDoC,eAAe/X,OAAOuJ,UAAU,aAAa,SAASqF;wBAClD,KAAKgxC,eAAeG,kBAAkBkC,WAAWrzC,IAAI;4BACjDlP,GAAG+C,KAAKggD,WAAW,SAAS//C,KAAKi/C;gCAG7B,IAAIA,oBAAoBgB,eACpBjjD,GAAGiiD,UAAUn+C,aAAa67C,yBAAyB;oCAEnD3/C,GAAGiiD,UAAU3gD;wCAAKlB,SAAS;;;;;;;;YAQnDiY,eAAe/X,OAAOuJ,UAAU,aAAa,SAASqF;gBAClD,IAAIyzC,mBAAmBzzC,IAAI;oBACvB8zC;;;YAOR3qC,eAAe/X,OAAON,GAAG6J,UAAUzG,WAAW,IAAI,cAAc,SAAS8L;gBACrE8zC;;YAGJ3qC,eAAe/X,OAAOuJ,UAAU,QAAQ,SAASqF;gBAC7CA,EAAED;gBACF+zC;;YAGJ3qC,eAAe/X,OAAOuJ,UAAU61C,uBAAuBsD;;QAG3DF;QAEA9iD,GAAG6B,OAAOxB;YACN6iD,oBAAoB,SAASjjD;gBACzBqY,QAAQwnC,iBAAiB58C,KAAKjD;gBAC9B8hD,cAAc9hD;;YAGlBkjD,gBAAgB,SAASljD;gBACrB,IAAI6Q,GACAsyC,MAAM9qC,QAAQwnC;gBAElB,KAAKhvC,KAAKsyC,KAAK;oBACX,IAAIA,IAAItyC,OAAO7Q,SAAS;wBACpB,OAAOmjD,IAAI7mC,OAAOzL,GAAG;;;;YAKjC0B,SAAS;gBACL6F,eAAe7F;gBACfxS,GAAG+C,KAAK68C,iBAAiB,SAAS58C,KAAKi/C;oBACnCA,SAASzvC;;;;;IAMzBxS,GAAGy/C,YAAYj5B,YAAY;QACvB;QAEA;YACIq7B,wBAAwB;YACxBvB,gCAAgC,SAAS3gC,OAAO0jC;YAChDvB,WAAW,SAAS9xB,MAAMszB;gBACtBtjD,GAAGmG,IAAI,6BAA6B6pB,OAAO,6BAA6BszB,iBAAiB,KAAK;;YAElGlD,SAAS,SAASh6C,SAASC;gBACvBrG,GAAGmG,IAAIC,SAASC;;;;IAK5BrG,GAAGkiD,iBAAiB,SAAS/pC;QACzB;QAEA,IAAIE,iBAAiB,IAAIrY,GAAGsS,kBACxBgG,SAASrY,SAASsjD,aAAaC;QAEnClrC;YACIrY,SAAS;YACTkiD,SAAS,SAASjzC;YAClBmlB,SAAS,SAASnlB;YAElBmzC,uBAAuB,SAASnzC;YAChCozC,QAAQ,SAASpzC;;QAGrBlP,GAAG6B,OAAOyW,SAASH;QACnBlY,UAAUqY,QAAQrY;QAElB,SAASwjD;YACL,OAAOzjD,GAAGiO,YAAajO,GAAGqO,aAAarO,GAAGsO;;QAG9C,SAASo1C,mBAAmBx0C;YAExB,KAAKs0C,qBAAqB;gBAGtB,IAAIC,0BAA0B;oBAC1BprC,eAAe/X,OAAOuJ,UAAU,YAAY,SAASqF;wBACjDA,EAAED;;uBAEH;oBACHoJ,eAAe/X,OAAOuJ,UAAU,YAAY,SAASqF;wBACjD,IAAIA,EAAE3E,cAAc;4BAChB2E,EAAE3E,aAAao5C,aAAa;4BAC5Bz0C,EAAED;;;;gBAKdu0C,sBAAsB;;;QAI9B,SAASI,gBAAgB10C;YAGrB,KAAKlP,GAAGkT,kBAAkB+C,UAAU;gBAChC,OAAO;;YAGX,IAAI4tC,YAAYC,KAAK50C,EAAE3E,cAEvBw5C,WAAW/jD,GAAGiO;YAOd41C,aAAa7jD,GAAGyN,QAAQzN,GAAGkT,kBAAkB+C,WAAW,OAAO6tC,GAAGE,kBAAkB;YACpF,OAAOF,MAAMD,eAAeC,GAAGnkC,UAAWokC,YAAYD,GAAGpB,MAAM5hD,YAAYgjD,GAAGpB,MAAM5hD,SAAS;;QAGjG,SAASmjD,oBAAoBC;YACzB,IAAIA,eAAe//C,WAAW;gBAC1Bo/C,cAAcW;;YAElB,OAAOX;;QAGX,SAASY;YACL,IAAIC;YAEJ,SAASC;gBACLD,iBAAiBv6C,SAASy6C,YAAY;gBACtCF,eAAeG,UAAUjsC,QAAQonC,uBAAuB,MAAM;;YAGlE,IAAI16C,OAAOw/C,aAAa;gBACpB;oBACIJ,iBAAiB,IAAII,YAAYlsC,QAAQonC;kBAE7C,OAAOlK;oBACH6O;;mBAGH;gBACDA;;YAGJx6C,SAAS46C,cAAcL;;QAG3B,SAASM;YACLrsC,eAAe/X,OAAOL,SAAS,YAAY,SAASiP;gBAChD,KAAK00C,gBAAgB10C,IAAI;oBACrB;;gBAKJ,IAAIy1C,SAAS3kD,GAAGyN,QAAQzN,GAAGkT,kBAAkB+C,WAAW,OAAO/G,EAAE3E,aAAay5C;gBAC9E,IAAIW,WAAW,UAAUA,WAAW,YAAY;oBAC5Cz1C,EAAE3E,aAAao5C,aAAa;uBACzB;oBACHz0C,EAAE3E,aAAao5C,aAAa;;gBAGhCz0C,EAAEkzC;gBACFlzC,EAAED;;YAGNoJ,eAAe/X,OAAOL,SAAS,aAAa,SAASiP;gBACjD,KAAK+0C,uBAAuB;oBACxB,KAAKL,gBAAgB10C,IAAI;wBACrB;;oBAEJoJ,QAAQ6pC,QAAQjzC;;;YAIxBmJ,eAAe/X,OAAOL,SAAS,aAAa,SAASiP;gBACjD,KAAK00C,gBAAgB10C,IAAI;oBACrB;;gBAGJoJ,QAAQ+b,QAAQnlB;gBAEhB,IAAI0zC,gBAAgB/4C,SAAS+6C,iBAAiB11C,EAAE21C,SAAS31C,EAAE41C;gBAE3D,IAAI9kD,GAAGK,MAAMS,SAAS8hD,gBAAgB;oBAClC;;gBAGJtqC,QAAQ+pC,sBAAsBnzC;;YAGlCmJ,eAAe/X,OAAOL,SAAS,QAAQ,SAASiP;gBAC5C,KAAK+0C,uBAAuB;oBACxB,KAAKL,gBAAgB10C,IAAI;wBACrB;;oBAGJA,EAAED;oBACFC,EAAEkzC;oBACF9pC,QAAQgqC,OAAOpzC;oBAEfi1C;;;;QAKZT;QACAgB;QAEA1kD,GAAG6B,OAAOxB;YACNggD,cAAc,SAAS6D;gBACnB,OAAOD,oBAAoBC;;YAG/B1xC,SAAS;gBACL6F,eAAe7F;;YAGnB+tC,YAAY;gBACR,OAAOtgD;;;;KCvelB;QACG;QAEAD,GAAG+kD;YACCzmC,iBAAiB,SAASC;gBACtBle,KAAK2kD,QAAQt+C,UAAU4X,gBAAgBjO,MAAMhQ,MAAM8H;gBACnD9H,KAAK4kD,YAAYC;;YAGrB7kC,kBAAkB;gBACdhgB,KAAK2kD,QAAQt+C,UAAU2Z,iBAAiBhQ,MAAMhQ,MAAM8H;gBACpD9H,KAAK4kD,YAAYE;;YAGrBC,kBAAkB,SAASnlD;gBACvBI,KAAKglD,QAAQhlD,KAAKglD,KAAKnC,mBAAmBjjD;;YAG9CqlD,qBAAqB,SAASrlD;gBAC1B,IAAII,KAAKglD,MAAM;oBACX,OAAOhlD,KAAKglD,KAAKlC,eAAeljD;;;YAIxCslD,iBAAiB,SAAS1qC;gBACtB,KAAKxa,KAAK4kD,YAAYO,gBAAgB3qC,KAAK;oBACvC,OAAOxa,KAAK4kD,YAAYQ,iBAAiB5qC;;;YAIjDV,OAAO;gBACH9Z,KAAK2kD,QAAQt+C,UAAUyT,MAAM9J,MAAMhQ,MAAM8H;gBACzC9H,KAAK4kD,YAAY9qC;gBAEjB,KAAK9Z,KAAK0e,SAAS2E,UAAUrjB,KAAK4kD,YAAYhjC,aAAa;oBACvD5hB,KAAK+sB,mBAAmB/sB,KAAKkpB;wBACzBtpB,SAASI,KAAK4kD,YAAYhjC;wBAC1BpJ,OAAOxY,KAAK0e,SAASrb,KAAK2mB;uBAC3BvQ;;gBAGP,IAAIzZ,KAAKglD,MAAM;oBACXhlD,KAAKglD,KAAK7yC;oBACVnS,KAAKglD,OAAOhlD,KAAKqlD;;gBAGrBrlD,KAAKslD,qBAAqB;gBAC1BtlD,KAAKulD,yBAAyB;gBAE9BvlD,KAAKwlD;;YAGTrgC,SAAS,SAAS3K,IAAI+B;gBAClB,IAAIkpC,oBAAoBzlD,KAAK0e,SAAS0R,eAAe7T;gBAErDvc,KAAK2kD,QAAQt+C,UAAU8e,QAAQnV,MAAMhQ,MAAM8H;gBAC3C9H,KAAK4kD,YAAYc,eAAelrC,IAAIirC;;YAGxCziC,aAAa,SAASxI;gBAClB,IAAIusB,SAAS/mC,KAAK2kD,QAAQt+C,UAAU2c,YAAYhT,MAAMhQ,MAAM8H;gBAE5Di/B,UAAU/mC,KAAK4kD,YAAYe,aAAanrC;gBACxC,OAAOusB;;YAGX9mB,gBAAgB,SAASzF;gBACrB,IAAIorC,YAAY5lD,KAAK2kD,QAAQt+C,UAAU4Z,eAAejQ,MAAMhQ,MAAM8H;gBAElE89C,aAAa5lD,KAAK4kD,YAAYiB,gBAAgBrrC;gBAC9C,OAAOorC;;YAGXE,OAAO,SAASC;gBACZ,OAAO/lD,KAAK4kD,YAAYoB,UAAUD;;YAGtCE,eAAe,SAASplC;gBACpB,IAAItB,OAAOvf,KAAKuhB,QAAQV;gBAExB,OAAOtB,KAAK2mC;;;QAOpBvmD,GAAGwmD;YACCtkC,YAAY,SAASpJ;gBACjB,IAAI4K,SAASrjB,KAAK2kD,QAAQt+C,UAAUwb,WAAW7R,MAAMhQ,MAAM8H;gBAE3D,KAAKub,QAAQ;oBACT,IAAI5K,aAAazY,KAAK+sB,kBAAkB;wBACpC1J,SAASrjB,KAAK4kD,YAAYhjC;;;gBAIlC,OAAOyB;;YAGX+iC,iBAAiB,SAASvlC;gBACtB7gB,KAAK4kD,YAAYyB,WAAWxlC;;YAGhC2kC,iCAAiC;gBAC7BxlD,KAAKsmD,2BAA2B3mD,GAAG4mD,2BAA2BvmD,KAAKwmD;gBAInExmD,KAAKymD,0BAA0B9mD,GAAGqO;gBAElC,IAAIhO,KAAK0mD,0BACT;oBACI1mD,KAAK2mD,wBAAwB3mD,KAAK4mD;oBAClC5mD,KAAK6mD,+BAA+B7mD,KAAK8mD;oBACzC9mD,KAAK+mD,6BAA6B/mD,KAAKgnD;;;YAI/C3B,mBAAmB;gBACf,IAAIttC,OAAO/X,MACPy/C,mBAAmBz/C,KAAK0e,SAASuoC,YAAYC,gBAC7CC,aAAannD,KAAK4kD,aAClBwC,kBAAkBD,WAAWE;gBAEjCD,mBAAmB3H,iBAAiB58C,KAAKukD;gBAEzC,OAAO,IAAIznD,GAAGy/C;oBACVK,kBAAkBA;oBAClBC,oBAAoB1/C,KAAK0e,SAAShV;oBAClCggB;wBACIi2B,YAAY3/C,KAAK0e,SAASgL,QAAQi2B;;oBAEtCx5B;wBACIq7B,wBAAwB;4BACpB2F,WAAWG;;wBAEfrH,gCAAgC,SAAS3gC,OAAO0jC;4BAC5CmE,WAAWI;4BAEX5nD,GAAG+C,KAAK4c,OAAO,SAAS3c,KAAK4c;gCACzBA,KAAK2mC,eAAelD;;4BAGxB,IAAI1jC,MAAM5Z,QAAQ;gCACdqS,KAAKiG,SAASsB,OAAO,MAAM;;;wBAGnCmiC,WAAW,SAAS9xB,MAAM63B;4BACtBzvC,KAAKwN,WAAWoK,MAAM63B;;wBAE1BzH,SAAS,SAASh6C,SAASC;4BACvB+R,KAAKjS,IAAIC,SAASC;;;;;YAMlCwgD,4BAA4B;gBACxB,IAAIzuC,OAAO/X;gBAEX,OAAO,IAAIL,GAAG4mD;oBACVY,YAAYnnD,KAAK4kD;oBAEjB9+C,KAAK,SAASC,SAAS0hD;wBACnB1vC,KAAKjS,IAAIC,SAAS0hD;;oBAGtBC,cAAc,SAAS7mC;wBACnB9I,KAAKwI,WAAWM;;oBAGpBiK,UAAU,SAASjK;wBACf9I,KAAK4H,OAAOkB;;oBAGhB8mC,SAAS,SAAS9mC;wBACd9I,KAAK+L,MAAMjD;;oBAGf+mC,SAAS,SAAS/mC;wBACd9I,KAAKiL,YAAYnC;;oBAGrBgnC,YAAY,SAAShnC;wBACjB9I,KAAKkI,eAAeY;;oBAGxBinC,WAAW,SAASjnC;wBAChB,OAAO9I,KAAKsI,QAAQQ;;;;YAKhC6lC,wBAAwB;gBAEpB,OAAO1mD,KAAK4kD,YAAYmD,6BAChB/nD,KAAK0e,SAASuQ,cACftvB,GAAGqoD,wBACHroD,GAAGsoD,6BACHtoD,GAAGsoD;;YAGdC,sBAAsB;gBAClB,IAAInwC,OAAO/X,MACPmnD,aAAannD,KAAK4kD;gBAEtB;oBACIuC,YAAYA;oBACZrhD,KAAK,SAASC,SAAS0hD;wBACnB1vC,KAAKjS,IAAIC,SAAS0hD;;oBAEtBU,mBAAmB,SAAStnC;wBACxB,OAAO9I,KAAKsK;4BAAY7H,IAAIqG;2BAAShG;;oBAEzCitC,WAAW,SAASjnC;wBAChB,OAAO9I,KAAKsI,QAAQQ;;oBAExBunC,WAAW,SAAS5tC,IAAI+B;wBACpBxE,KAAKoN,QAAQ3K,IAAI+B;;oBAErB8rC,uBAAuB,SAAS7tC,IAAI8tC;wBAChC,IAAIC,UAAU5oD,GAAGwnD,WAAWqB,aAAahuC,MACrCiuC,kBAAkB9oD,GAAGwnD,WAAW/B,iBAAiB5qC;wBAErD,IAAI8tC,WAAW;4BACXC,QAAQvmD,SAAS;4BACjBmlD,WAAWuB,aAAaluC;4BACxB2sC,WAAWwB,aAAanuC;+BAEvB;4BACD+tC,QAAQtmD,YAAY;4BACpBklD,WAAWyB,aAAapuC;4BACxB2sC,WAAW0B,aAAaruC;;wBAI5BiuC,gBAAgBzmD,SAAS,WAAWC,YAAY;;;;YAK5D8mB,uBAAuB,SAASvO,IAAIwB,WAAWD;gBAC3C/b,KAAK2kD,QAAQt+C,UAAU0iB,sBAAsB/Y,MAAMhQ,MAAM8H;gBAEzD,IAAI9H,KAAK0mD,0BAA0B;oBAE/B,IAAI1mD,KAAK4kD,YAAYQ,iBAAiB5qC,OAAOuB,cAAcpc,GAAGkb,OAAOkC,WAAW;wBAC5E/c,KAAK4kD,YAAYkE,qBAAqBtuC;wBACtCxa,KAAK4kD,YAAY+D,aAAanuC;;;gBAItC,IAAIwB,cAAcrc,GAAGkb,OAAOwC,mBAAmBtB,cAAcpc,GAAGkb,OAAOuC,WAAW;oBAC9Epd,KAAK4kD,YAAYmE,UAAUvuC;oBAC3Bxa,KAAK4kD,YAAYoE,cAAcxuC;oBAC/B7a,GAAGK,KAAK4kD,YAAYQ,iBAAiB5qC,KAAKvY,YAAYjC,KAAKipD,SAASC;uBAEnE,IAAIntC,cAAcpc,GAAGkb,OAAO0C,eAAe;oBAC5Cvd,KAAK4kD,YAAYuE,UAAU3uC;;;YAInCssC,gCAAgC;gBAC5B,IAAIzrC,OAAO1b,GAAG6B,WAAWxB,KAAKkoD;gBAE9B,OAAO,IAAIvoD,GAAGypD,4BAA4B/tC;;YAG9C2rC,8BAA8B;gBAC1B,IAAI3rC,OAAO1b,GAAG6B,WAAWxB,KAAKkoD;gBAE9B,OAAO,IAAIvoD,GAAGsoD,0BAA0B5sC;;YAG5CurC,yBAAyB;gBACrB,IAAIvrC,OAAO1b,GAAG6B,WAAWxB,KAAKkoD;gBAE9B,OAAO,IAAIvoD,GAAGqoD,qBAAqB3sC;;YAGvCsX,gBAAgB,SAASnY;gBACrBxa,KAAK2kD,QAAQt+C,UAAUssB,eAAe3iB,MAAMhQ,MAAM8H;gBAClD9H,KAAK4kD,YAAYyE,YAAY7uC;;YAGjCkW,gBAAgB,SAASe,YAAYC;gBACjC1xB,KAAK2kD,QAAQt+C,UAAUqqB,eAAe1gB,MAAMhQ,MAAM8H;gBAClD9H,KAAK4kD,YAAY0E;;YAGrB/2B,WAAW,SAAS/X,IAAI9Y;gBACpB,IAAI6d,OAAOvf,KAAKuhB,QAAQ/G;gBAExB,IAAI+E,QAAQA,KAAKghC,UAAUvgD,KAAK0e,SAASuoC,YAAYsC,sBAAsB;oBACvEvpD,KAAKsjB,aAAauF,YAAYrO;wBAC1BgvC,QAAQjqC,KAAKghC;;;gBAIrBvgD,KAAK2kD,QAAQt+C,UAAUksB,UAAUviB,MAAMhQ,MAAM8H;gBAC7C9H,KAAKypD,WAAWjvC,IAAI9Y;;YAIxB+wB,cAAc,SAASjY;gBAEnB,IAAIxa,KAAK0mD,0BAA0B;oBAC/B1mD,KAAK4kD,YAAYkE,qBAAqBtuC;oBACtCxa,KAAK4kD,YAAYiE,aAAaruC;oBAG9B,KAAKxa,KAAKymD,wBAAwB;wBAC9BzmD,KAAK+mD,2BAA2B2C,WAAW1pD,KAAK4kD,YAAY4D,aAAahuC;;;;YAMrFmQ,aAAa,SAASnQ,IAAI9Y,MAAM+oB,QAAQC;gBACpC1qB,KAAK2kD,QAAQt+C,UAAUskB,YAAY3a,MAAMhQ,MAAM8H;gBAE/C9H,KAAK4kD,YAAY+E,eAAenvC,IAAIiQ,QAAQC;gBAE5C,IAAIA,UAAU,KAAKppB,KAAKC,MAAMkpB,SAASC,QAAQ,SAAS,KAAK;oBACzD1qB,KAAK4kD,YAAYgF,WAAWpvC;oBAC5Bxa,KAAK4kD,YAAYuE,UAAU3uC;oBAC3Bxa,KAAK4kD,YAAYiF,aAAarvC;oBAC9Bxa,KAAK4kD,YAAYoE,cAAcxuC,IAAIxa,KAAK0e,SAASrb,KAAKymD;oBAGtD9pD,KAAK+pD,iBAAiBvvC;uBAErB;oBAEDxa,KAAK+pD,iBAAiBvvC,IAAIiQ,QAAQC;;;YAI1CwI,kBAAkB,SAASzI,QAAQC;gBAC/B1qB,KAAK2kD,QAAQt+C,UAAU6sB,iBAAiBljB,MAAMhQ,MAAM8H;gBACpD9H,KAAK4kD,YAAY/I,oBAAoBpxB,QAAQC;;YAGjDG,aAAa,SAASrQ,IAAI9Y,MAAMY,QAAQgS;gBACpC,IAAI01C,eAAehqD,KAAK2kD,QAAQt+C,UAAUwkB,YAAY7a,MAAMhQ,MAAM8H,YAC9Dq/C,aAAannD,KAAK4kD,aAClBnlC,gBAAgB0nC,WAAW/B,iBAAiB5qC,KAC5CzC,OAAO/X;gBAEX,SAASiqD,eAAe3nD;oBAGpB,KAAKmd,eAAe;wBAChB;;oBAGJ0nC,WAAW6B,cAAcxuC;oBAEzB7a,GAAG8f,eAAexd,YAAY8V,KAAKkxC,SAASC;oBAC5C/B,WAAW0C,aAAarvC;oBAExB,IAAIzC,KAAKsK;wBAAY7H,IAAIA;uBAAKK,WAAWlb,GAAGkb,OAAO0C,eAAe;wBAC9D4pC,WAAWyC,WAAWpvC;;oBAE1B2sC,WAAWkC,YAAY7uC;oBAEvB,IAAIlY,OAAOsJ,SAAS;wBAChBmM,KAAKmyC,sBAAsB1vC;2BAE1B;wBACD7a,GAAG8f,eAAezd,SAAS+V,KAAKkxC,SAASkB;wBACzChD,WAAWiD,WAAW5vC;wBAEtB,IAAI2sC,WAAWkD,sBAAsBtyC,KAAKoL,gBAAgB3I,KAAK;4BAC3D7a,GAAG8f,eAAezd,SAAS+V,KAAKkxC,SAASvN;4BACzCyL,WAAWmD,UAAU9vC;;wBAEzBzC,KAAKwyC,2BAA2B/vC,IAAIlY;;;gBAK5C,IAAI0nD,wBAAwBrqD,GAAG+L,SAAS;oBACpCs+C,aAAaxyC,KAAK,SAASgzC;wBACvBP,eAAeO;;uBAIlB;oBACDP,eAAe3nD;;gBAGnB,OAAO0nD;;YAGXE,uBAAuB,SAAS1vC;gBAC5B,IAAI2sC,aAAannD,KAAK4kD;gBAEtB,IAAI5kD,KAAKovB,qBAAqB;oBAC1B+3B,WAAWsD,iBAAiBjwC;;gBAGhC7a,GAAGwnD,WAAW/B,iBAAiB5qC,KAAKxY,SAAShC,KAAKipD,SAASr9C;gBAE3D5L,KAAK0qD,sBAAsBlwC;;YAG/B0Q,eAAe,SAAS1Q;gBACpBxa,KAAK2kD,QAAQt+C,UAAU6kB,cAAclb,MAAMhQ,MAAM8H;gBACjD9H,KAAK4kD,YAAY+F,YAAYnwC;;YAGjC4Q,WAAW,SAAS5Q,IAAI9Y;gBACpB,IAAIsoD,eAAehqD,KAAK2kD,QAAQt+C,UAAU+kB,UAAUpb,MAAMhQ,MAAM8H;gBAEhE9H,KAAK4kD,YAAY+F,YAAYnwC;gBAE7B,OAAOwvC;;YAGXz+B,gBAAgB,SAAS/Q,IAAI8Q;gBACzBtrB,KAAK2kD,QAAQt+C,UAAUklB,eAAevb,MAAMhQ,MAAM8H;gBAIlD,IAAIwjB,UAAU+L,YAAY,KAAKr3B,KAAK4f,SAAS4jB,YAAYhpB,KAAK;oBAC1Dxa,KAAK4kD,YAAYgG,WAAWpwC;;;YAIpCwQ,WAAW,SAASxQ,IAAI9Y;gBACpB1B,KAAK2kD,QAAQt+C,UAAU2kB,UAAUhb,MAAMhQ,MAAM8H;gBAC7C9H,KAAKomD,gBAAgB5rC;gBAErB,IAAIxa,KAAKotB,sBAAsB,GAAG;oBAC9BptB,KAAK4kD,YAAY0E;;;YAIzBv3B,oBAAoB,SAASvX;gBACzB,IAAIqwC,oBAAoBC,SAASC;gBAEjC/qD,KAAK2kD,QAAQt+C,UAAU0rB,mBAAmB/hB,MAAMhQ,MAAM8H;gBAEtD9H,KAAKgrD,gBAAgBxwC;gBAErB,IAAIxa,KAAK0e,SAASoF,MAAMmnC,mBAAmB;oBACvCJ,qBAAqB7qD,KAAKijB,aAAazI;oBACvCswC,UAAU9qD,KAAK0e,SAASoF,MAAM2Q;oBAE9Bs2B,YAAY/qD,KAAK0e,SAASoF,MAAMonC,cAAchpD,QAAQ,iBAAiB2oD;oBACvEE,YAAYA,UAAU7oD,QAAQ,gBAAgB4oD;oBAE9C9qD,KAAK4kD,YAAYoE,cAAcxuC,IAAIuwC;oBACnCprD,GAAGK,KAAK4kD,YAAYQ,iBAAiB5qC,KAAKxY,SAAShC,KAAKipD,SAASC;;;YAKzE14B,sBAAsB,SAAShW;gBAC3B,IAAIxa,KAAK2kD,QAAQt+C,UAAUmqB,qBAAqBxgB,MAAMhQ,MAAM8H,YAAY;oBACpE9H,KAAK4kD,YAAYuG,cAAc3wC;oBAC/B7a,GAAGK,KAAK4kD,YAAYQ,iBAAiB5qC,KAAKvY,YAAYjC,KAAKipD,SAASkB;oBACpEnqD,KAAK4kD,YAAYoE,cAAcxuC;oBAC/Bxa,KAAK4kD,YAAY+F,YAAYnwC;oBAC7Bxa,KAAKgrD,gBAAgBxwC;oBACrB,OAAO;uBAEN;oBACD7a,GAAGK,KAAK4kD,YAAYQ,iBAAiB5qC,KAAKxY,SAAShC,KAAKipD,SAASvN;oBACjE17C,KAAK4kD,YAAY0F,UAAU9vC;oBAC3B,OAAO;;;YAIfgG,iBAAiB,SAAShG;gBACtB,IAAIoY,oBAAoBjzB,GAAGgQ,KAAK3P,KAAKorD,wBAAwBprD;gBAE7DA,KAAK2kD,QAAQt+C,UAAUma,gBAAgBja,KAAKvG,MAAMwa,IAAIoY;;YAG1Dw4B,wBAAwB,SAAS5wC,IAAIG,MAAMkY;gBACvC,IAAI7yB,KAAK0e,SAAS6B,WAAW8qC,cAAc;oBACvCrrD,KAAKsrD,mBAAmBt7C,MAAMhQ,MAAM8H;uBAEnC;oBACD9H,KAAKurD,mBAAmBv7C,MAAMhQ,MAAM8H;;;YAI5Cwf,mBAAmB,SAAS9M,IAAIlG,KAAK+S;gBACjCrnB,KAAK2kD,QAAQt+C,UAAUihB,kBAAkBtX,MAAMhQ,MAAM8H;gBAErD9H,KAAK4kD,YAAYyE,YAAY7uC;gBAE7B,IAAI6M,SAAS;oBACTrnB,KAAK4kD,YAAYoE,cAAcxuC,IAAIxa,KAAK0e,SAAS6B,WAAWirC;oBAC5DxrD,KAAK4kD,YAAY6F,iBAAiBjwC;uBAEjC;oBACDxa,KAAKomD,gBAAgB5rC;;;YAI7B+wC,oBAAoB,SAAS/wC,IAAIG,MAAMkY;gBACnC7yB,KAAK4kD,YAAY6G,iBAAiBjxC;gBAClCxa,KAAK4kD,YAAY+F,YAAYnwC;gBAC7Bxa,KAAK4kD,YAAYoE,cAAcxuC,IAAIxa,KAAK0e,SAAS6B,WAAWmrC;gBAC5D1rD,KAAKgzB,eAAeC,WAAWjjB,MAAMhQ,MAAM8H;;YAG/CwjD,oBAAoB,SAAS9wC,IAAIG,MAAMye;gBAEnC,IAAIpnB,WAAWhS,KAAKqgB,QAAQ7F,KACxBmxC,iBAAiB3rD,KAAK0e,SAAS6B,WAAWorC,eAAezpD,QAAQ,iBAAiB8P,WAClF2I,OAAO3a,KAAK8iB,QAAQtI,KACpBoxC,oBAAoB9jD,WACpBiQ,OAAO/X,MACPsP;gBAEJA,SAAStP,KAAK0e,SAASmtC,YAAYF;gBAEnC,IAAIhsD,GAAGkX,iBAAiBvH,SAAS;oBAC7BA,OAAOyH,KAAK;wBACRgB,KAAKwzC,mBAAmBv7C,MAAM+H,MAAM6zC;;uBAGvC,IAAIt8C,WAAW,OAAO;oBACvByI,KAAKwzC,mBAAmBv7C,MAAM+H,MAAM6zC;;;YAI5CnC,YAAY,SAASjvC,IAAI9Y,MAAMoqD;gBAC3B,IAAIC,aACAC,eAAe,GACfC,cAAcjsD,KAAK4f,SAAS2jB,UAAU/oB,OAAOxa,KAAK0e,SAASrI,QAAQ61C,YACnEpV;gBAEJ,IAAI92C,KAAK0e,SAAS3e,QAAQosD,cAAc;oBACpC,IAAInsD,KAAKslD,qBAAqB,KAAKtlD,KAAKulD,yBAAyB,GAAG;wBAChEyG,eAAehsD,KAAKulD,yBAAyB;;oBAGjDwG;wBACI/wC,OAAOgxC;;;gBAIf,KAAKF,QAAQ;oBACT,IAAI9rD,KAAK0e,SAASiX,gCAAgCh2B,GAAGkT,kBAAkBsC,eAAe;wBAClFnV,KAAK4kD,YAAYwH;;oBAMrB,KAAKpsD,KAAK0e,SAAShV,UAAU;wBACzBotC,SAAS92C,KAAKqiB;4BAAY7H,IAAIA;;wBAE9Bxa,KAAKqsD,qBAAqBrsD,KAAKqsD,sBAAsBvV,OAAOp7B;wBAE5D,IAAIo7B,OAAOp7B,iBAAiB1b,KAAKqsD,uBAAuBvV,OAAOp7B,cAAc;4BACzE1b,KAAK4f,SAASC;4BACd7f,KAAKssD;4BACLtsD,KAAKqsD,qBAAqB;;;;gBAKtC,IAAIP,QAAQ;oBACR9rD,KAAK4kD,YAAY2H,eAAe/xC,IAAIxa,KAAK0e,SAAS0R,eAAe1uB,OAAOqqD,aAAaE;oBACrFjsD,KAAK4kD,YAAY4H,gBAAgBhyC,IAAIxa,KAAKqhB,eAAe7G,KAAK,MAAMxa,KAAK0e,SAAS+tC,WAAWz0B;uBAE5F;oBACDh4B,KAAK4kD,YAAYxpC,QAAQZ,IAAIxa,KAAK0e,SAAS0R,eAAe1uB,OAAOqqD,aAAaE;oBAC9EjsD,KAAK4kD,YAAY8H,gBAAgBlyC,IAAIxa,KAAKuhB,QAAQ/G,KAAKxa,KAAK0e,SAAS+tC,WAAWz0B;;gBAGpFh4B,KAAKulD,0BAA0B;gBAE/B,IAAIuG,UACC9rD,KAAK0e,SAAS3e,QAAQ4sD,oBAAoBhtD,GAAGkT,kBAAkBsC,eAAgB;oBAEhFnV,KAAK+pD,iBAAiBvvC;;;YAI9B8xC,YAAY;gBACRtsD,KAAK4kD,YAAYE;gBACjB9kD,KAAKggB;;YAGT+pC,kBAAkB,SAASvvC,IAAIoyC,YAAYvR;gBACvC,IAAI7/B,OAAOxb,KAAKuiB,QAAQ/H,KACpBqyC,iBAAiB7sD,KAAKosB,YAAY5Q;gBAEtC,IAAIA,QAAQ,GAAG;oBACX,IAAIoxC,eAAe9oD,aAAau3C,cAAcv3C,WAAW;wBACrD+oD,iBAAiB7sD,KAAK8sD,gBAAgBF,YAAYvR;;oBAGtDr7C,KAAK4kD,YAAYpoC,WAAWhC,IAAIqyC;;;YAIxCC,iBAAiB,SAASC,cAAc1R;gBACpC,IAAIt1C,UAAU/F,KAAK0e,SAASrb,KAAK2pD;gBACjC,SAAS//C,EAAEvL,MAAMwuB;oBAAenqB,UAAUA,QAAQ7D,QAAQR,MAAMwuB;;gBAEhEjjB,EAAE,aAAa3L,KAAKC,MAAMwrD,eAAe1R,YAAY;gBACrDpuC,EAAE,gBAAgBjN,KAAKosB,YAAYivB;gBACnC,OAAOt1C;;YAGXwkD,4BAA4B,SAAS/vC,IAAIuW;gBACrC,IAAIk8B,MAAMC,kBAAkBC;gBAE5BF,OAAOjtD,KAAK0e,SAAS0uC,wBAAwBH;gBAC7CC,mBAAmBltD,KAAK0e,SAAS0uC,wBAAwBF;gBAEzD,IAAID,SAAS,UAAU;oBACnBE,gBAAgBp8B,SAASm8B;oBACzB,KAAKC,eAAe;wBAChBA,gBAAgBntD,KAAK0e,SAASrb,KAAKgqD;;oBAGvCrtD,KAAK4kD,YAAYoE,cAAcxuC,IAAI2yC;oBAEnC,IAAIntD,KAAK0e,SAAS0uC,wBAAwBE,eAAe;wBACrDttD,KAAKutD,aAAa/yC,IAAI2yC;;uBAGzB,IAAIF,SAAS,WAAW;oBACzBjtD,KAAK4kD,YAAYoE,cAAcxuC,IAAIxa,KAAK0e,SAASrb,KAAKgqD;uBAErD,IAAIJ,SAAS,QAAQ;oBACtBjtD,KAAK8F,IAAI,4CAA4CmnD,OAAO,kBAAkB;;;YAItFM,cAAc,SAAS/yC,IAAInX;gBACvBrD,KAAK4kD,YAAYQ,iBAAiB5qC,IAAIhC,QAAQnV;;YAGlD2nD,iBAAiB,SAASxwC;gBACtB,KAAKxa,KAAK0e,SAASiX,+BAA+Bh2B,GAAGkT,kBAAkBsC,eAAe;oBAClFnV,KAAK4kD,YAAYwF,WAAW5vC;;;YAIpC+K,YAAY,SAASoK,MAAMjuB,MAAMuF;gBAC7B,IAAIlB,UAAU/F,KAAK2kD,QAAQt+C,UAAUkf,WAAWvV,MAAMhQ,MAAM8H;gBAC5D9H,KAAK0e,SAAS8uC,YAAYznD;;YAG9BmgB,aAAa,SAASngB;gBAClB/F,KAAK2kD,QAAQt+C,UAAU6f,YAAYlW,MAAMhQ,MAAM8H;gBAC/C9H,KAAK0e,SAAS8uC,YAAYznD;;YAG9B0nD,mBAAmB;gBACf,IAAI11C,OAAO/X;gBAEXA,KAAK0e,SAASyH,UAAU0B,kBAAkB;oBACtC,IAAI9hB,UAAUgS,KAAK2G,SAASgJ,MAAMgmC,mBAC9BC,aAAa51C,KAAK2G,SAASgJ,MAAM9I;oBAErC,OAAO7G,KAAK2G,SAASkvC,WAAW7nD,SAAS4nD;;;YAIjDxhC,qBAAqB,SAAS3R,IAAI9Y;gBAC9B1B,KAAKslD,sBAAsB;gBAC3BtlD,KAAK2kD,QAAQt+C,UAAU8lB,oBAAoBnc,MAAMhQ,MAAM8H;;YAG3D4X,wBAAwB,SAASvV,OAAO2T,QAAQC;gBAC5C/d,KAAKslD,qBAAqBn7C,MAAMzE;gBAChC1F,KAAKulD,yBAAyB;gBAC9BvlD,KAAK2kD,QAAQt+C,UAAUqZ,uBAAuB1P,MAAMhQ,MAAM8H;;YAG9D4iD,uBAAuB,SAAS7pC;gBAC5B,IAAIgF,eAAe7lB,KAAKqhB,eAAeR,SACnCgtC,aAAa7tD,KAAKqiB;oBAAY7H,IAAIqG;mBAAShG;gBAE/C,IAAIgzC,eAAeluD,GAAGkb,OAAO6C,YACxBmI,gBACD7lB,KAAK0e,SAAS+tC,WAAWqB,aAAaC,sBACrCpuD,GAAGkT,kBAAkBkD,gBAAgB;oBAItC/V,KAAK4kD,YAAY4H,gBAAgB3rC,QAAQgF,cAAc7lB,KAAK0e,SAAS+tC,WAAWz0B;;;YAIxF5Z,gBAAgB,SAASsH;gBACrB,IAAIlL,KAAKxa,KAAK2kD,QAAQt+C,UAAU+X,eAAepO,MAAMhQ,MAAM8H;gBAE3D9H,KAAKypD,WAAWjvC,IAAIxa,KAAKqgB,QAAQ7F,KAAK;gBACtCxa,KAAK4kD,YAAYyE,YAAY7uC;gBAC7Bxa,KAAK4kD,YAAYgF,WAAWpvC;gBAC5Bxa,KAAKkqD,sBAAsB1vC;gBAE3B,OAAOA;;YAGXuR,UAAU,SAASvR,IAAIiC;gBACnBzc,KAAK2kD,QAAQt+C,UAAU0lB,SAAS/b,MAAMhQ,MAAM8H;gBAE5C9H,KAAK4kD,YAAYpoC,WAAWhC,IAAIxa,KAAKosB,YAAY3P;;YAGrD4X,yBAAyB;gBACrBr0B,KAAK4kD,YAAYC;gBACjB7kD,KAAK2kD,QAAQt+C,UAAUguB,wBAAwBrkB,MAAMhQ,MAAM8H;;;;IC7sBvEnI,GAAGquD,eAAe,SAASl2C,GAAGsS;QAC1B;QAEA,IAAIrS,OAAO/X;QAKXA,KAAK2kD,UAAUv6B,YAAYzqB,GAAGyqB,WAAWsL,oBAAoB/1B,GAAG+1B;QAChE11B,KAAK2kD,QAAQ30C,MAAMhQ,MAAM8H;QAGzBnI,GAAG6B,OAAOxB,KAAK0e;YACX9e,SAAS;YAETyjB,QAAQ;YAER4qC,aAAa;YAEbhH;gBACIC;gBACAqC,sBAAsB;;YAG1BlmD;gBACI2pD,gBAAgB;gBAChBK,YAAY;gBACZvD,oBAAoB;gBACpB/iB,QAAQ;;YAGZmnB,UAAU;YAEVxkC;gBACIw/B,UAAU;gBACVxN,WAAW;gBACX9vC,SAAS;gBACTu+C,MAAM;gBACNgE,UAAU;gBACVtuD,MAAM;gBACN8/C,YAAY;;YAGhByN;gBACIH,MAAM;gBACNC,kBAAkB;gBAClBI,eAAe;;YAGnBz9B;gBACIu+B,mBAAmB;gBACnBC,oBAAoB;;YAGxBvqC;gBACImnC,mBAAmB;gBACnBC,eAAe;;YAGnB3qC;gBACI8qC,cAAc;gBACdM,gBAAgB;gBAChBD,oBAAoB;gBACpBF,oBAAoB;;YAIxBzrD;gBACI4sD,kBAAkB;gBAClBR,cAAc;;YAGlBzkC;gBACI4mC,eAAe;gBACfZ,mBAAmB;;YAGvBjB;gBACIz0B,eAAe;gBACfu2B,UAAU;gBACVT;oBACIC,mBAAmB;oBACnBS,kBAAkB;oBAClBC,aAAa;;gBAEjBC,mBAAmB;;YAGvBr4C;gBACI61C,YAAY;;YAGhBsB,aAAa,SAASznD;gBAClB,IAAIgS,KAAK6sC,YAAY+J,UAAU,UAAU;oBACrC,OAAO52C,KAAK6sC,YAAYgK,WAAW,SAAS7oD;uBAE3C;oBACDkjB,WAAW;wBACPtkB,OAAOisB,MAAM7qB;uBACd;;;YAIX8lD,aAAa,SAAS9lD;gBAClB,IAAIgS,KAAK6sC,YAAY+J,UAAU,YAAY;oBACvC,OAAO52C,KAAK6sC,YAAYgK,WAAW,WAAW7oD;uBAE7C;oBACD,OAAOpB,OAAOkqD,QAAQ9oD;;;YAI9B6nD,YAAY,SAAS7nD,SAAS+oD;gBAC1B,IAAI/2C,KAAK6sC,YAAY+J,UAAU,WAAW;oBACtC,OAAO52C,KAAK6sC,YAAYgK,WAAW,UAAU7oD,SAAS+oD;uBAErD;oBACD,OAAOnqD,OAAOoqD,OAAOhpD,SAAS+oD;;;WAGvC;QAGHnvD,GAAG6B,OAAOxB,KAAK0e,UAAU5G,GAAG;QAE5B9X,KAAK4kD,cAAc,IAAIjlD,GAAGqvD;YACtBlpD,KAAKnG,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;YACvBivD,gBAAgBjvD,KAAK0e,SAASwvC;YAC9BgB,aAAalvD,KAAK0e,SAAS9e;YAC3BuvD,iBAAiBnvD,KAAK0e,SAASuvC;YAC/B5qC,QAAQrjB,KAAK0e,SAAS2E;YACtB60B,gBAAgBl4C,KAAKohB;YACrBsI;gBACI7pB,MAAMG,KAAK0e,SAASgL,QAAQ7pB;gBAC5BsuD,UAAUnuD,KAAK0e,SAASgL,QAAQykC;;YAEpCla;gBACImb,WAAWpvD,KAAK0e,SAAS+tC,WAAW8B;gBACpCG,mBAAmB1uD,KAAK0e,SAAS+tC,WAAWiC;;YAEhDZ;gBACIuB,iBAAiBrvD,KAAK0e,SAAS+tC,WAAWqB,aAAaC;gBACvDuB,uBAAuBtvD,KAAK0e,SAAS+tC,WAAWqB,aAAaU;gBAC7De,qBAAqBvvD,KAAK0e,SAAS+tC,WAAWqB,aAAaW;;YAE/DprD,MAAMrD,KAAK0e,SAASrb;;QAGxB,IAAIrD,KAAK0e,SAAS6K,YAAYoH,qBAAqBhxB,GAAG6O,YAAY7O,GAAG+O,aAAa;YAC9E1O,KAAK4kD,YAAY4K,cAAcxvD,KAAK0e,SAASmR,SAASgB;eAErD,KAAKlxB,GAAGkT,kBAAkB2D,aAAcxW,KAAK0e,SAASsI,KAAKqI,aAAa1vB,GAAGkT,kBAAkB4D,YAAa;YAC3GzW,KAAK4kD,YAAY4K,cAAcxvD,KAAK0e,SAASmR,SAASw+B;eAErD;YACDruD,KAAKo1B;YAELp1B,KAAK4kD,YAAYhX;YAEjB5tC,KAAKipD,WAAWjpD,KAAK0e,SAASgL;YAE9B,KAAK1pB,KAAK0e,SAAS2E,UAAUrjB,KAAK4kD,YAAYhjC,aAAa;gBACvD5hB,KAAK+sB,mBAAmB/sB,KAAKkpB;oBACzBtpB,SAASI,KAAK4kD,YAAYhjC;oBAC1BpJ,OAAOxY,KAAK0e,SAASrb,KAAK2mB;mBAC3BvQ;;YAGPzZ,KAAKwlD;YAEL,IAAI7lD,GAAGy/C,eAAez/C,GAAGkT,kBAAkB+C,UAAU;gBACjD5V,KAAKglD,OAAOhlD,KAAKqlD;;YAGrB,IAAIrlD,KAAK0e,SAASgJ,MAAMD,iBAAiBznB,KAAK0e,SAASgJ,MAAM4mC,eAAe;gBACxE,IAAI3uD,GAAG6nB,cAAc;oBACjBxnB,KAAKytD;uBAEJ;oBACDztD,KAAK8F,IAAI,mCAAmC;;;YAIpD9F,KAAKslD,qBAAqB;YAC1BtlD,KAAKulD,yBAAyB;;;IAKtC5lD,GAAG6B,OAAO7B,GAAGquD,aAAa3nD,WAAW1G,GAAGge;IACxChe,GAAG6B,OAAO7B,GAAGquD,aAAa3nD,WAAW1G,GAAG8lB;IAGxC9lB,GAAG6B,OAAO7B,GAAGquD,aAAa3nD,WAAW1G,GAAG+kD;IACxC/kD,GAAG6B,OAAO7B,GAAGquD,aAAa3nD,WAAW1G,GAAGwmD;IC5LxCxmD,GAAGqvD,aAAa,SAAS3zC;QACrB;QAEA,IAAIo0C,eAAe,cACfC,oBAAoB,eACpBC,0BAA0B,eAC1BC,8BAA8B,mBAE9BC,qBAAqB,oBACrBC,sBAAsB,qBACtBC,oBAAoB,kBACpBC,uBAAuB,qBACvBC;YACIC,SAAS1mD,SAAS2mD;YAClBC;WAEJC,mBAAmB,OACnBC,sBAAsB,GACtBC,+BAA+B,OAC/BC,2BACAC,oBAAoB,GACpBx4C;YACInS,KAAK;YACLmuC;gBACImb,WAAW;gBACXV,mBAAmB;;YAEvBO,gBAAgB;YAChBC,aAAa;YACbC,iBAAiB;YACjB9rC,QAAQ;YACR60B,gBAAgB;YAChBxuB;gBACI7pB,MAAM;gBACNsuD,UAAU;;YAEdL;gBACIuB,iBAAiB;gBACjBC,uBAAuB;gBACvBC,qBAAqB;;YAEzBlsD;gBACI0jC,QAAQ;;WAGhB2pB;YACIrtC,QAAQ;YACRstC,aAAa;YACbC,oBAAoB;YACpBC,eAAe;YACfC,eAAe;YACfC,gBAAgB;YAChBC,cAAc;YACdC,UAAU;YACVC,MAAM;YACNC,MAAM;YACNC,sBAAsB;YACtBj7C,aAAa;YACbk7C,2BAA2B;YAC3BC,kBAAkB;YAClB/xC,MAAM;YACNgyC,SAAS;YACT/1C,MAAM;YACNmE,QAAQ;YACRzJ,OAAO;YACPs7C,gBAAgB;YAChBC,cAAc;YACd3tC,OAAO;YACP4tC,YAAY;YACZC,mBAAmB;YACnBC,cAAc;YACdC,UAAU;YACVC,gBAAgB;YAChBC,uBAAuB;YACvBC,WAAW;WAEfC,wBACAC,iCAAiC,IAAIvyD,GAAG+L,WACxCymD,+BAA+B,IAAIxyD,GAAG+L,WACtC5F,KACAssD,qBACAC,qBACAC,cACA9wC,WACAiN,UACA8jC,gBACAC,aAKAC,6BAA6B;YACzB,IAAIC,kBAAmBz6C,QAAQ61C,aAAawB,uBACxCqD,aAAa16C,QAAQ61C,aAAayB,qBAClCl0C;gBACI0F,SAAS0vC;gBACTnvC,OAAOkxC;;YAGf,IAAID,gBAAgB;gBAChB,IAAIG,iBAAiB;oBACjBz6C,QAAQigC,eAAez2B,SAASixC,iBAAiB,IAAIrlB,SAAShyB,MAAMtE,KAChE,SAAS67C;wBACLV,+BAA+BtmD,QAAQgnD;uBAE3C;wBACIV,+BAA+BpmD;wBAC/BhG,IAAI,0DAA0D4sD,iBAAiB;;uBAItF;oBACDR,+BAA+BpmD;;gBAGnC,IAAI6mD,YAAY;oBACZ16C,QAAQigC,eAAez2B,SAASkxC,YAAY,IAAItlB,SAAShyB,MAAMtE,KAC3D,SAAS67C;wBACLT,6BAA6BvmD,QAAQgnD;uBAEzC;wBACIT,6BAA6BrmD;wBAC7BhG,IAAI,kEAAkE6sD,YAAY;;uBAIzF;oBACDR,6BAA6BrmD;;;WAOzC+mD,oBAAoB,SAASb;YACzB,IAAIc,sBAAsB,IAAInzD,GAAG+L;YAEjCymD,6BAA6Bp7C,KAAK,SAAS4yB;gBACvCopB,4BAA4BppB,KAAKqoB;gBAEjC,KAAKA,UAAUvkB,KAAK;oBAChBukB,UAAUvkB,MAAM9D,IAAI8D;oBACpBukB,UAAUrmD,SAAS;wBACfqmD,UAAUrmD,SAAS;wBACnBqnD,KAAKhB;wBACLc,oBAAoBlnD;;uBAGvB;oBACDknD,oBAAoBlnD;;eAEzB;gBAIC/L,KAAKmyD;gBACLc,oBAAoBlnD;;YAGxB,OAAOknD;WAGXG,qBAAqB,SAASz4C,IAAIpP,MAAMiQ;YACpC,IAAI22C,YAAYkB,aAAa14C;YAE7B1U,IAAI,kCAAkC0U;YACtCpP,KAAK+nD,gBAAgB34C;YAErB,OAAOvC,QAAQigC,eAAez2B,SAASrW,MAAM4mD,WAAW32C,MAAMtE,KAC1D;gBACIu5C;gBACA0C,KAAKhB;gBACLC,kBAAkBz3C,IAAI5O;eAE1B;gBACIqmD,kBAAkBz3C,IAAI1O;gBAItB,KAAKmM,QAAQ61C,aAAauB,iBAAiB;oBACvC+D,+BAA+B54C,IAAIw3C;;;WAKnDqB,4BAA4B;YACxB,IAAI7C,qBAAqB9qD,QAAQ;gBAC7B6qD,+BAA+B;gBAE/B,IAAI+C,qBAAqB9C,qBAAqBn+C;gBAE9C,IAAIihD,mBAAmBC,QAAQ;oBAC3BC,kCAAkCF;uBAEjC;oBACDG,+BAA+BH;;mBAGlC;gBACD/C,+BAA+B;;WAIvCmD,YAAY,SAASl5C;YACjB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgB/wC;WAGtDi0C,cAAc,SAASp5C;YACnB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBc;WAGtDqC,YAAY,SAAS3zD;YACjB,OAAOyzD,cAAcnyC,WAAWkvC,gBAAgBxwD,OAAO;WAG3D4zD,YAAY,SAASt5C;YACjB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBe;WAGtDsC,oBAAoB;YAChB,OAAOJ,cAAcnyC,WAAWkvC,gBAAgBoB;WAGpDkC,cAAc,SAASx5C;YACnB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBkB;WAGtDrwC,UAAU,SAAS/G;YACf,OAAOy1C,UAAUG,IAAI51C,OAAO7a,GAAG8uB,UAAU3rB,gBAAgB4sD,oBAAoBl1C;WAGjF1I,cAAc,SAAS0I;YACnB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBnxC;WAGtD00C,WAAW,SAASz5C;YAChB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBx6C;WAGtDg+C,cAAc,SAAS15C;YAGnB,IAAIA,MAAM,MAAM;gBACZ,OAAOm5C,cAAcnyC,WAAWkvC,gBAAgBW,8BAC5CsC,cAAcnyC,WAAWkvC,gBAAgBY;;YAIjD,OAAOqC,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBU,yBAC9CuC,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBv6C;WAGnDg+C,WAAW,SAAS35C;YAChB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgB5sC;WAGtDvB,UAAU,SAAS/H;YACf,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBl1C;WAGtD44C,aAAa,SAAS55C;YAClB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBa;WAGtDoC,gBAAgB,SAAS9jD,SAASwkD;YAC9B,OAAOxkD,WAAWlQ,GAAGkQ,SAAS/M,gBAAgBuxD;WAGlDnB,eAAe,SAAS14C;YACpB,OAAO+3C,kBAAkBoB,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBsB;WAGxEnyD,OAAO,SAASwuC;YACZA,MAAM1uC,GAAG0uC,IAAIrsC,SAASiW,QAAQyR,QAAQ7pB;WAM1CkzD,8BAA8B,SAASxiC,aAAayhC;YAChD,IAAI/7B,WAAW1F,YAAYzwB,MAAMm2B,UAC7BD,YAAYzF,YAAYzwB,MAAMk2B;YAElC,IAAIA,aAAaC,aAAa+7B,UAAUlyD,MAAMm2B,aAAa+7B,UAAUlyD,MAAMk2B,WAAW;gBAClFr2B,GAAGqyD,WAAW/wD;oBACVg1B,UAAUA;oBACVD,WAAWA;;;WAQvBo9B,iCAAiC,SAAS54C,IAAIw3C;YAC1C,IAAIsC,aAAarC,kBAAkBz3C,OAAO,IAAI7a,GAAG+L,UAAUI,WACvDyoD,2BAA2B,IAAI50D,GAAG+L;YAEtCwmD,+BAA+Bn7C,KAAK,SAAS4yB;gBACzC2qB,WAAWv9C,KACP;oBACIw9C,yBAAyB3oD;mBAE7B;oBACImnD,4BAA4BppB,KAAKqoB;oBAEjCA,UAAUrmD,SAAS;wBACfqmD,UAAUrmD,SAAS;wBACnB4oD,yBAAyB3oD;;oBAG7BomD,UAAUvkB,MAAM9D,IAAI8D;oBACpBulB,KAAKhB;;;YAKjB,OAAOuC;WAWXC,sBAAsB;YAClB,IAAIC,UACAC,YACAC,cACAC,gBACAC,cACAC,eACAnT,UACAqQ,WACAF,gBACAiD,YACAC;YAEJlvD,IAAI;YAGJ,IAAImS,QAAQg3C,kBAAkB,MAAM;gBAChC,MAAM,IAAI9tD,MAAM;;YAIpB,IAAIxB,GAAGwH,SAAS8Q,QAAQg3C,iBAAiB;gBACrCwF,WAAWjrD,SAASg7B,eAAevsB,QAAQg3C;gBAE3C,IAAIwF,aAAa,MAAM;oBACnB,MAAM,IAAItzD,MAAMxB,GAAG8H,OAAO,2CAA2CwQ,QAAQg3C;;gBAGjFyF,aAAaD,SAASvlD;mBAErB;gBACD,IAAI+I,QAAQg3C,eAAe//C,cAAcpL,WAAW;oBAChD,MAAM,IAAI3C,MAAM,mEACZ;;gBAGRuzD,aAAaz8C,QAAQg3C,eAAe//C;;YAGxCwlD,aAAa/0D,GAAG0H,QAAQqtD;YACxBE,iBAAiBprD,SAASC,cAAc;YACxCmrD,eAAezjD,YAAYxR,GAAGoP,UAAU2lD;YACxCM,aAAar1D,GAAGi1D,gBAAgB9xD,gBAAgB4tD,gBAAgBO;YAIhE,IAAIh5C,QAAQoL,QAAQ;gBAChByxC,gBAAgBn1D,GAAGi1D,gBAAgB9xD,gBAAgB4tD,gBAAgBrtC;gBACnE,IAAIyxC,eAAe;oBACfn1D,GAAGm1D,eAAe/zD;;;YAS1B,KAAKpB,GAAGy/C,gBAAgBz/C,GAAGkT,kBAAkB+C,UAAU;gBACnDk8C,iBAAiBnyD,GAAGi1D,gBAAgB9xD,gBAAgB4tD,gBAAgBoB;gBACpE,IAAIA,gBAAgB;oBAChBnyD,GAAGmyD,gBAAgB/wD;;;YAI3B4gD,WAAWhiD,GAAGi1D,gBAAgB9xD,gBAAgB4tD,gBAAgBQ;YAI9D,IAAIvP,aAAahiD,GAAGy/C,aAAa;gBAC7Bt5C,IAAI,2BAA2B;gBAC/BnG,GAAGgiD,UAAU5gD;;YAGjB,KAAKpB,GAAGkT,kBAAkB+C,UAAU;gBAEhCo/C,WAAWp7C,gBAAgBk2C;gBAE3B,IAAInO,YAAYhiD,GAAGgiD,UAAUl+C,aAAaosD,qBAAqB;oBAI3DlwD,GAAGgiD,UAAU1gD;wBACTlB,SAAS;;;mBAIhB,IAAIJ,GAAGq1D,YAAYvxD,aAAaqsD,wBAAwBnO,UAAU;gBACnEoT,aAAap1D,GAAGgiD,UAAU7+C,gBAAgB4tD,gBAAgBmB;gBAC1DkD,cAAcp1D,GAAGo1D,YAAYh0D;;YAKjCixD,YAAYryD,GAAGi1D,gBAAgB9xD,gBAAgB4tD,gBAAgBsB;YAC/D,KAAKO,gBAAgB;gBACjBP,aAAaryD,GAAGqyD,WAAWjxD;mBAE1B,IAAIixD,WAAW;gBAChBvB,mBAAmB9uB,SAASqwB,UAAUnuD,aAAa8rD;gBAEnDc,mBAAmBA,mBAAmB,IAAIA,mBAAmB;gBAE7D+B,cAAc7yD,GAAGqyD,WAAWvuD,aAAamsD;;YAE7C2C,iBAAiBA,kBAAkBP;YAEnCI,sBAAsBzyD,GAAGi1D,gBAAgBzyD,WAAWuuD,gBAAgBiB,mBAAmBjsD,SAAS;YAChG2sD,sBAAsB1yD,GAAGi1D,gBAAgBzyD,WAAWuuD,gBAAgB5sC,OAAOpe,SAAS;YAEpFivD,eAAeh1D,GAAGi1D,gBAAgB9xD,gBAAgB4tD,gBAAgBS;YAElE,IAAIwD,gBAAgB,MAAM;gBACtB,MAAM,IAAIxzD,MAAM;;YAGpB0zD,eAAeF,aAAazlD;YAC5BylD,aAAazlD,YAAY;YAGzB,IAAI0lD,eAAenyD,qBAAqB,UAAUiD,QAAQ;gBACtD8D,SAASC,cAAc;;YAG3B3D,IAAI;YAEJ;gBACIooD,UAAUvuD,GAAG0H,QAAQutD,eAAe1lD;gBACpC+lD,cAAct1D,GAAG0H,QAAQwtD;;WAIjCK,cAAc,SAAS7mB,IAAIrzB,OAAOyT;YAC9B,IAAI0mC,WAAW1mC,UACX2mC,WAAWD,SAASlyD;YAExB,IAAI+X,QAAQ,GAAG;gBACXo6C,WAAWz1D,GAAGw1D,UAAUpyD,WAAWiY,OAAO7X;;YAI9CgyD,SAASv0D,aAAaytC,IAAI+mB;WAG9B3B,iCAAiC,SAASH;YACtC,IAAI94C,KAAK84C,mBAAmB94C,IACxB66C,gBAAgB/B,mBAAmB+B,eACnCC,qBAAqBD,iBAAiBA,cAAclC,eACpDnB,YAAYkB,aAAa14C,KACzBa;gBACI4F,sBAAsBqyC,mBAAmBryC;gBACzCF,SAAS0vC;gBACTv4B,QAAQ;gBACR5W,OAAO;;YAGf,IAAI3hB,GAAGkT,kBAAkBkD,eAAe;gBACpC,IAAIi8C,WAAW;oBACX,IAAI/5C,QAAQg8B,OAAOmb,aAAan3C,QAAQg8B,OAAOmb,aAAakB,qBAAqB;wBAC7E8C,+BAA+B54C,IAAIw3C;wBACnCqB;2BAEC;wBACDR,kBAAkBb,WAAWx6C,KAAK;4BAC9By6C,kBAAkBz3C,MAAM,IAAI7a,GAAG+L;4BAE/BumD,kBAAkBz3C,IAAIhD,KAAK;gCACvByR,WAAWoqC,2BAA2Bp7C,QAAQg8B,OAAOya;;4BAMzD,IAAI4G,sBAAsB,MAAM;gCAC5BC,iBAAiB/6C,IAAI86C;mCAEpB;gCACDrC,mBAAmBz4C,IAAI66C,eAAeh6C;;;;uBAMjD;oBACDg4C;;mBAGH,IAAIrB,WAAW;gBAChBa,kBAAkBb;gBAClBqB;;WAIRG,oCAAoC,SAASF;YACzC,IAAI94C,KAAK84C,mBAAmB94C,IACxBqL,eAAeytC,mBAAmBztC,cAClC2vC,iBAAiBlC,mBAAmBkC,gBACpCxD,YAAYkB,aAAa14C,KACzBa;gBACI4F,sBAAsBqyC,mBAAmBryC;gBACzCK,OAAOkxC;gBACPzxC,SAAS0vC;;YAGjB,IAAIuB,WAAW;gBACX,IAAInsC,cAAc;oBACd,IAAI5N,QAAQg8B,OAAOmb,aAAan3C,QAAQg8B,OAAOmb,aAAakB,qBAAqB;wBAC7E8C,+BAA+B54C,IAAIw3C;wBACnCqB;2BAEC;wBACD,IAAImC,gBAAgB;4BAChB3C,kBAAkBb;;wBAGtB,OAAO/5C,QAAQigC,eAAez2B,SAASoE,cAAcmsC,WAAW32C,MAAMtE,KAClE;4BACIi8C,KAAKhB;4BACL1B;4BACArnC,WAAWoqC,2BAA2Bp7C,QAAQg8B,OAAOya;2BAGzD;4BACI0E,+BAA+B54C,IAAIw3C;4BACnC/oC,WAAWoqC,2BAA2Bp7C,QAAQg8B,OAAOya;;;uBAKhE;oBACD0E,+BAA+B54C,IAAIw3C;oBACnCqB;;;WAKZoC,sBAAsB,SAASj7C,IAAIk7C;YAC/B,IAAIC,MAAMzB,YAAY15C,KAElBo7C,sBAAsBp7C,MAAM,OAAOk2C,gBAAgBY,mBAAmBZ,gBAAgBv6C;YAE1F,IAAIw/C,QAAQh2D,GAAGg2D,KAAKl0D,SAASm0D,sBAAsB;gBAC/CD,MAAMh2D,GAAGg2D,KAAK7yD,gBAAgB8yD;;YAGlC,IAAID,KAAK;gBACLh2D,GAAGg2D,KAAK10D;oBAAKgpC,OAAOyrB,UAAU;;gBAC9BC,IAAIzkD,aAAa,iBAAiBwkD;;WAI1C1C,OAAO,SAAS3kB;YACZA,MAAM1uC,GAAG0uC,IAAIpsC,YAAYgW,QAAQyR,QAAQ7pB;WAG7C01D,mBAAmB,SAASM,mBAAmBC;YAC3C,IAAIC,kBAAkB7C,aAAa2C,oBAC/BG,kBAAkB9C,aAAa4C;YAEnChwD,IAAInG,GAAG8H,OAAO,sFAAsFouD,mBAAmBC,mBAAmBA;YAG1I7D,kBAAkB6D,mBAAmB/+C,KAAK;gBACtCu5C;gBACA2B,kBAAkB4D,mBAAmBjqD;gBACrC9F,IAAInG,GAAG8H,OAAO,wEAAwEquD,mBAAmBD;gBACzGE,gBAAgBtoB,MAAMuoB,gBAAgBvoB;gBACtCulB,KAAK+C;eAET;gBACI9D,kBAAkB4D,mBAAmB/pD;gBACrC,KAAKmM,QAAQ61C,aAAauB,iBAAiB;oBACvC+D,+BAA+ByC,mBAAmBE;;;;QAKlEp2D,GAAG6B,OAAOyW,SAASoD;QACnBvV,MAAMmS,QAAQnS;QAId,KAAKnG,GAAGkT,kBAAkBkD,eAAe;YACrCkC,QAAQg8B,OAAOya,oBAAoB;YACnCz2C,QAAQg8B,OAAOmb,YAAY;;QAG/B5tC,YAAYvJ,QAAQi3C;QACpBqD,iBAAiBt6C,QAAQigC,mBAAmBp0C;QAC5CwuD,eAAekC;QAEf/B;QAEA9yD,GAAG6B,OAAOxB;YACN4tC,QAAQ;gBACJ9nC,IAAI;gBAEJwqD,sBAAsB;gBAEtB9uC,UAAUtS,YAAYojD,aAAapE;gBACnCruD,KAAKk0D;gBACL/zD,KAAKi2D;gBACLxnC,WAAWxW,QAAQk3C,mBAAmBwE,cAAcnyC,WAAWkvC,gBAAgBS;gBAE/ErrD,IAAI;;YAGR0pD,eAAe,SAASzpD;gBACpB,IAAImwD,eAAev2D,GAAGoP,UAAUhJ;gBAChCyb,UAAUtS,YAAY;gBACtBsS,UAAUrQ,YAAY+kD;;YAG1Bp8C,OAAO;gBACH9Z,KAAK4tC;;YAGTkX,YAAY;gBACRr2B,SAASvf,YAAY;;YAGzBk9C,eAAe;gBACXiE,mBAAmB;;YAGvBj1C,SAAS,SAASZ,IAAI9Y,MAAMy0D,aAAaC,aAAaC;gBAClD,IAAIC,SAAS32D,GAAGoP,UAAUujD,aAAa2C,eACnCsB,aAAa5C,cAAc2C,QAAQ5F,gBAAgBnxC,OACnDy1C,aAAarB,cAAcnyC,WAAWkvC,gBAAgBO,WACtDxxC,gBAAgB42C,QAAQpG,UAAUC,UAAUzhC,UAC5C+nC;gBAEJ,IAAIH,OAAO;oBACPpG,UAAUG,IAAI51C,MAAM87C;;gBAGxB32D,GAAG22D,QAAQt0D,SAAS0tD,oBAAoBl1C;gBACxCw6C,WAAWp7C,gBAAgBk2C;gBAE3B,IAAIyG,YAAY;oBACZ52D,GAAG42D,YAAYnzD,QAAQ1B;oBACvB60D,WAAWrlD,aAAa,SAASxP;;gBAGrC40D,OAAOplD,aAAau+C,cAAcj1C;gBAElC,IAAI27C,aAAa;oBACbjB,YAAYoB,QAAQH,YAAYn7C,OAAOyE;uBAEtC;oBACDA,cAActO,YAAYmlD;;gBAG9B,IAAIF,aAAa;oBACbE,OAAOx2D,MAAMC,UAAU;oBACvBJ,GAAG22D,QAAQt0D,SAASguD;uBAEnB;oBACDnwD,KAAKq0D,YAAY15C;oBACjB3a,KAAK0iB,QAAQ/H;oBACb3a,KAAKi0D,UAAUt5C;oBACf3a,KAAKs0D,SAAS35C;oBACd3a,KAAKo0D,SAASz5C;oBACd3a,KAAK+zD,YAAYp5C;oBAEjB,IAAI61C,kBAAkB;wBAClBrwD,KAAK4pD,WAAWpvC;;oBAGpBg8C,QAAQtD,aAAa14C;oBACrB,IAAIg8C,UAAUA,MAAM/oB,KAAK;wBACrB0kB,6BAA6Bp7C,KAAK,SAAS0/C;4BACvCD,MAAM/oB,MAAMgpB,WAAWhpB;4BACvB,IAAIgpB,WAAW32D,MAAMk2B,aAAaygC,WAAW32D,MAAMm2B,UAAU;gCACzDt2B,GAAG62D,OAAOv1D;oCACN+0B,WAAWygC,WAAW32D,MAAMk2B;oCAC5BC,UAAUwgC,WAAW32D,MAAMm2B;;;4BAInC+8B,KAAKwD;;;;;YAMrBjK,gBAAgB,SAAS/xC,IAAI9Y,MAAMy0D,aAAaC;gBAC5Cp2D,KAAKob,QAAQZ,IAAI9Y,MAAMy0D,aAAaC,aAAa;;YAGrDvR,eAAe;gBACXp2B,SAAStd,YAAY8+C,UAAUC;gBAC/BD,UAAUC,UAAU1mD,SAAS2mD;gBAC7BF,UAAUG;;YAGd/J,YAAY,SAAS7rC;gBACjB7a,GAAG4hB,QAAQ/G,KAAKzZ;;YAGpBilD,WAAW,SAAS3X;gBAChB,IAAIqoB,cAAcroB;gBAElB,IAAIqoB,aAAa;oBAEb,OAAOA,YAAY7yD,aAAa4rD,iBAAiB,MAAM;wBACnDiH,cAAcA,YAAY51D;;oBAG9B,OAAO6gC,SAAS+0B,YAAY7yD,aAAa4rD;;;YAIjDkH,aAAa;gBACT,OAAOloC;;YAGXq6B,sBAAsB,SAAStuC;gBAC3B,IAAI9I,WAAWI,YAAY0I;gBAE3B9I,YAAY/R,GAAG+R,UAAU1P,SAASiW,QAAQyR,QAAQykC;;YAGtDzI,gBAAgB,SAASlrC,IAAI9Y;gBACzB,IAAIk1D,aAAa9kD,YAAY0I;gBAE7B,IAAIo8C,YAAY;oBACZj3D,GAAGi3D,YAAYxzD,QAAQ1B;oBACvBk1D,WAAW1lD,aAAa,SAASxP;;;YAIzCgnD,cAAc,SAASluC;gBACnB3a,KAAKiS,YAAY0I;;YAGrBouC,cAAc,SAASpuC;gBACnBw4C,KAAKlhD,YAAY0I;;YAGrBq8C,YAAY,SAASxoB;gBACjB,OAAO1uC,GAAG0uC,IAAI5sC,SAASivD,gBAAgBnxC;;YAG3CqC,WAAW;gBACP,OAAO3J,QAAQoL,UAAUswC,cAAcnyC,WAAWkvC,gBAAgBrtC;;YAGtEkkC,oBAAoB;gBAChB1nD,KAAKk0D;;YAGTzM,oBAAoB;gBAChB0L,KAAKe;;YAGT1M,aAAa;gBACT,OAAOsM,cAAcnyC,WAAWkvC,gBAAgBQ;;YAGpDnJ,wBAAwB;gBACpB,OAAOqK;;YAGXrJ,WAAW,SAASvuC;gBAChB3a,KAAKs0D,SAAS35C;;YAGlB6vC,iBAAiB;gBACb,OAAOgI;;YAGX/H,WAAW,SAAS9vC;gBAChBw4C,KAAKmB,SAAS35C;;YAGlB4qC,kBAAkB,SAAS5qC;gBACvB,OAAO+G,QAAQ/G;;YAGnBquC,cAAc,SAASruC;gBACnB,IAAIs8C,OAAO9C,YAAYx5C;gBAEvBs8C,QAAQn3D,GAAGm3D,MAAM90D,SAASiW,QAAQyR,QAAQykC;;YAG9ChJ,iBAAiB,SAAS3qC;gBACtB,OAAO7a,GAAG4hB,QAAQ/G,KAAK/Y,SAASuuD;;YAGpCrH,cAAc,SAASnuC;gBACnB,IAAIs8C,OAAO9C,YAAYx5C;gBAEvBs8C,QAAQn3D,GAAGm3D,MAAM70D,YAAYgW,QAAQyR,QAAQykC;;YAGjD4I,YAAY,SAAS1oB;gBACjB,OAAO1uC,GAAG0uC,IAAI5sC,SAASivD,gBAAgBkB,cAAc;;YAGzDpJ,cAAc,SAAShuC;gBACnB,OAAOm5C,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBiB;;YAGtDqF,aAAa,SAAS3oB;gBAClB,OAAO1uC,GAAG0uC,IAAI5sC,SAASivD,gBAAgBiB,mBAAmB;;YAG9DhI,gBAAgB,SAASnvC,IAAIiQ,QAAQC;gBACjC,IAAIirC,MAAMzB,YAAY15C,KAClBk7C;gBAEJ,IAAIC,OAAOjrC,QAAQ,GAAG;oBAClBgrC,UAAUp0D,KAAKC,MAAMkpB,SAASC,QAAQ;oBAEtC,IAAIgrC,YAAY,KAAK;wBACjB71D,KAAK81D;2BAEJ;wBACD3C,KAAK2C;;oBAGTF,oBAAoBj7C,IAAIk7C;;;YAIhC7Z,qBAAqB,SAASpxB,QAAQC;gBAClC1qB,KAAK2pD,eAAe,MAAMl/B,QAAQC;;YAGtCm/B,cAAc,SAASrvC;gBACnB,IAAIm7C,MAAMzB,YAAY15C;gBAEtBm7C,OAAO91D,KAAK81D;;YAGhBM,mBAAmB;gBACfj2D,KAAK6pD;;YAGTsB,eAAe,SAAS3wC;gBACpBi7C,oBAAoBj7C,IAAI;gBACxBxa,KAAKi2D,kBAAkBz7C;;YAG3B8uC,oBAAoB;gBAChBtpD,KAAKmrD;;YAGTf,YAAY,SAAS5vC;gBACjB,KAAK61C,kBAAkB;oBACnB,IAAI1wC,SAAS+zC,UAAUl5C;oBAEvBmF,UAAUhgB,GAAGggB,QAAQ1d,YAAYgW,QAAQyR,QAAQ7pB;;;YAIzD+pD,YAAY,SAASpvC;gBACjB3a,KAAK6zD,UAAUl5C;;YAGnBy8C,UAAU,SAAS5oB;gBACf,OAAO1uC,GAAG0uC,IAAI5sC,SAASivD,gBAAgB/wC,QAAQ;;YAGnDirC,YAAY,SAASpwC;gBACjBw4C,KAAKiB,SAASz5C;gBACd3a,KAAK+zD,YAAYp5C;;YAGrBmrC,cAAc,SAASnrC;gBACnBxa,KAAKgpD,cAAcxuC,IAAIvC,QAAQ5U,KAAK0jC;gBACpC/mC,KAAKk3D,oBAAoB18C;gBACzB3a,KAAKu0D,WAAW55C;;YAGpB2uC,WAAW,SAAS3uC;gBAChB3a,KAAKo0D,SAASz5C;;YAGlB28C,SAAS,SAAS9oB;gBACd,OAAO1uC,GAAG0uC,IAAI5sC,SAASivD,gBAAgBx6C,OAAO;;YAGlDkhD,kBAAkB,SAAS/oB;gBACvB,OAAO1uC,GAAG0uC,IAAI5sC,SAASivD,gBAAgBc,gBAAgB;;YAG3D0F,qBAAqB,SAAS18C;gBAC1Bw4C,KAAKY,YAAYp5C;gBACjB3a,KAAKo0D,SAASz5C;;YAGlBqrC,iBAAiB,SAASrrC;gBACtBxa,KAAKgpD,cAAcxuC,IAAI;gBACvBxa,KAAK4qD,WAAWpwC;gBAChBw4C,KAAKoB,WAAW55C;;YAGpBiwC,kBAAkB,SAASjwC;gBACvBw4C,KAAKc,UAAUt5C;;YAGnBixC,kBAAkB,SAASjxC;gBACvB3a,KAAKi0D,UAAUt5C;;YAGnB68C,gBAAgB,SAAShpB;gBACrB,OAAO1uC,GAAG0uC,IAAI5sC,SAASivD,gBAAgBe,cAAc;;YAGzD6F,SAAS,SAASjpB;gBACd,OAAO1uC,GAAG0uC,IAAI5sC,SAASivD,gBAAgB5sC,OAAO;;YAGlDtH,YAAY,SAAShC,IAAInX;gBACrB,IAAImY,OAAO+G,QAAQ/H;gBAEnB,IAAIgB,MAAM;oBACNw3C,KAAKx3C;oBACL7b,GAAG6b,MAAMpY,QAAQC;;;YAIzB2lD,eAAe,SAASxuC,IAAInX;gBACxB,IAAIk0D,SAAS5D,cAAcpyC,QAAQ/G,KAAKk2C,gBAAgBgB;gBAExD,IAAI6F,QAAQ;oBAER,IAAIl0D,QAAQ,MAAM;wBACd1D,GAAG43D,QAAQ/zD;2BAEV;wBACD7D,GAAG43D,QAAQn0D,QAAQC;;;;YAK/BgmD,aAAa,SAAS7uC;gBAClB7a,GAAG4hB,QAAQ/G,KAAKvY,YAAY8tD;gBAC5BlwD,KAAKu0D,WAAW55C;;YAGpBmwC,aAAa,SAASnwC;gBAClB7a,GAAG4hB,QAAQ/G,KAAKxY,SAAS+tD;gBACzBiD,KAAKoB,WAAW55C;;YAGpBkyC,iBAAiB,SAASlyC,IAAI66C,eAAep0C;gBACzC,KAAKjhB,KAAKmlD,gBAAgB3qC,KAAK;oBAC3Bg2C,qBAAqB3tD;wBAAM2X,IAAIA;wBAAIyG,sBAAsBA;wBAAsBo0C,eAAeA;;qBAC7F9E,gCAAgC8C;;;YAIzC7G,iBAAiB,SAAShyC,IAAIqL,cAAc2vC,gBAAgBv0C;gBACxD,KAAKjhB,KAAKmlD,gBAAgB3qC,KAAK;oBAC3Bg2C,qBAAqB3tD;wBAAMoe,sBAAsBA;wBAAsBsyC,QAAQ;wBAAM/4C,IAAIA;wBAAIqL,cAAcA;wBAAc2vC,gBAAgBA;;qBACxIjF,gCAAgC8C;;;YAIzC1E,WAAW,SAASzuD;gBAChB,OAAOP,GAAGkT,kBAAkB6C,mBAAmBm+C,UAAU3zD;;YAG7D0uD,YAAY,SAAS1uD,MAAM6F,SAAS+oD;gBAChC,IAAI0I,SAAS3D,UAAU3zD,OACnBu3D,YAAY9D,cAAc6D,QAAQ9G,gBAAgBI,gBAClD4G,UAAUF,OAAO/0D,qBAAqB,SAAS,IAC/Ck1D,YAAYhE,cAAc6D,QAAQ9G,gBAAgBE,qBAClDgH,QAAQjE,cAAc6D,QAAQ9G,gBAAgBK,iBAC9CtlD,UAAU,IAAI9L,GAAG+L,WAEjBmsD,eAAe;oBACXF,UAAUp3D,oBAAoB,SAASu3D;oBACvCF,SAASA,MAAMr3D,oBAAoB,SAASw3D;oBAC5CtsD,QAAQK;mBAGZgsD,qBAAqB;oBACjBH,UAAUp3D,oBAAoB,SAASu3D;oBACvCN,OAAOQ;mBAGXD,iBAAiB;oBACbP,OAAOj3D,oBAAoB,SAASs3D;oBACpCD,MAAMr3D,oBAAoB,SAASw3D;oBACnCP,OAAOQ;oBAEPvsD,QAAQG,QAAQ8rD,WAAWA,QAAQhxD;;gBAG3C8wD,OAAOp3D,iBAAiB,SAASy3D;gBACjCF,UAAUv3D,iBAAiB,SAAS03D;gBACpCF,SAASA,MAAMx3D,iBAAiB,SAAS23D;gBAEzC,IAAIL,SAAS;oBACTA,QAAQhxD,QAAQooD;;gBAEpB2I,UAAUl0D,cAAcwC;gBAExByxD,OAAOS;gBAEP,OAAOxsD;;;;IC/gCnB9L,GAAGu4D,iBAAiB,SAASC,GAAGC;QAC5B;QAEA,IAAIhmD,WAAW,IAAIzS,GAAGsS,kBAClBoJ;YACIg9C,WAAW;YACXC,UAAU;YACVC,WAAW,SAASnsD,QAAQ2nB;;QAKpCp0B,GAAG6B,OAAOxB;YACN0pD,YAAY,SAAS9pD;gBACjB8pD,WAAW9pD;;YAGfuS,SAAS;gBACLC,SAASD;;;QAIjB,SAASu3C,WAAW9pD;YAChBwS,SAASnS,OAAOL,SAASyb,KAAKg9C,WAAW,SAAStkC;gBAE9CA,QAAQA,SAASpvB,OAAOovB;gBAGxB,IAAI3nB,SAAS2nB,MAAM3nB,UAAU2nB,MAAMykC;gBAEnCn9C,KAAKk9C,UAAUnsD,QAAQ2nB;;;QAK/Bp0B,GAAG6B,OAAO42D;YACNK,mBAAmB,SAASxxD;gBACxB,OAAOA,KAAKyxD;;YAGhBC,mBAAmB;gBACf,OAAOvmD;;;QAIfzS,GAAG6B,OAAO6Z,MAAM88C;QAEhB,IAAI98C,KAAKi9C,UAAU;YACf5O,WAAWruC,KAAKi9C;;;IClDxB34D,GAAG4mD,0BAA0B,SAAS4R;QAClC;QAEA,IAAIS,2BACAv9C;YACI8rC,YAAY;YACZrhD,KAAK,SAASC,SAAS0hD;YACvBC,cAAc,SAAS7mC;YACvBiK,UAAU,SAASjK;YACnB8mC,SAAS,SAAS9mC;YAClB+mC,SAAS,SAAS/mC;YAClBgnC,YAAY,SAAShnC;YACrBinC,WAAW,SAASjnC;WAExBg4C;YACIl5C,QAAQ,SAASnF;gBAAMa,KAAKyP,SAAStQ;;YACrCsJ,OAAQ,SAAStJ;gBAAMa,KAAKssC,QAAQntC;;YACpCi3C,cAAc,SAASj3C;gBAAMa,KAAKqsC,aAAaltC;;YAC/CtE,OAAO,SAASsE;gBAAMa,KAAKusC,QAAQptC;;YACnCg3C,gBAAgB,SAASh3C;gBAAMa,KAAKwsC,WAAWrtC;;;QAGvD,SAASs+C,aAAa1sD,QAAQ2nB;YAC1Bp0B,GAAG+C,KAAKm2D,gBAAgB,SAASE,YAAY3qC;gBACzC,IAAI4qC,2BAA2BD,WAAWrpD,OAAO,GAAG8W,gBAAgBuyC,WAAWlxD,MAAM,IACjFgZ;gBAEJ,IAAIxF,KAAK8rC,WAAW,OAAO6R,0BAA0B5sD,SAAS;oBAC1DyU,SAASxF,KAAK8rC,WAAWnB,UAAU55C;oBACnCzM,GAAGiP,eAAemlB;oBAClB1Y,KAAKvV,IAAInG,GAAG8H,OAAO,gEAAgE4T,KAAKysC,UAAUjnC,SAASA;oBAC3GuN,QAAQvN;oBACR,OAAO;;;;QAKnBlhB,GAAG6B,OAAO6Z,MAAM88C;QAEhB98C,KAAKg9C,YAAY;QACjBh9C,KAAKk9C,YAAYO;QACjBz9C,KAAKi9C,WAAWj9C,KAAK8rC,WAAWwP;QAEhCh3D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGu4D,eAAe78C,MAAMu9C;;IC1ChDj5D,GAAGqoD,uBAAuB,SAASmQ;QAC/B;QAEA,IAAIS,2BACAv9C;YACI8rC,YAAY;YACZrhD,KAAK,SAASC,SAAS0hD;YACvB/9B;gBACInK,MAAM;gBACNqyC,cAAc;;YAElBzJ,mBAAmB,SAAStnC;YAC5BinC,WAAW,SAASjnC;;QAG5BlhB,GAAG6B,OAAO6Z,MAAM88C;QAGhB,SAASW,aAAa1sD,QAAQ2nB;YAC1B,IAAI1Y,KAAK8rC,WAAW0P,WAAWzqD,WAAWiP,KAAK8rC,WAAW4P,WAAW3qD,SAAS;gBAC1E,IAAIyU,SAASxF,KAAK8rC,WAAWnB,UAAU55C,SACnCyO,SAASQ,KAAK8sC,kBAAkBtnC;gBAGpC,IAAIhG,WAAWlb,GAAGkb,OAAOkC,WAAW;oBAChC1B,KAAKvV,IAAInG,GAAG8H,OAAO,6DAA6D4T,KAAKysC,UAAUjnC,SAASA;oBACxGlhB,GAAGiP,eAAemlB;oBAElB6kC,qBAAqBK,mBAAmBp4C,QAAQzU,QAAQ;;;;QAKpEiP,KAAKg9C,YAAY;QACjBh9C,KAAKk9C,YAAYO;QAEjBn5D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGu5D,oBAAoB79C,MAAMu9C;;ICpCrDj5D,GAAGypD,8BAA8B,SAAS+O,GAAGS;QACzC;QAEA,IAAIv9C;YACI8rC,YAAY;YACZgB,mBAAmB,SAAStnC;YAC5B/a,KAAK,SAASC,SAAS0hD;;QAG/B,KAAKmR,sBAAsB;YACvBA;;QAIJ,SAASO,iBAAiB/sD,QAAQ2nB;YAC9B,IAAI1Y,KAAK8rC,WAAW6P,YAAY5qD,SAAS;gBACrC,IAAIyU,SAASxF,KAAK8rC,WAAWnB,UAAU55C,SACnCyO,SAASQ,KAAK8sC,kBAAkBtnC;gBAEpC,IAAIhG,WAAWlb,GAAGkb,OAAOkC,WAAW;oBAChC1B,KAAKvV,IAAInG,GAAG8H,OAAO,mEAAmE4T,KAAKysC,UAAUjnC,SAASA;oBAC9G+3C,qBAAqBK,mBAAmBp4C,QAAQzU;;;;QAK5DiP,KAAKg9C,YAAY;QACjBh9C,KAAKk9C,YAAYY;QAEjBx5D,GAAG6B,OAAO6Z,MAAM88C;QAChBx4D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGu5D,oBAAoB79C,MAAMu9C;;ICzBrDj5D,GAAGsoD,4BAA4B,SAAS5sC;QACpC;QAEAA,KAAKg9C,YAAY;QACjBh9C,KAAKi9C,WAAW;QAEhB34D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGypD,4BAA4B/tC;;ICVvD1b,GAAGu5D,sBAAsB,SAASf,GAAGS;QACjC;QAEA,IAAIv9C;YACI8rC,YAAY;YACZrhD,KAAK,SAASC,SAAS0hD;YACvBU,mBAAmB,SAAStnC;YAC5BinC,WAAW,SAASjnC;YACpBunC,WAAW,SAASvnC,QAAQtE;YAC5B8rC,uBAAuB,SAASxnC,QAAQynC;;QAGhD,SAAS8Q,yBAAyBv4C;YAC9B,IAAIw4C,kBAAkBh+C,KAAKysC,UAAUjnC,SACjClP,SAAS0nD,gBAAgBznD,YAAY;YAEzC,IAAID,SAAS,GAAG;gBACZ0nD,kBAAkBA,gBAAgBxnD,OAAO,GAAGF;;YAGhD,OAAO0nD;;QAGX,SAASC,qBAAqBz4C;YAC1B,IAAI04C,WAAWl+C,KAAKysC,UAAUjnC;YAC9B,OAAOlhB,GAAG8R,aAAa8nD;;QAI3B,SAASC,iBAAiBC,oBAAoB54C;YAC1C,IAAItE,UAAUk9C,mBAAmB/yD,OAC7BgzD;YAEJ,IAAIn9C,YAAYzY,aAAanE,GAAG0H,QAAQkV,SAAS7W,SAAS,GAAG;gBACzDg0D,gBAAgBJ,qBAAqBz4C;gBAErC,IAAI64C,kBAAkB51D,WAAW;oBAC7ByY,UAAUA,UAAU,MAAMm9C;;gBAG9Br+C,KAAK+sC,UAAUvnC,QAAQtE;;YAG3BlB,KAAKgtC,sBAAsBxnC,QAAQ;;QAIvC,SAAS84C,yBAAyBjC,SAAS72C;YACvC+3C,qBAAqBD,oBAAoB14D,OAAOy3D,SAAS,QAAQ;gBAC7D8B,iBAAiB9B,SAAS72C;;;QAKlC,SAAS+4C,6BAA6BlC,SAAS72C;YAC3C+3C,qBAAqBD,oBAAoB14D,OAAOy3D,SAAS,SAAS,SAAS3jC;gBAEvE,IAAIpE,OAAOoE,MAAM8lC,WAAW9lC,MAAM+lC;gBAElC,IAAInqC,SAAS,IAAI;oBACb6pC,iBAAiB9B,SAAS72C;;;;QAKtClhB,GAAG6B,OAAO6Z,MAAM88C;QAEhB98C,KAAKi9C,WAAWj9C,KAAK8rC,WAAWwP;QAEhCh3D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGu4D,eAAe78C,MAAMu9C;QAE5Cj5D,GAAG6B,OAAOo3D;YACNK,oBAAoB,SAASz+C,IAAIpO,QAAQ2tD;gBACrC,IAAIN,qBAAqBp+C,KAAK8rC,WAAWqB,aAAahuC;gBAEtDa,KAAKgtC,sBAAsB7tC,IAAI;gBAE/Bi/C,mBAAmB/yD,QAAQ0yD,yBAAyB5+C;gBAEpD,IAAIu/C,YAAY;oBACZN,mBAAmBO;;gBAGvBL,yBAAyBF,oBAAoBj/C;gBAC7Co/C,6BAA6BH,oBAAoBj/C;;;;G3CvF9B7V","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
@@ -592,6 +592,10 @@ class SeedDMS_Extension_Mgr { return false; } } + if(!$file) { + $this->errmsgs[] = 'Extension list is empty'; + return false; + } file_put_contents($this->cachedir."/".self::repos_list_file, $file); } else { return false; diff --git a/inc/inc.ClassSchedulerTask.php b/inc/inc.ClassSchedulerTask.php index 45017dbc3..f9caf2af2 100644 --- a/inc/inc.ClassSchedulerTask.php +++ b/inc/inc.ClassSchedulerTask.php @@ -232,14 +232,14 @@ class SeedDMS_SchedulerTask { if (!$res) return false; - $this->_disabled = $newDisable; + $this->_disabled = $newDisabled; return true; } /* }}} */ public function setParameter($newParams) { /* {{{ */ $db = $this->db; - $queryStr = "UPDATE `tblSchedulerTask` SET `parameter` =".json_encode($newParams)." WHERE `id` = " . $this->_id; + $queryStr = "UPDATE `tblSchedulerTask` SET `params` =".$db->qstr(json_encode($newParams))." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -248,7 +248,9 @@ class SeedDMS_SchedulerTask { return true; } /* }}} */ - public function getParameter() { + public function getParameter($name = '') { + if($name) + return isset($this->_params[$name]) ? $this->_params[$name] : null; return $this->_params; } @@ -275,4 +277,21 @@ class SeedDMS_SchedulerTask { $this->_lastrun = $lastrun; $this->_nextrun = $nextrun; } + + /** + * Delete task + * + * @return boolean true on success or false in case of an error + */ + function remove() { /* {{{ */ + $db = $this->db; + + $queryStr = "DELETE FROM `tblSchedulerTask` WHERE `id` = " . $this->_id; + if (!$db->getResult($queryStr)) { + return false; + } + + return true; + } /* }}} */ + } diff --git a/inc/inc.ClassSchedulerTaskBase.php b/inc/inc.ClassSchedulerTaskBase.php index c190096a9..c51c0c0e7 100644 --- a/inc/inc.ClassSchedulerTaskBase.php +++ b/inc/inc.ClassSchedulerTaskBase.php @@ -29,7 +29,7 @@ * @package SeedDMS */ class SeedDMS_SchedulerTaskBase { - public function execute($task, $dms) { + public function execute($task, $dms, $user) { return true; } } diff --git a/inc/inc.ClassSession.php b/inc/inc.ClassSession.php index 8dcc92283..78f796a0b 100644 --- a/inc/inc.ClassSession.php +++ b/inc/inc.ClassSession.php @@ -294,7 +294,7 @@ class SeedDMS_Session { function addToClipboard($object) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $dms = $object->_dms; + $dms = $object->getDMS(); if($object->isType('document')) { if(!in_array($object->getID(), $this->data['clipboard']['docs'])) array_push($this->data['clipboard']['docs'], $object->getID()); @@ -317,7 +317,7 @@ class SeedDMS_Session { function removeFromClipboard($object) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $dms = $object->_dms; + $dms = $object->getDMS(); if($object->isType('document')) { $key = array_search($object->getID(), $this->data['clipboard']['docs']); if($key !== false) diff --git a/inc/inc.ClassUI.php b/inc/inc.ClassUI.php index 13abf3274..7beab4283 100644 --- a/inc/inc.ClassUI.php +++ b/inc/inc.ClassUI.php @@ -137,8 +137,8 @@ class UI extends UI_Default { $view->setParam('enablesessionlist', $settings->_enableSessionList); $view->setParam('workflowmode', $settings->_workflowMode); $view->setParam('checkoutdir', $settings->_checkOutDir); - $view->setParam('partitionsize', (int) $settings->_partitionSize); - $view->setParam('maxuploadsize', (int) $settings->_maxUploadSize); + $view->setParam('partitionsize', SeedDMS_Core_File::parse_filesize( $settings->_partitionSize)); + $view->setParam('maxuploadsize', SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize)); $view->setParam('showmissingtranslations', $settings->_showMissingTranslations); $view->setParam('defaultsearchmethod', $settings->_defaultSearchMethod); $view->setParam('cachedir', $settings->_cacheDir); diff --git a/inc/inc.ClassViewCommon.php b/inc/inc.ClassViewCommon.php index a63c9d770..cee14544c 100644 --- a/inc/inc.ClassViewCommon.php +++ b/inc/inc.ClassViewCommon.php @@ -69,6 +69,16 @@ class SeedDMS_View_Common { return null; } + /** + * Check if the view has a parameter with the given name + * + * @param string $name name of parameter + * @return boolean true if parameter exists otherwise false + */ + function hasParam($name) { + return isset($this->params[$name]) ? true : false; + } + public function unsetParam($name) { if(isset($this->params[$name])) unset($this->params[$name]); diff --git a/languages/de_DE/lang.inc b/languages/de_DE/lang.inc index e823dbd9a..5fef65ae3 100644 --- a/languages/de_DE/lang.inc +++ b/languages/de_DE/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (2765), dgrutsch (22) +// Translators: Admin (2767), dgrutsch (22) $text = array( '2_factor_auth' => '2-Faktor Authentifizierung', diff --git a/languages/el_GR/lang.inc b/languages/el_GR/lang.inc index cc5eec81a..7edaf768d 100644 --- a/languages/el_GR/lang.inc +++ b/languages/el_GR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (311) +// Translators: Admin (322) $text = array( '2_factor_auth' => '', @@ -347,7 +347,7 @@ $text = array( 'document_is_checked_out' => '', 'document_is_not_locked' => '', 'document_link_by' => '', -'document_link_public' => '', +'document_link_public' => 'Δημόσιο', 'document_moved_email' => 'Το έγγραφα μετακινήθηκε', 'document_moved_email_body' => '', 'document_moved_email_subject' => '', @@ -364,7 +364,7 @@ $text = array( 'document_updated_email' => '', 'document_updated_email_body' => '', 'document_updated_email_subject' => '', -'does_not_expire' => '', +'does_not_expire' => 'Δεν λήγει', 'does_not_inherit_access_msg' => '', 'download' => 'Λήψη', 'download_extension' => '', @@ -467,7 +467,7 @@ $text = array( 'expired_at_date' => '', 'expired_documents' => '', 'expires' => 'Λήγει', -'expire_by_date' => '', +'expire_by_date' => 'Λήγει στην ημερομηνία', 'expire_in_1d' => '', 'expire_in_1h' => '', 'expire_in_1m' => 'Λήγει σε 1 μήνα', @@ -660,7 +660,7 @@ $text = array( 'list_contains_no_access_docs' => '', 'list_hooks' => '', 'list_tasks' => '', -'local_file' => '', +'local_file' => 'Τοπικό αρχείο', 'locked_by' => '', 'lock_document' => 'Κλείδωμα', 'lock_message' => '', @@ -689,7 +689,7 @@ $text = array( 'mandatory_reviewers' => '', 'mandatory_reviewer_no_access' => '', 'march' => 'Μάρτιος', -'max_upload_size' => '', +'max_upload_size' => 'Μέγιστο μέγεθος μεταφόρτωσης', 'may' => 'Μάϊος', 'menu_dropfolder' => '', 'menu_upload_from_dropfolder' => '', @@ -715,7 +715,7 @@ $text = array( 'my_documents' => 'Τα έγγραφα μου', 'my_transmittals' => '', 'name' => 'Όνομα', -'nb_NO' => '', +'nb_NO' => 'Νορβηγικά', 'needs_correction' => '', 'needs_workflow_action' => '', 'network_drive' => '', @@ -833,7 +833,7 @@ URL: [url]', 'personal_default_keywords' => '', 'pl_PL' => 'Πολωνικά', 'possible_substitutes' => '', -'preset_expires' => '', +'preset_expires' => 'Λήξη προκαθορισμένης τιμής', 'preview' => 'προεπισκόπηση', 'preview_converters' => '', 'preview_images' => '', @@ -1014,7 +1014,7 @@ URL: [url]', 'select_attrdefgrp_show' => '', 'select_attribute_value' => '', 'select_category' => 'Επιλογή κατηγορίας', -'select_group' => '', +'select_group' => 'Επιλογή ομάδας', 'select_groups' => '', 'select_grp_approvers' => '', 'select_grp_ind_approvers' => '', @@ -1420,7 +1420,7 @@ URL: [url]', 'settings_workflowMode_valtraditional_only_approval' => '', 'settings_zendframework' => '', 'set_expiry' => '', -'set_owner' => '', +'set_owner' => 'Θέσε Ιδιοκτήτη', 'set_owner_error' => '', 'set_password' => '', 'set_workflow' => '', @@ -1672,9 +1672,9 @@ URL: [url]', 'user_login' => '', 'user_management' => 'Διαχείριση χρηστών', 'user_name' => 'Πλήρες Όνομα', -'use_comment_of_document' => '', +'use_comment_of_document' => 'Χρήση σχολίου εγγράφου', 'use_default_categories' => '', -'use_default_keywords' => '', +'use_default_keywords' => 'Χρήση προκαθορισμένων λέξεων κλειδιών', 'valid_till' => '', 'version' => 'Έκδοση', 'versioning_file_creation' => '', diff --git a/languages/en_GB/lang.inc b/languages/en_GB/lang.inc index 5afcc7c00..0f12104da 100644 --- a/languages/en_GB/lang.inc +++ b/languages/en_GB/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1871), archonwang (3), dgrutsch (9), netixw (14) +// Translators: Admin (1873), archonwang (3), dgrutsch (9), netixw (14) $text = array( '2_factor_auth' => '2-factor authentication', diff --git a/languages/es_ES/lang.inc b/languages/es_ES/lang.inc index 5f357848e..896e23399 100644 --- a/languages/es_ES/lang.inc +++ b/languages/es_ES/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: acabello (20), Admin (1151), angel (123), francisco (2), jaimem (14) +// Translators: acabello (20), Admin (1171), angel (123), francisco (2), jaimem (14) $text = array( '2_factor_auth' => '', @@ -68,11 +68,11 @@ URL: [url]', 'add_receipt' => '', 'add_review' => 'Enviar revisión', 'add_revision' => '', -'add_role' => '', +'add_role' => 'Agregar Usuario', 'add_subfolder' => 'Añadir subcarpeta', 'add_task' => '', 'add_to_clipboard' => 'Añadir al portapapeles', -'add_to_transmittal' => '', +'add_to_transmittal' => 'Añadir a transmisión', 'add_transmittal' => '', 'add_user' => 'Añadir nuevo usuario', 'add_user_to_group' => 'Añadir usuario a grupo', @@ -136,7 +136,7 @@ URL: [url]', 'archive_creation_warning' => 'Con esta operación usted puede crear un archivo que contenga los ficheros de las carpetas del DMS completo. Después de crearlo el archivo se guardará en la carpeta de datos de su servidor.CUIDADO: un fichero creado como legible por humanos no podrá usarse como copia de seguridad del servidor.', 'ar_EG' => 'Arabe', 'assign_approvers' => 'Asignar aprobadores', -'assign_recipients' => '', +'assign_recipients' => 'Asignar Receptores', 'assign_reviewers' => 'Asignar revisores', 'assign_user_property_to' => 'Asignar propiedades de usuario a', 'assumed_released' => 'Supuestamente publicado', @@ -231,8 +231,8 @@ URL: [url]', 'change_assignments' => 'cambiar asignaciones', 'change_password' => 'cambiar contraseña', 'change_password_message' => 'Su contraseña se ha modificado.', -'change_recipients' => '', -'change_revisors' => '', +'change_recipients' => 'Definir destinatarios', +'change_revisors' => 'Definir revisores', 'change_status' => 'cambiar estado', 'charts' => 'Gráficos', 'chart_docsaccumulated_title' => 'Cantidad de documentos', @@ -254,7 +254,7 @@ URL: [url]', 'choose_attrdefgroup' => '', 'choose_category' => 'Seleccione categoría', 'choose_group' => 'Seleccione grupo', -'choose_role' => '', +'choose_role' => 'Seleccione Usuario', 'choose_target_category' => 'Seleccione categoría', 'choose_target_document' => 'Seleccione documento', 'choose_target_file' => 'Seleccione fichero destino', @@ -442,7 +442,7 @@ URL: [url]', 'do_object_setfilesize' => 'Asignar tamaño de fichero', 'do_object_setfiletype' => '', 'do_object_unlink' => 'Borrar versión del documento', -'draft' => '', +'draft' => 'Borrador', 'draft_pending_approval' => 'Borador - pendiente de aprobación', 'draft_pending_review' => 'Borrador - pendiente de revisión', 'drag_icon_here' => 'Arrastre carpeta o documento aquí!', @@ -656,7 +656,7 @@ URL: [url]', 'index_pending' => '', 'index_waiting' => 'Esperando', 'individuals' => 'Individuales', -'individuals_in_groups' => '', +'individuals_in_groups' => 'Miembros del grupo', 'info_recipients_tab_not_released' => '', 'inherited' => 'heredado', 'inherits_access_copy_msg' => 'Copiar lista de acceso heredado', @@ -686,7 +686,7 @@ URL: [url]', 'invalid_user_id' => 'ID de usuario no válido', 'invalid_version' => 'Versión de documento no válida', 'in_folder' => 'En el directorio', -'in_revision' => '', +'in_revision' => 'En revisión', 'in_workflow' => 'En flujo de trabajo', 'is_disabled' => 'Deshabilitar cuenta', 'is_hidden' => 'Ocultar de la lista de usuarios', @@ -794,7 +794,7 @@ URL: [url]', 'my_transmittals' => 'Mi transmision', 'name' => 'Nombre', 'nb_NO' => 'Noruego (Bokmål)', -'needs_correction' => '', +'needs_correction' => 'Necesita corrección', 'needs_workflow_action' => 'Este documento requiere su atención. Por favor chequee la pestaña de flujo de trabajo.', 'network_drive' => '', 'never' => 'nunca', @@ -855,7 +855,7 @@ URL: [url]', 'no_action' => 'No es necesaria ninguna acción', 'no_approval_needed' => 'No hay aprobaciones pendientes.', 'no_attached_files' => 'No hay ficheros adjuntos', -'no_backup_dir' => '', +'no_backup_dir' => 'El directorio de backup no está definido', 'no_current_version' => 'Está utilizando una versión desactualizada de este producto. La última versión disponible es [latestversion].', 'no_default_keywords' => 'No hay palabras clave disponibles', 'no_docs_checked_out' => '', @@ -971,7 +971,7 @@ Si continua teniendo problemas de acceso, por favor contacte con el administrado 'receipt_summary' => 'Resumen de recepción', 'receipt_update_failed' => '', 'recent_uploads' => 'Subidas recientes', -'reception' => '', +'reception' => 'Recepción', 'reception_acknowleged' => '', 'reception_noaction' => '', 'reception_rejected' => '', @@ -1052,7 +1052,7 @@ URL: [url]', 'review_submit_email_subject' => '[sitename]: [name] - Revisión enviada', 'review_summary' => 'Resumen de revisión', 'review_update_failed' => 'Error actualizando el estado de la revisión. La actualización ha fallado.', -'revise_document' => '', +'revise_document' => 'Revisar documento', 'revise_document_on' => '', 'revisions_accepted' => '', 'revisions_accepted_latest' => '', @@ -1065,14 +1065,14 @@ URL: [url]', 'revisions_without_group' => '', 'revisions_without_user' => '', 'revision_date' => '', -'revision_log' => '', +'revision_log' => 'Histórico de revisiones', 'revision_request_email_body' => '', 'revision_request_email_subject' => '', 'revision_status' => '', 'revision_submit_email_body' => '', 'revision_submit_email_subject' => '', 'revision_summary' => 'Resumen de revisión', -'revisors' => '', +'revisors' => 'Revisores', 'revisor_already_assigned' => '', 'revisor_already_removed' => '', 'rewind_workflow' => 'Retroceso del flujo de trabajo', @@ -1160,16 +1160,16 @@ URL: [url]', 'select_grp_approvers' => 'Haga Click para seleccionar grupo de aprobadores', 'select_grp_ind_approvers' => '', 'select_grp_ind_notification' => '', -'select_grp_ind_recipients' => '', -'select_grp_ind_reviewers' => '', +'select_grp_ind_recipients' => 'Seleccione grupo', +'select_grp_ind_reviewers' => 'Dar click para seleccionar el grupo', 'select_grp_ind_revisors' => '', 'select_grp_notification' => 'Clic para seleccionar la notificación grupal', -'select_grp_recipients' => '', +'select_grp_recipients' => 'Dar click para selecionar el grupo', 'select_grp_reviewers' => 'Haga Click para seleccionar grupo de revisores', 'select_grp_revisors' => '', 'select_ind_approvers' => 'Haga Click para seleccionar aprobador individual', 'select_ind_notification' => 'Clic para seleccionar la notificación individual', -'select_ind_recipients' => '', +'select_ind_recipients' => 'Dar click para asignar los receptores', 'select_ind_reviewers' => 'Haga Click para seleccionar revisor individual', 'select_ind_revisors' => '', 'select_one' => 'Seleccionar uno', @@ -1660,7 +1660,7 @@ URL: [url]', 'status_not_approved' => 'Sin aprobar', 'status_not_receipted' => '', 'status_not_reviewed' => 'Sin revisar', -'status_not_revised' => '', +'status_not_revised' => 'No revisado', 'status_receipted' => '', 'status_receipt_rejected' => '', 'status_recipient_removed' => '', diff --git a/languages/fr_FR/lang.inc b/languages/fr_FR/lang.inc index c02f80626..9948dad7d 100644 --- a/languages/fr_FR/lang.inc +++ b/languages/fr_FR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1102), jeromerobert (50), lonnnew (9), Oudiceval (922) +// Translators: Admin (1102), jeromerobert (50), lonnnew (9), Oudiceval (929) $text = array( '2_factor_auth' => 'Authentification forte', @@ -1666,7 +1666,7 @@ Nom : [username] 'splash_error_add_to_transmittal' => 'Erreur lors de l’ajout du document à la transmission', 'splash_error_rm_download_link' => 'Erreur lors de la suppression du lien de téléchargement', 'splash_error_send_download_link' => 'Erreur lors de l’envoi du lien de téléchargement', -'splash_extension_getlist' => 'Liste des extensions mises à jour depuis le dépôt', +'splash_extension_getlist' => 'Liste des extensions du dépôt actualisée', 'splash_extension_import' => 'Extension installée', 'splash_extension_refresh' => 'Liste des extensions actualisée', 'splash_extension_upload' => 'Extension installée', @@ -1743,8 +1743,8 @@ Nom : [username] 'submit_review' => 'Soumettre la vérification', 'submit_revision' => 'Soumettre la révision', 'submit_userinfo' => 'Soumettre info', -'submit_webauthn_login' => '', -'submit_webauthn_register' => '', +'submit_webauthn_login' => 'Identification', +'submit_webauthn_register' => 'Inscription', 'subsribe_timelinefeed' => 'S’abonner au flux RSS', 'substitute_to_user' => 'Basculer sur \'[username]\'', 'substitute_user' => 'Utilisateur de substitution', @@ -1904,10 +1904,10 @@ URL: [url]', 'view' => 'Aperçu', 'view_online' => 'Aperçu en ligne', 'warning' => 'Avertissement', -'webauthn_auth' => '', -'webauthn_crossplatform_info' => '', -'webauthn_info' => '', -'webauth_crossplatform' => '', +'webauthn_auth' => 'Authentification WebAuthn', +'webauthn_crossplatform_info' => 'Choisissez « Oui » lorsque vous avez un périphérique amovible, comme une clé Yubico, que vous souhaitez utiliser pour vous connecter sur différents ordinateurs ; choisissez « Non » lorsque votre appareil est connecté à l\'ordinateur. Le choix affecte le ou les appareils proposés par le navigateur et / ou le système de sécurité informatique.', +'webauthn_info' => 'WebAuthn est une authentification sans mot de passe utilisant la cryptographie à clé publique. Une paire de clés privée-publique (connue sous le nom de certificat) est créée pour un site Web. La clé privée est stockée en toute sécurité sur l’appareil de l’utilisateur ; une clé publique et un identifiant généré de manière aléatoire sont envoyés au serveur pour stockage. Le serveur peut ensuite utiliser cette clé publique pour prouver l’identité de l’utilisateur. La clé privée est généralement stockée sur un jeton matériel. Le jeton doit être enregistré avant de pouvoir être utilisé pour l’authentification.', +'webauth_crossplatform' => 'Multiplateforme', 'wednesday' => 'Mercredi', 'wednesday_abbr' => 'Mer.', 'weeks' => 'semaines', diff --git a/languages/hu_HU/lang.inc b/languages/hu_HU/lang.inc index 90326a8c9..5e1e21ee4 100644 --- a/languages/hu_HU/lang.inc +++ b/languages/hu_HU/lang.inc @@ -23,11 +23,11 @@ $text = array( '2_factor_auth' => 'Kétfaktoros azonosítás', -'2_factor_auth_info' => '', +'2_factor_auth_info' => 'A rendszernek két faktoros hitelesítése van. Szükséged lesz a Google Authenticator-ra a mobil telefonodon. Lejebb látható két QR kód. A jobb oldali a saját jelszavát, a baloldali egy új titkos jelszót tartalmaz. Ha új jelszót szeretne beállítani, szkennelje be újra a Goolge Authenticator-al.', '2_fact_auth_secret' => 'Titkos', 'accept' => 'Elfogad', -'access_control' => '', -'access_control_is_off' => '', +'access_control' => 'Hozzáférés vezérlés', +'access_control_is_off' => 'A speciális vezérlés hozzáférése ki van kapcsolva', 'access_denied' => 'Hozzáférés megtagadva.', 'access_inheritance' => 'Hozzáférés öröklés', 'access_mode' => 'Hozzáférési mód', @@ -54,7 +54,7 @@ URL: [url]', 'action_revise' => 'Felülvizsgálat', 'add' => 'Hozzáad', 'add_approval' => 'Jóváhagyás küldése', -'add_attrdefgroup' => '', +'add_attrdefgroup' => 'Új tulajdonságcsoport hozzáadása', 'add_document' => 'Dokumentum hozzáadása', 'add_document_link' => 'Hivatkozás hozzáadása', 'add_document_notify' => 'Hozzárendelés értesítés', @@ -67,7 +67,7 @@ URL: [url]', 'add_multiple_files' => 'Több állomány hozzáadása (az állomány nevét használja dokumentum névként)', 'add_receipt' => '', 'add_review' => 'Felülvizsgálat küldése', -'add_revision' => '', +'add_revision' => 'Felülvizsgálat hozzáadása', 'add_role' => 'szerepkör hozzáadása', 'add_subfolder' => 'Alkönyvtár hozzáadása', 'add_task' => 'Feladat hozzáadása', @@ -103,7 +103,7 @@ URL: [url]', 'approval_deletion_email' => 'Jóváhagyási kérelem törölve', 'approval_deletion_email_body' => '', 'approval_deletion_email_subject' => '', -'approval_file' => '', +'approval_file' => 'Fájl', 'approval_group' => 'Jóváhagyó csoport', 'approval_log' => 'Jóváhagyási napló', 'approval_request_email' => 'Jóváhagyási kérelem', @@ -115,7 +115,7 @@ Felhasználó: [username] URL: [url]', 'approval_request_email_subject' => '[sitename]: [name] - Jóváhagyási kérelem', 'approval_status' => 'Jóváhagyási állapot', -'approval_submit_email' => '', +'approval_submit_email' => 'Fordítás hiányzik', 'approval_submit_email_body' => 'Dokumentum jóváhagyása Documentum: [name] Verzió: [version] @@ -143,10 +143,10 @@ URL: [url]', 'attrdefgroup_management' => '', 'attrdefgrp_show_detail' => '', 'attrdefgrp_show_list' => '', -'attrdefgrp_show_search' => '', +'attrdefgrp_show_search' => 'Keresés', 'attrdefgrp_show_searchlist' => '', 'attrdef_exists' => 'Jellemző meghatározás már létezik', -'attrdef_info' => '', +'attrdef_info' => 'Információ', 'attrdef_in_use' => 'Jellemző meghatározás még használatban van', 'attrdef_management' => 'Jellemző meghatározás kezelése', 'attrdef_maxvalues' => 'Legnagyobb érték', @@ -162,11 +162,11 @@ URL: [url]', 'attrdef_type' => 'Típus', 'attrdef_type_boolean' => 'Logikai', 'attrdef_type_date' => 'Dátum', -'attrdef_type_email' => '', +'attrdef_type_email' => 'Email', 'attrdef_type_float' => 'Szám tizedesjeggyel', 'attrdef_type_int' => 'Egész szám', 'attrdef_type_string' => 'Szöveg', -'attrdef_type_url' => '', +'attrdef_type_url' => 'URL', 'attrdef_valueset' => 'Értékek beállítása', 'attributes' => 'Jellemzők', 'attribute_changed_email_body' => 'Jellemző módosult @@ -223,7 +223,7 @@ URL: [url]', 'category' => 'Kategória', 'category_exists' => 'Kategória már létezik', 'category_filter' => 'Kizárólag kategóriák', -'category_info' => '', +'category_info' => 'Információk', 'category_in_use' => 'Dokumentumok használják ezt a kategóriát', 'category_noname' => 'Nem adott meg kategória nevet.', 'ca_ES' => 'Katalán', @@ -299,8 +299,8 @@ URL: [url]', 'confirm_update_transmittalitem' => '', 'content' => 'Tartalom', 'continue' => 'Folytatás', -'converter_new_cmd' => '', -'converter_new_mimetype' => '', +'converter_new_cmd' => 'Új parancs', +'converter_new_mimetype' => 'Új mime típus', 'copied_to_checkout_as' => '', 'create_download_link' => '', 'create_fulltext_index' => 'Teljes szöveg index létrehozása', @@ -366,7 +366,7 @@ Szülő mappa: [folder_path] Felhasználó: [username] URL: [url]', 'document_comment_changed_email_subject' => '[sitename]: [name] - Megjegyzés módosult', -'document_count' => '', +'document_count' => 'Dokumentumok száma', 'document_deleted' => 'Dokumentum törölve', 'document_deleted_email' => 'Dokumentum törölve', 'document_deleted_email_body' => 'Dokumentum törölve @@ -457,7 +457,7 @@ URL: [url]', 'dump_list' => 'Meglévő adatbázis metések', 'dump_remove' => 'Adatbázis mentés eltávolítása', 'duplicates' => '', -'duplicate_content' => '', +'duplicate_content' => 'Duplikált tartalom', 'edit' => 'Szerkesztés', 'edit_attributes' => 'Jellemzők szerkesztése', 'edit_comment' => 'Megjegyzés szerkesztése', @@ -539,7 +539,7 @@ Felhasználó: [username] URL: [url]', 'expiry_changed_email_subject' => '[sitename]: [name] - Lejárati dátum módosítva', 'export' => 'exportálás', -'extension_archive' => '', +'extension_archive' => 'Bővítmények', 'extension_changelog' => 'Változásnapló', 'extension_loading' => 'Kiterjesztések betöltése ...', 'extension_manager' => 'Bővítmények kezelése', @@ -630,7 +630,7 @@ URL: [url]', 'guest_login_disabled' => 'Vendég bejelentkezés letiltva.', 'hash' => 'hash', 'help' => 'Segítség', -'home_folder' => '', +'home_folder' => 'Saját mappa', 'hook_name' => '', 'hourly' => 'Óra', 'hours' => 'óra', @@ -641,14 +641,14 @@ URL: [url]', 'identical_version' => 'Az új verzió megegyezik az eredetivel.', 'import' => 'Import', 'importfs' => '', -'import_extension' => '', +'import_extension' => 'Kiterjesztés import', 'import_fs' => 'Importálás fájlrendszerből', 'import_fs_warning' => '', 'include_content' => '', 'include_documents' => 'Tartalmazó dokumentumok', 'include_subdirectories' => 'Tartalmazó alkönyvtárak', 'indexing_tasks_in_queue' => 'Indexelés folyamatban', -'index_converters' => '', +'index_converters' => 'Index konvertáló', 'index_done' => '', 'index_error' => '', 'index_folder' => 'Mappa indexelése', @@ -784,7 +784,7 @@ URL: [url]', 'monday_abbr' => 'Hé', 'monthly' => 'Havi', 'month_view' => 'Havi nézet', -'more_objects_loading' => '', +'more_objects_loading' => 'További sorok betöltése...', 'move' => 'Áthelyez', 'move_clipboard' => 'Vágólapra helyez', 'move_document' => 'Dokumentum áthelyezése', @@ -929,10 +929,10 @@ Amennyiben problémákba ütközik a bejelentkezés során, kérjük vegye fel a 'password_strength' => 'Jelszó erősség', 'password_strength_insuffient' => 'Jelszó erőssége elégtelen', 'password_wrong' => 'Hibás jelszó', -'pdf_converters' => '', -'pending_approvals' => '', +'pdf_converters' => 'PDF konvertáló', +'pending_approvals' => 'Függőben lévő jóváhagyások', 'pending_receipt' => '', -'pending_reviews' => '', +'pending_reviews' => 'Függőben lévő feladatok', 'pending_revision' => '', 'pending_workflows' => '', 'personal_default_keywords' => 'Személyes kulcsszó lista', @@ -940,7 +940,7 @@ Amennyiben problémákba ütközik a bejelentkezés során, kérjük vegye fel a 'possible_substitutes' => '', 'preset_expires' => 'Érvényesség beállítása', 'preview' => 'Előnézet', -'preview_converters' => '', +'preview_converters' => 'A dokumentum átalakításának előnézete', 'preview_images' => 'előnézeti képek', 'preview_markdown' => '', 'preview_pdf' => '', @@ -948,7 +948,7 @@ Amennyiben problémákba ütközik a bejelentkezés során, kérjük vegye fel a 'previous_state' => 'Előző állapot', 'previous_versions' => 'Előző változatok', 'process' => 'Folyamat', -'process_without_user_group' => '', +'process_without_user_group' => 'Felhasználó / csoport nélküli folyamatok', 'pt_BR' => 'Portugál (BR)', 'quota' => 'Kvóta', 'quota_exceeded' => 'Túllépte a lemezterület korlátot [bytes].', @@ -1171,7 +1171,7 @@ URL: [url]', 'select_ind_recipients' => '', 'select_ind_reviewers' => 'Kattintson az önálló felülvizsgáló kijelöléséhez', 'select_ind_revisors' => '', -'select_one' => 'Vßlasszon egyet', +'select_one' => 'Válasszon egyet', 'select_user' => 'Felhasználó kiválasztása', 'select_users' => 'Kattintson a felhasználó kiválasztásához', 'select_value' => 'Érték kiválasztása', @@ -1180,13 +1180,13 @@ URL: [url]', 'send_login_data' => '', 'send_login_data_body' => '', 'send_login_data_subject' => '', -'send_test_mail' => 'teszt email küldése', +'send_test_mail' => 'Teszt e-mail küldése', 'september' => 'September', 'sequence' => 'Sorrend', 'seq_after' => '"[prevname]" utßn', 'seq_end' => 'Vgre', 'seq_keep' => 'Pozci megtartßsa', -'seq_start' => 'Elejre', +'seq_start' => 'Elejére', 'sessions' => '', 'setDateFromFile' => '', 'setDateFromFolder' => '', @@ -1200,16 +1200,16 @@ URL: [url]', 'settings_advancedAcl_desc' => '', 'settings_allowChangeRevAppInProcess' => '', 'settings_allowChangeRevAppInProcess_desc' => '', -'settings_allowReviewerOnly' => '', -'settings_allowReviewerOnly_desc' => '', +'settings_allowReviewerOnly' => 'Engedélyezi, hogy csak az ellenört állítsa be', +'settings_allowReviewerOnly_desc' => 'Ha ezt engedélyez, akkor lehetővé válik, hogy a hagyományos munkafolyamat módban csak ellenört állítson be, ne jóváhagyót.', 'settings_apache_mod_rewrite' => 'Apache - Rewrite modul', 'settings_Authentication' => 'Hitelesítési beállítások', -'settings_autoLoginUser' => '', -'settings_autoLoginUser_desc' => '', +'settings_autoLoginUser' => 'Automatikus bejelentkezés', +'settings_autoLoginUser_desc' => 'Használja ezt a felhasználói azonosítót a hozzáférésekhez, ha a felhasználó még nincs bejelentkezve. Az ilyen hozzáférés nem hoz létre munkamenetet.', 'settings_available_languages' => 'Elérhető nyelvek', 'settings_available_languages_desc' => '', -'settings_backupDir' => '', -'settings_backupDir_desc' => '', +'settings_backupDir' => 'Mentés könyvtára', +'settings_backupDir_desc' => 'Könyvtár, ahol a biztonsági mentési eszköz mentéseket készít. Ha ez a könyvtár nincs beállítva vagy nem érhető el, akkor a biztonsági másolatot a tartalom könyvtárba menti.', 'settings_cacheDir' => 'Átmeneti állományok könyvtára', 'settings_cacheDir_desc' => 'Ahol az előnézeti képek tárolódnak (legjobb olyan könyvtárat választani, amit a web-kiszolgálón keresztül nem lehet elérni)', 'settings_Calendar' => 'Naptár beállítások', @@ -1218,14 +1218,14 @@ URL: [url]', 'settings_cannot_disable' => 'ENABLE_INSTALL_TOOL állomány nem került törlésre', 'settings_checkOutDir' => '', 'settings_checkOutDir_desc' => '', -'settings_cmdTimeout' => '', -'settings_cmdTimeout_desc' => '', +'settings_cmdTimeout' => 'Külső parancsok időtúllépése', +'settings_cmdTimeout_desc' => 'Ez az időtartam másodpercben határozza meg, hogy mikor fejezik be a külső parancsot (például a teljes szöveg index létrehozásához).', 'settings_contentDir' => 'Tartalom könyvtár', 'settings_contentDir_desc' => 'Feltöltött állományok tárolási helye (olyan könyvtárat érdemes választani, amelyhez nem lehet a webszerveren keresztül hozzáférni)', 'settings_contentOffsetDir' => 'Tartalom eltérési könyvtár', 'settings_contentOffsetDir_desc' => 'Az alapul szolgáló fájlrendszer korlátozásainak kikerülésére új könyvtár struktúra került kialakításra amely úgy lett tervezve, hogy létezzen a tároló könyvtárban (Content Directory). Ehhez szükséges egy alap könyvtár ahonnan indul. Általában meg lehet hagyni az alapértelmezett értéket ami 1048576, de megadható bármilyen szám vagy karaktersorozat amely nem létezik a tartalom könyvtárban (Content Directory)', -'settings_convertToPdf' => '', -'settings_convertToPdf_desc' => '', +'settings_convertToPdf' => 'A dokumentum konvertálása PDF-be előnézet céljából', +'settings_convertToPdf_desc' => 'Ha a dokumentumot nem tudja megjeleníteni a böngészőben, akkor megjelenik egy pdf-formátumra konvertált változat.', 'settings_cookieLifetime' => 'Süti élettartam', 'settings_cookieLifetime_desc' => 'A süti élettartama másodpercben. Ha az értéke 0 akkor a süti a böngésző bezárásakor lesz törölve.', 'settings_coreDir' => 'Alap SeedDMS könyvtár', @@ -1247,12 +1247,12 @@ URL: [url]', 'settings_dbUser' => 'Felhasználónév', 'settings_dbUser_desc' => 'Az adatbázis eléréséhez tartozó felhasználónevet a telepítési eljárás során kell megadni. Ne szerkessze ezt a mezőt, csak ha nagyon szükséges, például, ha az adatbázist át kell helyezni egy másik gépre.', 'settings_dbVersion' => 'Adatbázis séma túl régi', -'settings_defaultAccessDocs' => '', -'settings_defaultAccessDocs_desc' => '', -'settings_defaultDocPosition' => '', -'settings_defaultDocPosition_desc' => '', -'settings_defaultDocPosition_val_end' => '', -'settings_defaultDocPosition_val_start' => '', +'settings_defaultAccessDocs' => 'Alapértelmezett hozzáférés az új dokumentumokhoz', +'settings_defaultAccessDocs_desc' => 'Új dokumentum létrehozásakor ez lesz az alapértelmezett hozzáférési jog.', +'settings_defaultDocPosition' => 'A dokumentum elhelyezése létrehozáskor', +'settings_defaultDocPosition_desc' => 'Ez az alapértelmezett hely egy mappában egy dokumentum létrehozásakor.', +'settings_defaultDocPosition_val_end' => 'vége', +'settings_defaultDocPosition_val_start' => 'eleje', 'settings_defaultSearchMethod' => 'Alapértelmezett keresési módszer', 'settings_defaultSearchMethod_desc' => '', 'settings_defaultSearchMethod_valdatabase' => 'adatbázis', @@ -1265,8 +1265,8 @@ URL: [url]', 'settings_dropFolderDir' => 'Drop mappa könyvtára', 'settings_dropFolderDir_desc' => 'Ez a könyvtár használható az importálandó állományok elhelyezésére a fájlrendszeren a böngészővel történő feltöltés helyett. A könyvtárnak tartalmaznia kell alkönyvtárakat minden felhasználóhoz akinek engedélyezett az állományok ilyen módon történő importálása.', 'settings_Edition' => 'Kiadás beállítások', -'settings_editOnlineFileTypes' => '', -'settings_editOnlineFileTypes_desc' => '', +'settings_editOnlineFileTypes' => 'Online fájltípusok szerkesztése', +'settings_editOnlineFileTypes_desc' => 'Az alábbi végződésekkel vagy mime-típusokkal rendelkező fájlok online szerkeszthetők (CSAK KISBETÜK HASZNÁLHTÓAK!)', 'settings_enable2FactorAuthentication' => '', 'settings_enable2FactorAuthentication_desc' => '', 'settings_enableAcknowledgeWorkflow' => '', @@ -1283,8 +1283,8 @@ URL: [url]', 'settings_enableConverting_desc' => 'Engedélyezi/tiltja az állományok konverzióját', 'settings_enableDebugMode' => '', 'settings_enableDebugMode_desc' => '', -'settings_enableDropFolderList' => '', -'settings_enableDropFolderList_desc' => '', +'settings_enableDropFolderList' => 'Engedélyezzi a fájlok listáját a drop mappa menüben', +'settings_enableDropFolderList_desc' => 'Kapcsolja be a Drop mappa-ban lévő fájlok listáját. A lista megjelenik a főmenüben.', 'settings_enableDropUpload' => 'Gyorsfeltöltés engedélyezése', 'settings_enableDropUpload_desc' => 'Be/Ki kapcsolja a \'Mappa nézet\' oldalon a fogd és vidd feltöltéshez tartozó területetet', 'settings_enableDuplicateDocNames' => 'Azonos dokumentum név engedélyezése', @@ -1299,8 +1299,8 @@ URL: [url]', 'settings_enableFolderTree_desc' => 'Hamis hogy ne jelenjen meg a mappa fastruktúra', 'settings_enableFullSearch' => 'Teljes szöveg keresés engedélyezése', 'settings_enableFullSearch_desc' => 'Engedélyezi a teljes szöveg keresést', -'settings_enableGuestAutoLogin' => '', -'settings_enableGuestAutoLogin_desc' => '', +'settings_enableGuestAutoLogin' => 'Engedélyezi az automatikus belépést a Vendég felhasználónak', +'settings_enableGuestAutoLogin_desc' => 'Ha a vendég bejelentkezés és az automatikus bejelentkezés engedélyezve van, a vendég automatikusan be lesz jelentkezve.', 'settings_enableGuestLogin' => 'Vendég belépésének engedélyezése', 'settings_enableGuestLogin_desc' => 'Ha azt szeretné, hogy bárki be tudjon jelentkezni vendégként, jelölje be ezt a lehetőséget. Megjegyzés: vendég bejelentkezés megbízható környezetben használható', 'settings_enableHelp' => 'Súgó engedélyezése', @@ -1309,10 +1309,10 @@ URL: [url]', 'settings_enableLanguageSelector_desc' => 'Megjelenít egy választást a felhasználói felületen a bejelentkezést követően.', 'settings_enableLargeFileUpload' => 'Nagy méretű állományok feltöltésének engedélyezése', 'settings_enableLargeFileUpload_desc' => 'Ha beállítja az állományok feltöltése elérhető lesz egy jumploadernek hívott java appleten keresztül a böngészőprogram állomány méret korlátja nélkül. Ez engedélyezi több állomány feltöltését egy lépésben.', -'settings_enableMenuTasks' => '', -'settings_enableMenuTasks_desc' => '', -'settings_enableMultiUpload' => '', -'settings_enableMultiUpload_desc' => '', +'settings_enableMenuTasks' => 'Feladatok menüpont engedélyezése', +'settings_enableMenuTasks_desc' => 'Engedélyezi / letiltja a menüelemet, amely a felhasználó összes feladatát tartalmazza. Ez olyan dokumentumokat tartalmaz, amelyeket felül kell vizsgálni, jóvá kell hagyni stb.', +'settings_enableMultiUpload' => 'Több fájl feltöltésének engedélyezése', +'settings_enableMultiUpload_desc' => 'Új dokumentum létrehozásakor több fájl feltölthető. Mindegyik létrehoz egy új dokumentumot.', 'settings_enableNotificationAppRev' => 'A felülvizsgáló/jóváhagyó értesítés engedélyezése', 'settings_enableNotificationAppRev_desc' => 'Ellenőrzi az értesítés küldését a felülvizsgálónak/jóváhagyónak új dokumentum változat hozzáadásakor', 'settings_enableNotificationWorkflow' => 'A felhasználó értesítése a következő munkafolyamatnál', @@ -1341,14 +1341,14 @@ URL: [url]', 'settings_enableSelfReceipt_desc' => '', 'settings_enableSelfRevApp' => 'Engedélyezi a felülvizsgálatot/jóváhagyást a bejelentkezett felhasználó számára', 'settings_enableSelfRevApp_desc' => 'Engedélyezze, a azt szeretné, hogy a bejelentkezett felhasználó listázásra kerüljön felülvizsgálóként/jóváhagyóként és a munkamenet átmeneteknél.', -'settings_enableSessionList' => '', -'settings_enableSessionList_desc' => '', +'settings_enableSessionList' => 'Engedélyezi a Felhasználók menüpont megjelenítését', +'settings_enableSessionList_desc' => 'Bejelentkezett felhasználók megjelenítése a főmenü / felhasználók menüjében.', 'settings_enableThemeSelector' => 'Téma választása', 'settings_enableThemeSelector_desc' => 'Kapcsolja be/ki a témaválasztót a bejelentkező oldalon', 'settings_enableUpdateReceipt' => '', 'settings_enableUpdateReceipt_desc' => '', 'settings_enableUpdateRevApp' => '', -'settings_enableUpdateRevApp_desc' => '', +'settings_enableUpdateRevApp_desc' => 'Engedélyezze ezt, ha a felülvizsgálatot / jóváhagyást megadó felhasználó megváltoztathatja a döntést, amíg a jelenlegi munkafolyamat még nem fejeződött be.', 'settings_enableUserImage' => 'Felhasználói kép engedélyezése', 'settings_enableUserImage_desc' => 'Engedélyezi a felhasználók képeit', 'settings_enableUsersView' => 'Felhasználók nézetének engedélyezése', @@ -1357,10 +1357,10 @@ URL: [url]', 'settings_enableVersionDeletion_desc' => 'Engedélyezi/tiltja a korábbi dokumentum verziók törlését az általános felhasználóknak. Adminisztrátor mindig törölheti a korábbi változatokat.', 'settings_enableVersionModification' => 'Engedélyezi a verziók módosítását', 'settings_enableVersionModification_desc' => 'Engedélyezi/tiltja a dokumentum verziók módosítását az általános felhasználóknak miután a verzió feltöltésre került. Adminisztrátor mindig módosíthatja a verziót feltöltés után.', -'settings_enableWebdavReplaceDoc' => '', -'settings_enableWebdavReplaceDoc_desc' => '', -'settings_enableXsendfile' => '', -'settings_enableXsendfile_desc' => '', +'settings_enableWebdavReplaceDoc' => 'Dokumentum cseréje mentés után', +'settings_enableWebdavReplaceDoc_desc' => 'Ha engedélyezve van, egy dokumentum új verziójának mentése az új verzió létrehozása helyett a régi dokumentumot váltja fel. Ez csak akkor lesz érvényes, ha a felhasználó, a típustípus és a fájlnév megegyezik az utolsó verzióval. Ez hasznos lehet, ha az alkalmazások automatikusan menti a dokumentumot meghatározott időközönként.', +'settings_enableXsendfile' => 'Apache xsendfile module használata', +'settings_enableXsendfile_desc' => 'Ha ez az opció be van állítva, és az xsendfile apache modul telepítve van, akkor a képeket továbbítja.', 'settings_encryptionKey' => 'Titkosító kulcs', 'settings_encryptionKey_desc' => 'Ez a karaktersorozat használható egyedi azonosító létrehozásához amely rejtett mezőként lesz hozzáadva az űrlapokhoz a CSRF támadások megelőzésére.', 'settings_error' => 'Hiba', @@ -1376,16 +1376,16 @@ URL: [url]', 'settings_firstDayOfWeek_desc' => 'A hét első napja', 'settings_footNote' => 'Lábjegyzet', 'settings_footNote_desc' => 'Minden oldal alján megjelenő üzenet', -'settings_fullSearchEngine' => '', -'settings_fullSearchEngine_desc' => '', -'settings_fullSearchEngine_vallucene' => 'Zend Lucene', -'settings_fullSearchEngine_valsqlitefts' => 'SQLiteFTS', +'settings_fullSearchEngine' => 'Szöveg keresési mód', +'settings_fullSearchEngine_desc' => 'Állítsa be a kereséséhez használt módot.', +'settings_fullSearchEngine_vallucene' => 'Dokumentum tartalom keresés', +'settings_fullSearchEngine_valsqlitefts' => 'Adatbázis keresés', 'settings_guestID' => 'Vendég azonosító', 'settings_guestID_desc' => 'A vendég felhasználó azonosítója ami a vendégként történő bejelentkezéskor lesz használva (általában nem szükséges módosítani)', 'settings_httpRoot' => 'Http gyökér', 'settings_httpRoot_desc' => 'A relatív elérési út az URL-ben a tartomány rész után. Ne tartalmazza a http:// előtagot vag a web szerver nevét. Pl.: ha a teljes URL http://www.example.com/seeddms/, adja meg \'/seeddms/\'. Ha az URL http://www.example.com/, adja meg \'/\'', -'settings_incItemsPerPage' => '', -'settings_incItemsPerPage_desc' => '', +'settings_incItemsPerPage' => 'Az oldal végén betöltött bejegyzések száma', +'settings_incItemsPerPage_desc' => 'Ha a mappák és a dokumentumok száma korlátozott, akkor ez beállítja a kiegészítőként betöltött tételek számát, amikor a nézetmappa oldal aljára görget. Ha ezt 0-ra állítja, akkor nincs megjelenítési korlátozás.', 'settings_initialDocumentStatus' => '', 'settings_initialDocumentStatus_desc' => '', 'settings_initialDocumentStatus_draft' => '', @@ -1416,14 +1416,14 @@ URL: [url]', 'settings_maxDirID_desc' => 'Szülő könyvtárban lévő alkönyvtárak maximális mennyisége, Alapérték: 0.', 'settings_maxExecutionTime' => 'Maximális végrehajtási idő (s)', 'settings_maxExecutionTime_desc' => 'Beállítja a szkript maximális engedélyezett futási idejét másodpercben mielőtt megszakítja az értelmező', -'settings_maxItemsPerPage' => '', -'settings_maxItemsPerPage_desc' => '', +'settings_maxItemsPerPage' => 'Egy oldalon megjeleníthető tételek maximális száma', +'settings_maxItemsPerPage_desc' => 'Korlátozza a nézetlistában megjelenő mappák és dokumentumok számát. További tételeket tölt be, amikor az oldal végére görgeti. 0-ra állítva az összes tétel mindig megjelenik.', 'settings_maxRecursiveCount' => 'Rekurzív dokumentum/mappa számláló legnagyobb értéke', 'settings_maxRecursiveCount_desc' => 'A dokumentumok és mappák maximális mennyisége amelyeken ellenőrizni fogják a hozzáférési jogokat, ha rekurzívan számláló tárgyakat. Ha ezt az értéket túllépik, a dokumentumok számát és mappák a Mappa nézetben is becsülhetők.', -'settings_maxSizeForFullText' => '', -'settings_maxSizeForFullText_desc' => '', -'settings_maxUploadSize' => '', -'settings_maxUploadSize_desc' => '', +'settings_maxSizeForFullText' => 'Maximális fájlméret az azonnali indexeléshez', +'settings_maxSizeForFullText_desc' => 'A beállított méretnél kisebb minden új dokumentum verziót a feltöltés után azonnal teljesen indexeli. Minden más esetben csak a metaadatok kerülnek indexelésre.', +'settings_maxUploadSize' => 'Feltölthető állományok maximális mérete', +'settings_maxUploadSize_desc' => 'Ez a feltöltött fájlok maximális mérete. A dokumentum verziókra és a mellékletekre is vonatkozik.', 'settings_more_settings' => 'További beállítások konfigurálása. Alapértelmezett bejelentkezés: admin/admin', 'settings_noDocumentFormFields' => '', 'settings_noDocumentFormFields_desc' => '', @@ -1433,8 +1433,8 @@ URL: [url]', 'settings_no_content_dir' => 'Tartalom könyvtár', 'settings_onePageMode' => '', 'settings_onePageMode_desc' => '', -'settings_overrideMimeType' => '', -'settings_overrideMimeType_desc' => '', +'settings_overrideMimeType' => 'A Mime típus felülbírálása', +'settings_overrideMimeType_desc' => 'A fájl feltöltése esetén felülbírálja a böngésző által szállított Mime típust. Az új Mime típust maga a SeedDMS határozza meg.', 'settings_partitionSize' => 'Részleges fájlméret', 'settings_partitionSize_desc' => 'A részleges állományok mérete, amelyek a jumploader segítségével lesznek feltöltve. Ne adjon meg magasabb értéket, mint a szerveren beállított legnagyobb feltölthető állomány méret.', 'settings_passwordExpiration' => 'Jelszó lejárat', @@ -1458,14 +1458,14 @@ URL: [url]', 'settings_presetExpirationDate_desc' => 'Minden feltöltött dokumentumhoz ezt a lejárati dátumot rendeli hozzá. A PHP strtotime() függvényének formátuma használható, pl.: +5 weeks.', 'settings_previewWidthDetail' => 'Előnézeti képek szélessége (részletek)', 'settings_previewWidthDetail_desc' => 'A részletek oldalon megjelenő előnézeti képek szélessége', -'settings_previewWidthDropFolderList' => '', -'settings_previewWidthDropFolderList_desc' => '', +'settings_previewWidthDropFolderList' => 'Az előnézeti képek szélessége (drop mappa listában)', +'settings_previewWidthDropFolderList_desc' => 'A listában szereplő előnézeti képek szélessége, amikor a fájlt kiválasztja a drop mappából.', 'settings_previewWidthList' => 'Előnézeti képek szélessége (lista)', 'settings_previewWidthList_desc' => 'A listában megjelenő előnézeti képek szélessége', -'settings_previewWidthMenuList' => '', -'settings_previewWidthMenuList_desc' => '', +'settings_previewWidthMenuList' => 'Az előnézeti képek szélessége (menülista)', +'settings_previewWidthMenuList_desc' => 'Az előnézeti képek szélessége, amelyeket tételekként jelennek meg a Drop mappa menüben.', 'settings_printDisclaimer' => 'Nyilatkozat nyomtatása', -'settings_printDisclaimer_desc' => 'Ha igaz a nyilatkozat üzenet a lang.inc állományok lesznek kiíratva a lap alján', +'settings_printDisclaimer_desc' => 'Ha igaz ez a beállítás, akkor s lang.inc-ben a Disclaimer tartalma kerül megjelenítésre a lap alján', 'settings_proxyUPassword' => '', 'settings_proxyUPassword_desc' => '', 'settings_proxyUrl' => '', @@ -1474,10 +1474,10 @@ URL: [url]', 'settings_proxyUser_desc' => '', 'settings_quota' => 'Felhasználói kvóta', 'settings_quota_desc' => 'A felhasználó által a lemezen használható bájtok legnagyobb száma. Állítsa 0-ra a korlátlan lemezterülethez. Ez az érték felülírható valamennyi felhasználó saját profiljában.', -'settings_removeFromDropFolder' => '', -'settings_removeFromDropFolder_desc' => '', -'settings_repositoryUrl' => '', -'settings_repositoryUrl_desc' => '', +'settings_removeFromDropFolder' => 'A sikeres feltöltés után távolítsa el a fájlt a drop mappából', +'settings_removeFromDropFolder_desc' => 'Engedélyezze ezt, ha a drop mappából vett fájlt a sikeres feltöltés után törölhető.', +'settings_repositoryUrl' => 'Bővítmények URL-je', +'settings_repositoryUrl_desc' => 'A bővítmények tárházának URL-je', 'settings_restricted' => 'Korlátozott hozzáférés', 'settings_restricted_desc' => 'Kizárólag azok a felhasználók jelentkezhetnek be, akik a helyi adatbázisban vannak (függetlenül a sikeres LDAP azonosítástól)', 'settings_rootDir' => 'Gyökérkönyvtár', @@ -1490,8 +1490,8 @@ URL: [url]', 'settings_showFullPreview_desc' => '', 'settings_showMissingTranslations' => 'Jelenítse meg a hiányzó fordításokat', 'settings_showMissingTranslations_desc' => 'Felsorolja az összes hiányzó fordítást a lap alján. A bejelentkezett felhasználó képes lesz arra, hogy javaslatot nyújtson be a hiányzó fordításokra, amelyek egy csv állományba kerülnek mentésre. Ne kapcsolja be ezt a funkciót élse környezetben!', -'settings_showSingleSearchHit' => '', -'settings_showSingleSearchHit_desc' => '', +'settings_showSingleSearchHit' => 'Ugrás egyenesen egyetlen keresési találatra', +'settings_showSingleSearchHit_desc' => 'Ha a keresésnek egy találata van, akkor ugorjon a dokumentum tartalmára.', 'settings_Site' => 'Webhely', 'settings_siteDefaultPage' => 'Webhely kezdőlap', 'settings_siteDefaultPage_desc' => 'Alapértelmezett oldal a bejelentkezést követően. Ha üres, akkor az alapértelmezett out/out.ViewFolder.php', @@ -1504,8 +1504,8 @@ URL: [url]', 'settings_smtpPort_desc' => 'SMTP kiszolgáló port, alapértelmezett 25', 'settings_smtpSendFrom' => 'Feladó', 'settings_smtpSendFrom_desc' => 'A levél feladója', -'settings_smtpSendTestMail' => '', -'settings_smtpSendTestMail_desc' => '', +'settings_smtpSendTestMail' => 'Teszt e-mail küldése', +'settings_smtpSendTestMail_desc' => 'Tesztlevelet küld az aktuális e-mail konfiguráció ellenőrzéséhez.', 'settings_smtpServer' => 'SMTP kiszolgáló gépnév', 'settings_smtpServer_desc' => 'SMTP kiszolgáló gépnév', 'settings_smtpUser' => 'SMTP kiszolgáló felhasználó', @@ -1551,7 +1551,7 @@ URL: [url]', 'settings_versiontolow' => 'túl alacsony verzió', 'settings_viewOnlineFileTypes' => 'Online állománytípus nézet', 'settings_viewOnlineFileTypes_desc' => 'A következő végződéssel rendelkező állományok megtekinthetők online (KIZÁRÓLAG KISBETŰS KARAKTEREKET HASZNÁLJON)', -'settings_webdav' => '', +'settings_webdav' => 'WebDAV', 'settings_workflowMode' => 'Munkafolyamat mód', 'settings_workflowMode_desc' => 'A részletes munkafolyamat engedélyezi saját kiadási munkafolyamat megadását a dokumentum változatokhoz.', 'settings_workflowMode_valadvanced' => 'részletes', @@ -1723,7 +1723,7 @@ URL: [url]', 'timeline_full_add_file' => '', 'timeline_full_add_version' => '', 'timeline_full_scheduled_revision' => '', -'timeline_full_status_change' => '', +'timeline_full_status_change' => '[document]Verzió [version]: [status]', 'timeline_scheduled_revision' => '', 'timeline_selected_item' => '', 'timeline_skip_add_file' => 'melléklet hozzáadva', @@ -1839,7 +1839,7 @@ Szülő mappa: [folder_path] Felhasználó: [username] URL: [url]', 'version_deleted_email_subject' => '[sitename]: [name] - Változat törölve', -'version_info' => 'Változat információ', +'version_info' => 'Verzió információ', 'view' => 'Nézet', 'view_online' => 'Online megtekintés', 'warning' => 'Figyelmeztetés', @@ -1878,7 +1878,7 @@ URL: [url]', 'workflow_transition_without_user_group' => '', 'workflow_user_summary' => 'Felhasználó áttekintés', 'wrong_filetype' => '', -'x_more_objects' => '', +'x_more_objects' => '[number] további tétel', 'year_view' => 'Éves nézet', 'yes' => 'Igen', 'zh_CN' => 'Kínai (CN)', diff --git a/languages/it_IT/lang.inc b/languages/it_IT/lang.inc index 1aa3c42c8..daf21b6b4 100644 --- a/languages/it_IT/lang.inc +++ b/languages/it_IT/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (2020), rickr (144), s.pnt (26) +// Translators: Admin (2021), rickr (144), s.pnt (26) $text = array( '2_factor_auth' => 'Autorizzazione a due fattori', @@ -803,7 +803,7 @@ URL: [url]', 'my_documents' => 'Documenti personali', 'my_transmittals' => 'Mie trasmissioni', 'name' => 'Nome', -'nb_NO' => 'Norvegese', +'nb_NO' => 'Norvegiese (Bokmål)', 'needs_correction' => 'Necessita correzioni', 'needs_workflow_action' => 'Il documento richiede attenzione. Prego controllare il flusso di lavoro.', 'network_drive' => 'Network drive', diff --git a/languages/nl_NL/lang.inc b/languages/nl_NL/lang.inc index 86f12a25b..e65db868f 100644 --- a/languages/nl_NL/lang.inc +++ b/languages/nl_NL/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (778), gijsbertush (651), pepijn (45), reinoutdijkstra@hotmail.com (270) +// Translators: Admin (779), gijsbertush (651), pepijn (45), reinoutdijkstra@hotmail.com (270) $text = array( '2_factor_auth' => '2-factor-authenticatie', @@ -1100,7 +1100,7 @@ URL: [url]', 'revision_status' => 'Status revisie', 'revision_submit_email_body' => '', 'revision_submit_email_subject' => '', -'revision_summary' => '', +'revision_summary' => 'Revisie samenvatting', 'revisors' => 'Herzieners', 'revisor_already_assigned' => 'Gebruiker is reeds herziener', 'revisor_already_removed' => 'Herziener reeds verwijderd', diff --git a/languages/pl_PL/lang.inc b/languages/pl_PL/lang.inc index afb7b95a5..12d9bebdb 100644 --- a/languages/pl_PL/lang.inc +++ b/languages/pl_PL/lang.inc @@ -19,14 +19,14 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (867), netixw (84), romi (93), uGn (112) +// Translators: Admin (871), netixw (84), romi (93), uGn (112) $text = array( '2_factor_auth' => '', '2_factor_auth_info' => '', '2_fact_auth_secret' => '', 'accept' => 'Akceptuj', -'access_control' => '', +'access_control' => 'Kontrola dostępu', 'access_control_is_off' => '', 'access_denied' => 'Dostęp zabroniony.', 'access_inheritance' => 'Dziedziczenie dostępu', @@ -1089,7 +1089,7 @@ URL: [url]', 'role_admin' => 'Administrator', 'role_guest' => 'Gość', 'role_info' => '', -'role_management' => '', +'role_management' => 'Zarządzanie rolam', 'role_name' => '', 'role_type' => '', 'role_user' => 'Użytkownik', @@ -1112,7 +1112,7 @@ URL: [url]', 'scheduler_class_description' => '', 'scheduler_class_parameter' => '', 'scheduler_class_tasks' => '', -'scheduler_task_mgr' => '', +'scheduler_task_mgr' => 'Zadania', 'search' => 'Szukaj', 'search_fulltext' => 'Przeszukaj całe teksty', 'search_in' => 'Szukaj w', @@ -1810,7 +1810,7 @@ URL: [url]', 'versioning_file_creation_warning' => 'Ta operacja utworzy plik zawierający informacje o wersjach plików z całego wskazanego folderu. Po utworzeniu, każdy plik będzie zapisany w folderze odpowiednim dla danego dokumentu.', 'versioning_info' => 'Informacje o wersjach', 'versiontolow' => 'Za niska wersja', -'version_comment' => '', +'version_comment' => 'Opis wersji', 'version_deleted_email' => 'Wersja usunięta', 'version_deleted_email_body' => 'Wersja została usunięta Dokument: [name] diff --git a/languages/ro_RO/lang.inc b/languages/ro_RO/lang.inc index be6d9d98a..d6d43ba4e 100644 --- a/languages/ro_RO/lang.inc +++ b/languages/ro_RO/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1097), balan (87) +// Translators: Admin (1099), balan (87) $text = array( '2_factor_auth' => '', @@ -798,7 +798,7 @@ URL: [url]', 'my_documents' => 'Documentele Mele', 'my_transmittals' => 'Trimiterile mele', 'name' => 'Nume', -'nb_NO' => '', +'nb_NO' => 'Norvegiana', 'needs_correction' => '', 'needs_workflow_action' => 'Acest document necesită atenția dumneavoastră. Vă rugăm să verificați tab-ul workflow.', 'network_drive' => '', @@ -1195,7 +1195,7 @@ URL: [url]', 'select_ind_reviewers' => 'Click pentru a selecta un revizuitor individual', 'select_ind_revisors' => 'Faceti click pentru a selecta retrimitori individuali', 'select_one' => 'Selectați unul', -'select_user' => '', +'select_user' => 'Selecteaza utilizator', 'select_users' => 'Click pentru a selecta utilizatori', 'select_value' => 'Valoare selectata', 'select_workflow' => 'Selectați workflow', diff --git a/languages/ru_RU/lang.inc b/languages/ru_RU/lang.inc index 67a762ac4..e5991b686 100644 --- a/languages/ru_RU/lang.inc +++ b/languages/ru_RU/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1678) +// Translators: Admin (1681) $text = array( '2_factor_auth' => 'Двухфакторная аутентификация', @@ -141,7 +141,7 @@ URL: [url]', 'archive_creation_warning' => 'Эта операция создаст архив, содержащий все каталоги. После создания архив будет сохранен в каталоге данных сервера.Внимание: архив созданный как понятный человеку, будет непригоден в качестве резервной копии для восстановления!', 'ar_EG' => 'Arabic', 'assign_approvers' => 'Назначить утверждающих', -'assign_recipients' => '', +'assign_recipients' => 'Указать получателей', 'assign_reviewers' => 'Назначить рецензентов', 'assign_user_property_to' => 'Назначить свойства пользователя', 'assumed_released' => 'Утверждён', @@ -799,7 +799,7 @@ URL: [url]', 'my_transmittals' => 'Мои пересылки', 'name' => 'Имя', 'nb_NO' => 'Норвежский', -'needs_correction' => '', +'needs_correction' => 'Нужны правки', 'needs_workflow_action' => 'Этот документ требует вашего внимания. См. вкладку «Процесс».', 'network_drive' => 'Сетевой диск', 'never' => 'никогда', @@ -1189,7 +1189,7 @@ URL: [url]', 'select_grp_approvers' => 'Выберите утверждающую группу', 'select_grp_ind_approvers' => 'Выберите группу', 'select_grp_ind_notification' => 'Выберите группу', -'select_grp_ind_recipients' => '', +'select_grp_ind_recipients' => 'Щелкните для выбора группы', 'select_grp_ind_reviewers' => 'Выберите группу', 'select_grp_ind_revisors' => '', 'select_grp_notification' => 'Выберите группу для уведомления', diff --git a/languages/sv_SE/lang.inc b/languages/sv_SE/lang.inc index fb92b16d4..fdf9e2f9e 100644 --- a/languages/sv_SE/lang.inc +++ b/languages/sv_SE/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1161), MagnusI (649), tmichelfelder (106) +// Translators: Admin (1162), MagnusI (649), tmichelfelder (106) $text = array( '2_factor_auth' => '2-faktors autentisering', @@ -804,7 +804,7 @@ URL: [url]', 'my_documents' => 'Mina dokument', 'my_transmittals' => 'Mina överföringar', 'name' => 'Namn', -'nb_NO' => '', +'nb_NO' => 'Norska (Bokmål)', 'needs_correction' => '', 'needs_workflow_action' => 'Detta dokument behöver din uppmärksamhet. Kontrollera inställningarna för arbetsflödet.', 'network_drive' => 'Nätverkslagring', diff --git a/languages/tr_TR/lang.inc b/languages/tr_TR/lang.inc index 3a1836370..43ffc5b9c 100644 --- a/languages/tr_TR/lang.inc +++ b/languages/tr_TR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1094), aydin (83) +// Translators: Admin (1095), aydin (83) $text = array( '2_factor_auth' => '', @@ -792,7 +792,7 @@ URL: [url]', 'my_documents' => 'Dokümanlarım', 'my_transmittals' => '', 'name' => 'İsim', -'nb_NO' => '', +'nb_NO' => 'Norveç Havayolları', 'needs_correction' => '', 'needs_workflow_action' => 'Bu doküman dikkatinizi gerektiriyor. Lütfen iş akış sekmesini kontrol ediniz.', 'network_drive' => '', diff --git a/languages/zh_CN/lang.inc b/languages/zh_CN/lang.inc index b04c861ed..7a888f5e7 100644 --- a/languages/zh_CN/lang.inc +++ b/languages/zh_CN/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (766), archonwang (469), fengjohn (5), yang86 (1) +// Translators: Admin (770), archonwang (469), fengjohn (5), yang86 (1) $text = array( '2_factor_auth' => '双重认证', @@ -517,7 +517,7 @@ URL: [url]', 'event_details' => '错误详情', 'exclude_items' => '排除项目', 'expired' => '过期', -'expired_at_date' => '', +'expired_at_date' => '过期时间', 'expired_documents' => '过期文档', 'expires' => '有效限期', 'expire_by_date' => '指定过期时间', @@ -786,9 +786,9 @@ URL: [url]', 'move_folder' => '移动文件夹', 'my_account' => '我的账户', 'my_documents' => '我的文档', -'my_transmittals' => '', +'my_transmittals' => '我的送达函', 'name' => '名称', -'nb_NO' => '', +'nb_NO' => '挪威语(书面挪威语)', 'needs_correction' => '', 'needs_workflow_action' => '', 'network_drive' => '网络驱动器', @@ -1125,7 +1125,7 @@ URL: [url]', 'scheduler_class_description' => '', 'scheduler_class_parameter' => '', 'scheduler_class_tasks' => '', -'scheduler_task_mgr' => '', +'scheduler_task_mgr' => '排程表', 'search' => '搜索', 'search_fulltext' => '全文检索', 'search_in' => '搜索于', diff --git a/op/op.AddDocument.php b/op/op.AddDocument.php index c8159b6fb..37804bc88 100644 --- a/op/op.AddDocument.php +++ b/op/op.AddDocument.php @@ -76,7 +76,7 @@ if ($accessop->check_controller_access($controller, array('action'=>'setOwner')) $owner = $user; } $comment = trim($_POST["comment"]); -$version_comment = trim($_POST["version_comment"]); +$version_comment = !empty($_POST["version_comment"]) ? trim($_POST["version_comment"]) : ''; if($version_comment == "" && isset($_POST["use_comment"])) $version_comment = $comment; @@ -408,10 +408,14 @@ if(!empty($_POST['notification_groups'])) { } /* Check files for Errors first */ +$maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); for ($file_num=0;$file_num $folder->getName())),getMLText("uploading_zerosize")); } + if ($maxuploadsize && $_FILES["userfile"]["size"][$file_num] > $maxuploadsize) { + UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("uploading_maxsize")); + } if (/* is_uploaded_file($_FILES["userfile"]["tmp_name"][$file_num]) && */$_FILES['userfile']['error'][$file_num]!=0){ UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("uploading_failed")); } diff --git a/op/op.AddFile.php b/op/op.AddFile.php index 8b3a8022a..3eb2d566f 100644 --- a/op/op.AddFile.php +++ b/op/op.AddFile.php @@ -62,10 +62,14 @@ if(isset($_POST[$prefix.'-fine-uploader-uuids']) && $_POST[$prefix.'-fine-upload } } +$maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); for ($file_num=0;$file_num $document->getName())),getMLText("uploading_zerosize")); } + if ($maxuploadsize && $_FILES["userfile"]["size"][$file_num] > $maxuploadsize) { + UI::exitError(getMLText("folder_title", array("documentname" => $document->getName())),getMLText("uploading_maxsize")); + } if (is_uploaded_file($_FILES["userfile"]["tmp_name"][$file_num]) && $_FILES['userfile']['error'][$file_num] != 0){ UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("uploading_failed")); } diff --git a/op/op.Ajax.php b/op/op.Ajax.php index 6c7774367..812eddf58 100644 --- a/op/op.Ajax.php +++ b/op/op.Ajax.php @@ -666,6 +666,13 @@ switch($command) { exit; } + $maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); + if ($maxuploadsize && $_FILES["userfile"]["size"] > $maxuploadsize) { + header('Content-Type: application/json'); + echo json_encode(array('success'=>false, 'message'=>getMLText("uploading_maxsize"))); + exit; + } + $userfiletmp = $_FILES["userfile"]["tmp_name"]; $userfiletype = $_FILES["userfile"]["type"]; $userfilename = $_FILES["userfile"]["name"]; diff --git a/op/op.SchedulerTaskMgr.php b/op/op.SchedulerTaskMgr.php index ca0ce4ea2..8b327b468 100644 --- a/op/op.SchedulerTaskMgr.php +++ b/op/op.SchedulerTaskMgr.php @@ -66,7 +66,7 @@ if ($action == "addtask") { /* {{{ */ add_log_line(".php&action=addtask&name=".$name); } /* }}} */ -// modify transmittal ---------------------------------------------------- +// modify task ---------------------------------------------------- else if ($action == "edittask") { /* {{{ */ /* Check if the form data comes for a trusted request */ @@ -90,7 +90,7 @@ else if ($action == "edittask") { /* {{{ */ $frequency = $_POST["frequency"]; $disabled = isset($_POST["disabled"]) ? $_POST["disabled"] : 0; $params = $_POST["params"]; - + if ($editedtask->getName() != $name) $editedtask->setName($name); if ($editedtask->getDescription() != $description) @@ -104,5 +104,40 @@ else if ($action == "edittask") { /* {{{ */ add_log_line(".php&action=edittask&taskid=".$taskid); } /* }}} */ +// delete task ------------------------------------------------------------- +else if ($action == "removetask") { /* {{{ */ + header('Content-Type: application/json'); + + /* Check if the form data comes from a trusted request */ + if(!checkFormKey('removetask')) { + echo json_encode(array('success'=>false, 'message'=>getMLText("invalid_request_token"))); + exit; + } + + if (!isset($_POST["taskid"]) || !is_numeric($_POST["taskid"]) || intval($_POST["taskid"])<1) { + echo json_encode(array('success'=>false, 'message'=>getMLText("invalid_task"))); + exit; + } + + $taskid=$_POST["taskid"]; + $task = $scheduler->getTask($taskid); + + if (!is_object($task)) { + echo json_encode(array('success'=>false, 'message'=>getMLText("invalid_task"))); + exit; + } + + if (!$task->remove()) { + echo json_encode(array('success'=>false, 'message'=>getMLText("error_occured"))); + exit; + } + + add_log_line("?taskid=".$_POST["taskid"]."&action=removetask"); + + echo json_encode(array('success'=>true, 'message'=>getMLText("task_removed"))); + exit; +} /* }}} */ + + header("Location:../out/out.SchedulerTaskMgr.php"); diff --git a/op/op.SetRevisors.php b/op/op.SetRevisors.php index 56cff04d6..8314c506c 100644 --- a/op/op.SetRevisors.php +++ b/op/op.SetRevisors.php @@ -212,7 +212,7 @@ if (count($revisionIndex["i"]) > 0) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("recipient_already_removed")); break; case -4: - // email error + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("recipient_was_active")); break; } } @@ -315,7 +315,7 @@ if (count($revisionIndex["g"]) > 0) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("recipient_already_removed")); break; case -4: - // email error + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("recipient_was_active")); break; } } @@ -323,6 +323,11 @@ if (count($revisionIndex["g"]) > 0) { } } +/* If all revisors has been removed, then clear the next revision date */ +if(!$pIndRev && !$pGrpRev) { + $content->setRevisionDate(false); +} + /* Recheck status, because all revisors could have been removed */ $content->verifyStatus(false, $user, getMLText('automatic_status_update'), $settings->_initialDocumentStatus); diff --git a/op/op.UpdateDocument.php b/op/op.UpdateDocument.php index 0006cb6c1..1081f30db 100644 --- a/op/op.UpdateDocument.php +++ b/op/op.UpdateDocument.php @@ -91,6 +91,11 @@ if (isset($_FILES['userfile']) && $_FILES['userfile']['error'] == 0) { if($_FILES["userfile"]["size"] == 0) UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("uploading_zerosize")); + $maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); + if ($maxuploadsize && $_FILES["userfile"]["size"] > $maxuploadsize) { + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("uploading_maxsize")); + } + $userfiletmp = $_FILES["userfile"]["tmp_name"]; $userfiletype = $_FILES["userfile"]["type"]; $userfilename = $_FILES["userfile"]["name"]; diff --git a/out/out.AddDocument.php b/out/out.AddDocument.php index d8c442a82..8351afc35 100644 --- a/out/out.AddDocument.php +++ b/out/out.AddDocument.php @@ -91,7 +91,6 @@ if($view) { $view->setParam('presetexpiration', $settings->_presetExpirationDate); $view->setParam('sortusersinlist', $settings->_sortUsersInList); $view->setParam('defaultposition', $settings->_defaultDocPosition); - $view->setParam('maxuploadsize', $settings->_maxUploadSize); $view->setParam('orderby', $settings->_sortFoldersDefault); $view->setParam('accessobject', $accessop); $view($_GET); diff --git a/out/out.TransmittalMgr.php b/out/out.TransmittalMgr.php index 2e7c789ff..3ce4fd276 100644 --- a/out/out.TransmittalMgr.php +++ b/out/out.TransmittalMgr.php @@ -47,6 +47,7 @@ if(isset($_GET['transmittalid']) && $_GET['transmittalid']) { if($view) { $view->setParam('seltransmittal', $seltransmittal); + $view->setParam('showtree', showtree()); $view->setParam('cachedir', $settings->_cacheDir); $view->setParam('timeout', $settings->_cmdTimeout); $view->setParam('previewWidthList', $settings->_previewWidthList); diff --git a/styles/bootstrap/application.css b/styles/bootstrap/application.css index 7427e89c7..aac713b83 100644 --- a/styles/bootstrap/application.css +++ b/styles/bootstrap/application.css @@ -60,6 +60,10 @@ ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover { font-weight: bold; } +legend > span { + float: right; +} + td.today { background-color: rgb(255, 200, 0); } @@ -158,6 +162,21 @@ div.splash { display: none; } +div.clipboard-container { + position: fixed; + left: 10px; + top: 40px; + width: 29.8%; + background: white; + border: 1px solid #d4d4d4; + border-radius: 5px; + padding: 10px; + height: 500px; + margin: 10px; + overflow-y: auto; + overflow-x: hidden; +} + div.statusbar-container { display: none; position: fixed; diff --git a/styles/bootstrap/application.js b/styles/bootstrap/application.js index 776c91b1e..134de9da2 100644 --- a/styles/bootstrap/application.js +++ b/styles/bootstrap/application.js @@ -166,6 +166,12 @@ $(document).ready( function() { } }); /* }}} */ + $('body').on('click', '#clipboard-float', function(ev) { /* {{{ */ + ev.preventDefault(); + ev.stopPropagation(); + $('#clipboard-container').toggleClass('clipboard-container'); + }); /* }}} */ + $('body').on('click', 'a.addtoclipboard', function(ev) { /* {{{ */ ev.preventDefault(); ev.stopPropagation(); @@ -178,7 +184,7 @@ $(document).ready( function() { function(data) { if(data.success) { $("#main-clipboard").html('Loading').load('../out/out.Clipboard.php?action=mainclipboard') - $("#menu-clipboard").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') + $("#menu-clipboard div").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') noty({ text: attr_msg, type: 'success', @@ -213,7 +219,7 @@ $(document).ready( function() { function(data) { if(data.success) { $("#main-clipboard").html('Loading').load('../out/out.Clipboard.php?action=mainclipboard') - $("#menu-clipboard").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') + $("#menu-clipboard div").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') noty({ text: attr_msg, type: 'success', @@ -451,7 +457,7 @@ $(document).ready( function() { if(data.success) { if(element.data('param1') == 'command=clearclipboard') { $("#main-clipboard").html('Loading').load('../out/out.Clipboard.php?action=mainclipboard') - $("#menu-clipboard").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') + $("#menu-clipboard div").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') } noty({ text: data.message, @@ -492,7 +498,7 @@ function onAddClipboard(ev) { /* {{{ */ function(data) { if(data.success) { $("#main-clipboard").html('Loading').load('../out/out.Clipboard.php?action=mainclipboard') - $("#menu-clipboard").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') + $("#menu-clipboard div").html('Loading').load('../out/out.Clipboard.php?action=menuclipboard') noty({ text: data.message, type: 'success', @@ -758,18 +764,18 @@ $(document).ready(function() { /* {{{ */ attr_rel = $(e.currentTarget).data('droptarget'); target_type = attr_rel.split("_")[0]; target_id = attr_rel.split("_")[1]; - target_name = $(e.currentTarget).data('name') + target_name = $(e.currentTarget).data('name')+''; // Force this to be a string if(target_type == 'folder') { var files = e.originalEvent.dataTransfer.files; if(files.length > 0) { - console.log('Drop '+files.length+' files on '+target_type+' '+target_id); +// console.log('Drop '+files.length+' files on '+target_type+' '+target_id); SeedDMSUpload.handleFileUpload(files,$(e.currentTarget),$('div.statusbar-container h1')/*$(e.currentTarget).find("span")*/); } else { var source_info = JSON.parse(e.originalEvent.dataTransfer.getData("text")); source_type = source_info.type; source_id = source_info.id; formtoken = source_info.formtoken; - console.log('Drop '+source_type+' '+source_id+' on '+target_type+' '+target_id); +// console.log('Drop '+source_type+' '+source_id+' on '+target_type+' '+target_id); if(source_type == 'document') { var bootbox_message = trans.confirm_move_document; if(source_info.name) @@ -863,14 +869,14 @@ $(document).ready(function() { /* {{{ */ } else if(target_type == 'document') { var files = e.originalEvent.dataTransfer.files; if(files.length > 0) { - console.log('Drop '+files.length+' files on '+target_type+' '+target_id); +// console.log('Drop '+files.length+' files on '+target_type+' '+target_id); SeedDMSUpload.handleFileUpload(files,$(e.currentTarget),$('div.statusbar-container h1')/*$(e.currentTarget).find("span")*/); } else { var source_info = JSON.parse(e.originalEvent.dataTransfer.getData("text")); source_type = source_info.type; source_id = source_info.id; formtoken = source_info.formtoken; - console.log('Drop '+source_type+' '+source_id+' on '+target_type+' '+target_id); +// console.log('Drop '+source_type+' '+source_id+' on '+target_type+' '+target_id); if(source_type == 'document') { if(source_id != target_id) { bootbox.dialog(trans.confirm_transfer_link_document, [{ @@ -956,7 +962,7 @@ $(document).ready(function() { /* {{{ */ id : attr_rel.split("_")[1], type : "folder", formtoken : $(e.target).attr('formtoken'), - name: $(e.target).data('name') + name: $(e.target).data('name')+'' }; /* Currently not used $.ajax({url: '../out/out.ViewFolder.php', @@ -982,7 +988,7 @@ $(document).ready(function() { /* {{{ */ id : attr_rel.split("_")[1], type : "document", formtoken : $(e.target).attr('formtoken'), - name: $(e.target).data('name') + name: $(e.target).data('name')+'' }; e.originalEvent.dataTransfer.setData("text", JSON.stringify(dragStartInfo)); }); diff --git a/styles/bootstrap/favicon.ico b/styles/bootstrap/favicon.ico index 890150f4c..7b4adcc9f 100644 Binary files a/styles/bootstrap/favicon.ico and b/styles/bootstrap/favicon.ico differ diff --git a/styles/bootstrap/fine-uploader/LICENSE b/styles/bootstrap/fine-uploader/LICENSE index 3814391a3..070caa60c 100644 --- a/styles/bootstrap/fine-uploader/LICENSE +++ b/styles/bootstrap/fine-uploader/LICENSE @@ -1,5 +1,7 @@ The MIT License (MIT) +Copyright (c) 2010-2012, Andrew Valums +Copyright (c) 2012-2013, Andrew Valums and Raymond S. Nicholus, III Copyright (c) 2013-present, Widen Enterprises, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/styles/bootstrap/fine-uploader/dnd.js b/styles/bootstrap/fine-uploader/dnd.js index 100061705..4beb73676 100644 --- a/styles/bootstrap/fine-uploader/dnd.js +++ b/styles/bootstrap/fine-uploader/dnd.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { var qq = function(element) { "use strict"; @@ -578,7 +578,7 @@ global.qq = qq; } })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -596,9 +596,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -636,7 +633,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -765,12 +766,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -798,6 +794,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -885,9 +889,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -927,8 +928,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -953,6 +956,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -1005,7 +1010,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -1088,6 +1093,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; })(window); //# sourceMappingURL=dnd.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.js.map b/styles/bootstrap/fine-uploader/dnd.js.map index dce774d90..853391d84 100644 --- a/styles/bootstrap/fine-uploader/dnd.js.map +++ b/styles/bootstrap/fine-uploader/dnd.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","options","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","disposeSupport","dropZoneElements","allowMultipleItems","classes","dropActive","callbacks","uploadDroppedFiles","files","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","fullPath","indexOfNameInFullPath","qqPath","fileError","code","isDirectory","getFilesInDirectory","allEntriesRead","entries","entriesLeft","readFailure","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","x","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","onLeave","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.indexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n file.qqPath = fullPath;\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","options","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","disposeSupport","dropZoneElements","allowMultipleItems","classes","dropActive","callbacks","uploadDroppedFiles","files","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","qqPath","extractDirectoryPath","fileError","fullPath","code","isDirectory","getFilesInDirectory","allEntriesRead","entries","entriesLeft","readFailure","indexOfNameInFullPath","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","x","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","_testing","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","onLeave","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n file.qqPath = extractDirectoryPath(entry);\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n function extractDirectoryPath(entry) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.lastIndexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n return fullPath;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.min.js b/styles/bootstrap/fine-uploader/dnd.min.js index 1841817de..bad4e2de0 100644 --- a/styles/bootstrap/fine-uploader/dnd.min.js +++ b/styles/bootstrap/fine-uploader/dnd.min.js @@ -1,3 +1,3 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(n,t){return e.addEventListener?e.addEventListener(n,t,!1):e.attachEvent&&e.attachEvent("on"+n,t),function(){qq(e).detach(n,t)}},detach:function(n,t){return e.removeEventListener?e.removeEventListener(n,t,!1):e.attachEvent&&e.detachEvent("on"+n,t),this},contains:function(n){return!!n&&(e===n||(e.contains?e.contains(n):!!(8&n.compareDocumentPosition(e))))},insertBefore:function(n){return n.parentNode.insertBefore(e,n),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(n){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=n.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(n.filter="alpha(opacity="+Math.round(100*n.opacity)+")"),qq.extend(e.style,n),this},hasClass:function(n,t){var r=new RegExp("(^| )"+n+"( |$)");return r.test(e.className)||!(!t||!r.test(e.parentNode.className))},addClass:function(n){return qq(e).hasClass(n)||(e.className+=" "+n),this},removeClass:function(n){var t=new RegExp("(^| )"+n+"( |$)");return e.className=e.className.replace(t," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(n,t){var r,o=[];return t&&e.querySelector?e.querySelector("."+n):e.querySelectorAll?e.querySelectorAll("."+n):(r=e.getElementsByTagName("*"),qq.each(r,function(e,t){qq(t).hasClass(n)&&o.push(t)}),t?o[0]:o)},getFirstByClass:function(n){return qq(e).getByClass(n,!0)},children:function(){for(var n=[],t=e.firstChild;t;)1===t.nodeType&&n.push(t),t=t.nextSibling;return n},setText:function(n){return e.innerText=n,e.textContent=n,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(n){var t;return e.hasAttribute?!!e.hasAttribute(n)&&null==/^false$/i.exec(e.getAttribute(n)):(t=e[n],void 0!==t&&null==/^false$/i.exec(t))}}};!function(){"use strict";qq.canvasToBlob=function(e,n,t){return qq.dataUriToBlob(e.toDataURL(n,t))},qq.dataUriToBlob=function(e){var n,t,r,o,i=function(e,n){var t=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,r=t&&new t;return r?(r.append(e),r.getBlob(n)):new Blob([e],{type:n})};return t=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],n=new ArrayBuffer(t.length),r=new Uint8Array(n),qq.each(t,function(e,n){r[e]=n.charCodeAt(0)}),i(n,o)},qq.log=function(e,n){window.console&&(n&&"info"!==n?window.console[n]?window.console[n](e):window.console.log("<"+n+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var n=Array.prototype.slice.call(arguments,1),t=e,r=t.indexOf("{}");return qq.each(n,function(e,n){var o=t.substring(0,r),i=t.substring(r+2);if(t=o+n+i,r=t.indexOf("{}",r+n.length),r<0)return!1}),t},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,n){var t=function(e){var t=e.toLowerCase();return n?"file"!==t:"file"===t};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&t(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&t(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,n,t){var r=e.slice||e.mozSlice||e.webkitSlice;return r.call(e,n,t)},qq.arrayBufferToHex=function(e){var n="",t=new Uint8Array(e);return qq.each(t,function(e,t){var r=t.toString(16);r.length<2&&(r="0"+r),n+=r}),n},qq.readBlobToHex=function(e,n,t){var r=qq.sliceBlob(e,n,n+t),o=new FileReader,i=new qq.Promise;return o.onload=function(){i.success(qq.arrayBufferToHex(o.result))},o.onerror=i.failure,o.readAsArrayBuffer(r),i},qq.extend=function(e,n,t){return qq.each(n,function(n,r){t&&qq.isObject(r)?(void 0===e[n]&&(e[n]={}),qq.extend(e[n],r,!0)):e[n]=r}),e},qq.override=function(e,n){var t={},r=n(t);return qq.each(r,function(n,r){void 0!==e[n]&&(t[n]=e[n]),e[n]=r}),e},qq.indexOf=function(e,n,t){if(e.indexOf)return e.indexOf(n,t);t=t||0;var r=e.length;for(t<0&&(t+=r);t=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(n){e.innerHTML=n;var t=e.firstChild;return e.removeChild(t),t}}(),qq.each=function(e,n){var t,r;if(e)if(window.Storage&&e.constructor===window.Storage)for(t=0;t0)return e.substr(n,e.length-n)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var n;do n=e.shift(),n&&n();while(n)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(n){e.push(n)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,n=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(n=!1)}catch(e){n=!1}return n}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function r(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function i(){return!!r()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function u(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function c(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var s,l,q,f,d,p,g,v,h,m,y,b,w,x,E;return s=e(),f=s&&qq.isXhrUploadSupported(),l=f&&!qq.androidStock(),q=f&&c(),d=q&&n(),p=f&&qq.isFileChunkingSupported(),g=f&&p&&u(),v=f&&t(),h=s&&(void 0!==window.postMessage||f),y=r(),m=o(),b=i(),w=a(),x=f&&void 0!==window.FileReader,E=function(){return!!f&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:f,blobUploading:l,canDetermineSize:f,chunking:p,deleteFileCors:b,deleteFileCorsXdr:m,deleteFileCorsXhr:y,dialogElement:!!window.HTMLDialogElement,fileDrop:q,folderDrop:d,folderSelection:w,imagePreviews:x,imageValidation:x,itemSizeValidation:f,pause:p,progressBar:E,resume:g,scaling:x&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:s,uploadCors:h,uploadCustomHeaders:f,uploadNonMultipart:f,uploadViaPaste:v}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,n,t=[],r=[],o=[],i=0;qq.extend(this,{then:function(o,a){return 0===i?(o&&t.push(o),a&&r.push(a)):i===-1?a&&a.apply(null,n):o&&o.apply(null,e),this},done:function(t){return 0===i?o.push(t):t.apply(null,void 0===n?e:n),this},success:function(){return i=1,e=arguments,t.length&&qq.each(t,function(n,t){t.apply(null,e)}),o.length&&qq.each(o,function(n,t){t.apply(null,e)}),this},failure:function(){return i=-1,n=arguments,r.length&&qq.each(r,function(e,t){t.apply(null,n)}),o.length&&qq.each(o,function(e,t){t.apply(null,n)}),this}})},qq.DragAndDrop=function(e){"use strict";function n(e,n){var t=Array.prototype.slice.call(e);s.callbacks.dropLog("Grabbed "+e.length+" dropped files."),n.dropDisabled(!1),s.callbacks.processingDroppedFilesComplete(t,n.getElement())}function t(e){var n=new qq.Promise;return e.isFile?e.file(function(t){var r=e.name,o=e.fullPath,i=o.indexOf(r);o=o.substr(0,i),"/"===o.charAt(0)&&(o=o.substr(1)),t.qqPath=o,d.push(t),n.success()},function(t){s.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+t.code+".","error"),n.failure()}):e.isDirectory&&r(e).then(function(e){var r=e.length;qq.each(e,function(e,o){t(o).done(function(){r-=1,0===r&&n.success()})}),e.length||n.success()},function(t){s.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+t.code+".","error"),n.failure()}),n}function r(e,n,t,o){var i=o||new qq.Promise,a=n||e.createReader();return a.readEntries(function(n){var o=t?t.concat(n):n;n.length?setTimeout(function(){r(e,a,o,i)},0):i.success(o)},i.failure),i}function o(e,n){var r=[],o=new qq.Promise;return s.callbacks.processingDroppedFiles(),n.dropDisabled(!0),e.files.length>1&&!s.allowMultipleItems?(s.callbacks.processingDroppedFilesComplete([]),s.callbacks.dropError("tooManyFilesError",""),n.dropDisabled(!1),o.failure()):(d=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,n){var i=n.webkitGetAsEntry();i&&(i.isFile?d.push(n.getAsFile()):r.push(t(i).done(function(){r.pop(),0===r.length&&o.success()})))}):d=e.files,0===r.length&&o.success()),o}function i(e){var t=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:l,element:e,onEnter:function(n){qq(e).addClass(s.classes.dropActive),n.stopPropagation()},onLeaveNotDescendants:function(n){qq(e).removeClass(s.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,t).then(function(){n(d,t)},function(){s.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return p.addDisposer(function(){t.dispose()}),qq(e).hasAttribute(q)&&qq(e).hide(),f.push(t),t}function a(e){var n;return qq.each(e.dataTransfer.types,function(e,t){if("Files"===t)return n=!0,!1}),n}function u(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function c(){var e=s.dropZoneElements,n=function(){setTimeout(function(){qq.each(e,function(e,n){qq(n).hasAttribute(q)&&qq(n).hide(),qq(n).removeClass(s.classes.dropActive)})},10)};qq.each(e,function(n,t){var r=i(t);e.length&&qq.supportedFeatures.fileDrop&&p.attach(document,"dragenter",function(n){!r.dropDisabled()&&a(n)&&qq.each(e,function(e,n){n instanceof HTMLElement&&qq(n).hasAttribute(q)&&qq(n).css({display:"block"})})})}),p.attach(document,"dragleave",function(e){u(e)&&n()}),p.attach(qq(document).children()[0],"mouseenter",function(e){n()}),p.attach(document,"drop",function(e){e.preventDefault(),n()}),p.attach(document,l,n)}var s,l="qq-hidezones",q="qq-hide-dropzone",f=[],d=[],p=new qq.DisposeSupport;s={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(s,e,!0),c(),qq.extend(this,{setupExtraDropzone:function(e){s.dropZoneElements.push(e),i(e)},removeDropzone:function(e){var n,t=s.dropZoneElements;for(n in t)if(t[n]===e)return t.splice(n,1)},dispose:function(){p.dispose(),qq.each(f,function(e,n){n.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,n){},dropError:function(e,n){qq.log("Drag & drop error code '"+e+" with these specifics: '"+n+"'","error")},dropLog:function(e,n){qq.log(e,n)}}},qq.UploadDropZone=function(e){"use strict";function n(){return qq.safari()||qq.firefox()&&qq.windows()}function t(e){l||(n?q.attach(document,"dragover",function(e){e.preventDefault()}):q.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),l=!0)}function r(e){if(!qq.supportedFeatures.fileDrop)return!1;var n,t=e.dataTransfer,r=qq.safari();return n=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==t.effectAllowed,t&&n&&(t.files||!r&&t.types.contains&&t.types.contains("Files"))}function o(e){return void 0!==e&&(s=e),s}function i(){function e(){n=document.createEvent("Event"),n.initEvent(u.HIDE_ZONES_EVENT_NAME,!0,!0)}var n;if(window.CustomEvent)try{n=new CustomEvent(u.HIDE_ZONES_EVENT_NAME)}catch(n){e()}else e();document.dispatchEvent(n)}function a(){q.attach(c,"dragover",function(e){if(r(e)){var n=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===n||"linkMove"===n?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),q.attach(c,"dragenter",function(e){if(!o()){if(!r(e))return;u.onEnter(e)}}),q.attach(c,"dragleave",function(e){if(r(e)){u.onLeave(e);var n=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(n)||u.onLeaveNotDescendants(e)}}),q.attach(c,"drop",function(e){if(!o()){if(!r(e))return;e.preventDefault(),e.stopPropagation(),u.onDrop(e),i()}})}var u,c,s,l,q=new qq.DisposeSupport;u={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(u,e),c=u.element,t(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){q.dispose()},getElement:function(){return c}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var r=new RegExp("(^| )"+t+"( |$)");return r.test(e.className)||!(!n||!r.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var r,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(r=e.getElementsByTagName("*"),qq.each(r,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,r,o,i=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,r=n&&new n;return r?(r.append(e),r.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),r=new Uint8Array(t),qq.each(n,function(e,t){r[e]=t.charCodeAt(0)}),i(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,r=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,r)+t+n.substring(r+2),r=n.indexOf("{}",r+t.length),r<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var r=n.toString(16);r.length<2&&(r="0"+r),t+=r}),t},qq.readBlobToHex=function(e,t,n){var r=qq.sliceBlob(e,t,t+n),o=new FileReader,i=new qq.Promise;return o.onload=function(){i.success(qq.arrayBufferToHex(o.result))},o.onerror=i.failure,o.readAsArrayBuffer(r),i},qq.extend=function(e,t,n){return qq.each(t,function(t,r){n&&qq.isObject(r)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],r,!0)):e[t]=r}),e},qq.override=function(e,t){var n={},r=t(n);return qq.each(r,function(t,r){void 0!==e[t]&&(n[t]=e[t]),e[t]=r}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var r=e.length;for(n<0&&(n+=r);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,r;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function r(){return void 0!==window.XDomainRequest}function o(){return!!n()||r()}function i(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function u(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var c,s,l,q,f,d,p,g,h,v,m,y,b,w,x;return c=e(),q=c&&qq.isXhrUploadSupported(),s=q&&!qq.androidStock(),l=q&&u(),f=l&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),d=q&&qq.isFileChunkingSupported(),p=q&&d&&a(),g=q&&t(),h=c&&(void 0!==window.postMessage||q),m=n(),v=r(),y=o(),b=i(),w=q&&void 0!==window.FileReader,x=function(){return!!q&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:q,blobUploading:s,canDetermineSize:q,chunking:d,deleteFileCors:y,deleteFileCorsXdr:v,deleteFileCorsXhr:m,dialogElement:!!window.HTMLDialogElement,fileDrop:l,folderDrop:f,folderSelection:b,imagePreviews:w,imageValidation:w,itemSizeValidation:q,pause:d,progressBar:x,resume:p,scaling:w&&s,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:c,uploadCors:h,uploadCustomHeaders:q,uploadNonMultipart:q,uploadViaPaste:g}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],r=[],o=[],i=0;qq.extend(this,{then:function(o,a){return 0===i?(o&&n.push(o),a&&r.push(a)):i===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===i?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return i=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return i=-1,t=arguments,r.length&&qq.each(r,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.DragAndDrop=function(e){"use strict";function t(e,t){var n=Array.prototype.slice.call(e);l.callbacks.dropLog("Grabbed "+e.length+" dropped files."),t.dropDisabled(!1),l.callbacks.processingDroppedFilesComplete(n,t.getElement())}function n(e){var t=new qq.Promise;return e.isFile?e.file(function(n){n.qqPath=r(e),f.push(n),t.success()},function(n){l.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+n.code+".","error"),t.failure()}):e.isDirectory&&o(e).then(function(e){var r=e.length;qq.each(e,function(e,o){n(o).done(function(){r-=1,0===r&&t.success()})}),e.length||t.success()},function(n){l.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+n.code+".","error"),t.failure()}),t}function r(e){var t=e.name,n=e.fullPath,r=n.lastIndexOf(t);return n=n.substr(0,r),"/"===n.charAt(0)&&(n=n.substr(1)),n}function o(e,t,n,r){var i=r||new qq.Promise,a=t||e.createReader();return a.readEntries(function(t){var r=n?n.concat(t):t;t.length?setTimeout(function(){o(e,a,r,i)},0):i.success(r)},i.failure),i}function i(e,t){var r=[],o=new qq.Promise;return l.callbacks.processingDroppedFiles(),t.dropDisabled(!0),e.files.length>1&&!l.allowMultipleItems?(l.callbacks.processingDroppedFilesComplete([]),l.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(f=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var i=t.webkitGetAsEntry();i&&(i.isFile?f.push(t.getAsFile()):r.push(n(i).done(function(){r.pop(),0===r.length&&o.success()})))}):f=e.files,0===r.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(l.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(l.classes.dropActive)},onDrop:function(e){i(e.dataTransfer,n).then(function(){t(f,n)},function(){l.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return d.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),q.push(n),n}function u(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function c(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function s(){var e=l.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(l.classes.dropActive)})},10)};qq.each(e,function(t,n){var r=a(n);e.length&&qq.supportedFeatures.fileDrop&&d.attach(document,"dragenter",function(t){!r.dropDisabled()&&u(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),d.attach(document,"dragleave",function(e){c(e)&&t()}),d.attach(qq(document).children()[0],"mouseenter",function(e){t()}),d.attach(document,"drop",function(e){u(e)&&(e.preventDefault(),t())}),d.attach(document,"qq-hidezones",t)}var l,q=[],f=[],d=new qq.DisposeSupport;l={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(l,e,!0),s(),qq.extend(this,{setupExtraDropzone:function(e){l.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=l.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){d.dispose(),qq.each(q,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=r},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){l||(t?q.attach(document,"dragover",function(e){e.preventDefault()}):q.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),l=!0)}function r(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,r=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!r&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(s=e),s}function i(){function e(){t=document.createEvent("Event"),t.initEvent(u.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(u.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){q.attach(c,"dragover",function(e){if(r(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),q.attach(c,"dragenter",function(e){if(!o()){if(!r(e))return;u.onEnter(e)}}),q.attach(c,"dragleave",function(e){if(r(e)){u.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||u.onLeaveNotDescendants(e)}}),q.attach(c,"drop",function(e){if(!o()){if(!r(e))return;e.preventDefault(),e.stopPropagation(),u.onDrop(e),i()}})}var u,c,s,l,q=new qq.DisposeSupport;u={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(u,e),c=u.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){q.dispose()},getElement:function(){return c}}),this._testing={},this._testing.isValidFileDrag=r}}(window); //# sourceMappingURL=dnd.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.min.js.map b/styles/bootstrap/fine-uploader/dnd.min.js.map index 09622593c..3927f6621 100644 --- a/styles/bootstrap/fine-uploader/dnd.min.js.map +++ b/styles/bootstrap/fine-uploader/dnd.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","uploadDroppedFiles","files","uploadDropZone","filesAsArray","options","callbacks","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","code","isDirectory","getFilesInDirectory","entries","entriesLeft","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","classes","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","disposeSupport","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","x","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","onLeave","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.indexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n file.qqPath = fullPath;\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","uploadDroppedFiles","files","uploadDropZone","filesAsArray","options","callbacks","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","code","isDirectory","getFilesInDirectory","entries","entriesLeft","indexOfNameInFullPath","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","classes","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","disposeSupport","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","x","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","_testing","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","onLeave","relatedTarget","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n file.qqPath = extractDirectoryPath(entry);\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n function extractDirectoryPath(entry) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.lastIndexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n return fullPath;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css index 4e3a3b075..ecdadfe0a 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css @@ -1 +1 @@ -.qq-gallery .qq-btn{float:right;border:none;padding:0;margin:0;box-shadow:none}.qq-gallery .qq-upload-button{display:inline;width:105px;padding:7px 10px;float:left;text-align:center;background:#00ABC7;color:#FFF;border-radius:2px;border:1px solid #37B7CC;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-gallery .qq-upload-button-hover{background:#33B6CC}.qq-gallery .qq-upload-button-focus{outline:#000 dotted 1px}.qq-gallery.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;border:1px dashed #CCC;background-color:#FAFAFA;padding:20px}.qq-gallery.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25;filter:alpha(opacity=25)}.qq-gallery .qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#F9F9F9;border-radius:4px;text-align:center}.qq-gallery .qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-gallery .qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-gallery .qq-upload-drop-area-active{background:#FDFDFD;border-radius:4px}.qq-gallery .qq-upload-list{margin:0;padding:10px 0 0;list-style:none;max-height:450px;overflow-y:auto;clear:both;box-shadow:none}.qq-gallery .qq-upload-list li{display:inline-block;position:relative;max-width:120px;margin:0 25px 25px 0;padding:0;line-height:16px;font-size:13px;color:#424242;background-color:#FFF;border-radius:2px;box-shadow:0 1px 1px 0 rgba(0,0,0,.22);vertical-align:top;height:186px}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-failed-text,.qq-gallery .qq-upload-pause,.qq-gallery .qq-upload-retry,.qq-gallery .qq-upload-size,.qq-gallery .qq-upload-spinner{display:inline}.qq-gallery .qq-upload-continue:hover,.qq-gallery .qq-upload-delete:hover,.qq-gallery .qq-upload-pause:hover,.qq-gallery .qq-upload-retry:hover{background-color:transparent}.qq-gallery .qq-upload-cancel,.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{cursor:pointer}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{border:none;background:0 0;color:#00A0BA;font-size:12px;padding:0}.qq-gallery .qq-upload-status-text{color:#333;font-size:12px;padding-left:3px;padding-top:2px;display:none;width:108px}.qq-gallery .qq-upload-fail .qq-upload-status-text{text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;display:block}.qq-gallery .qq-upload-retrying .qq-upload-status-text{display:inline-block}.qq-gallery .qq-upload-retrying .qq-progress-bar-container{display:none}.qq-gallery .qq-upload-cancel{background-color:#525252;color:#F7F7F7;font-weight:700;font-family:Arial,Helvetica,sans-serif;border-radius:12px;border:none;height:22px;width:22px;padding:4px;position:absolute;right:-5px;top:-6px;margin:0;line-height:17px}.qq-gallery .qq-upload-cancel:hover{background-color:#525252}.qq-gallery .qq-upload-retry{cursor:pointer;position:absolute;top:30px;left:50%;margin-left:-31px;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 4px 4px rgba(0,0,0,.5),0 -2px 12px rgba(0,0,0,.08) inset;padding:3px 4px;border:1px solid #d2ddc7;border-radius:2px;color:inherit;background-color:#EBF6E0;z-index:1}.qq-gallery .qq-upload-retry:hover{background-color:#f7ffec}.qq-gallery .qq-file-info{padding:10px 6px 4px;margin-top:-3px;border-radius:0 0 2px 2px;text-align:left;overflow:hidden}.qq-gallery .qq-file-info .qq-file-name{position:relative}.qq-gallery .qq-upload-file{display:block;margin-right:0;margin-bottom:3px;width:auto;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden}.qq-gallery .qq-upload-spinner{display:inline-block;background:url(loading.gif);position:absolute;left:50%;margin-left:-7px;top:53px;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-drop-processing{display:block}.qq-gallery .qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-gallery .qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-gallery .qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-upload-fail .qq-upload-failed-text,.qq-gallery .qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-gallery .qq-upload-list li.qq-upload-success{background-color:#F2F7ED}.qq-gallery .qq-upload-list li.qq-upload-fail{background-color:#F5EDED;box-shadow:0 0 1px 0 red;border:0}.qq-gallery .qq-progress-bar{display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-gallery .qq-total-progress-bar{height:25px;border-radius:9px}.qq-gallery .qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}.qq-gallery .qq-upload-size{float:left;font-size:11px;color:#929292;margin-bottom:3px;margin-right:0;display:inline-block}.qq-gallery INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-gallery .qq-upload-file.qq-editable{cursor:pointer;margin-right:20px}.qq-gallery .qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer;position:absolute;right:0;top:0}.qq-gallery INPUT.qq-edit-filename.qq-editing{position:static;height:28px;width:90px;width:-moz-available;padding:0 8px;margin-bottom:3px;border:1px solid #ccc;border-radius:2px;font-size:13px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-gallery .qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-continue-icon,.qq-gallery .qq-delete-icon,.qq-gallery .qq-pause-icon,.qq-gallery .qq-retry-icon{width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-delete-icon{background:url(trash.gif)}.qq-gallery .qq-retry-icon{background:url(retry.gif);float:none}.qq-gallery .qq-continue-icon{background:url(continue.gif)}.qq-gallery .qq-pause-icon{background:url(pause.gif)}.qq-gallery .qq-hide{display:none}.qq-gallery .qq-in-progress .qq-thumbnail-wrapper{opacity:.5;filter:alpha(opacity=50)}.qq-gallery .qq-thumbnail-wrapper{overflow:hidden;position:relative;height:120px;width:120px}.qq-gallery .qq-thumbnail-selector{border-radius:2px 2px 0 0;bottom:0;top:0;margin:auto;display:block}:root *>.qq-gallery .qq-thumbnail-selector{position:relative;top:50%;transform:translateY(-50%);-moz-transform:translateY(-50%);-ms-transform:translateY(-50%);-webkit-transform:translateY(-50%)}.qq-gallery.qq-uploader DIALOG{display:none}.qq-gallery.qq-uploader DIALOG[open]{display:block}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-gallery.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-gallery .qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-gallery.min.css.map */ \ No newline at end of file +.qq-gallery .qq-btn{float:right;border:none;padding:0;margin:0;box-shadow:none}.qq-gallery .qq-upload-button{display:inline;width:105px;padding:7px 10px;float:left;text-align:center;background:#00abc7;color:#fff;border-radius:2px;border:1px solid #37b7cc;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-gallery .qq-upload-button-hover{background:#33b6cc}.qq-gallery .qq-upload-button-focus{outline:1px dotted #000}.qq-gallery.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;border:1px dashed #ccc;background-color:#fafafa;padding:20px}.qq-gallery.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25}.qq-gallery .qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#f9f9f9;border-radius:4px;text-align:center}.qq-gallery .qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-gallery .qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-gallery .qq-upload-drop-area-active{background:#fdfdfd;border-radius:4px}.qq-gallery .qq-upload-list{margin:0;padding:10px 0 0;list-style:none;max-height:450px;overflow-y:auto;clear:both;box-shadow:none}.qq-gallery .qq-upload-list li{display:inline-block;position:relative;max-width:120px;margin:0 25px 25px 0;padding:0;line-height:16px;font-size:13px;color:#424242;background-color:#fff;border-radius:2px;box-shadow:0 1px 1px 0 rgba(0,0,0,.22);vertical-align:top;height:186px}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-failed-text,.qq-gallery .qq-upload-pause,.qq-gallery .qq-upload-retry,.qq-gallery .qq-upload-size,.qq-gallery .qq-upload-spinner{display:inline}.qq-gallery .qq-upload-continue:hover,.qq-gallery .qq-upload-delete:hover,.qq-gallery .qq-upload-pause:hover,.qq-gallery .qq-upload-retry:hover{background-color:transparent}.qq-gallery .qq-upload-cancel,.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{cursor:pointer}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{border:none;background:0 0;color:#00a0ba;font-size:12px;padding:0}.qq-gallery .qq-upload-status-text{color:#333;font-size:12px;padding-left:3px;padding-top:2px;width:inherit;display:none;width:108px}.qq-gallery .qq-upload-fail .qq-upload-status-text{text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;display:block}.qq-gallery .qq-upload-retrying .qq-upload-status-text{display:inline-block}.qq-gallery .qq-upload-retrying .qq-progress-bar-container{display:none}.qq-gallery .qq-upload-cancel{background-color:#525252;color:#f7f7f7;font-weight:700;font-family:Arial,Helvetica,sans-serif;border-radius:12px;border:none;height:22px;width:22px;padding:4px;position:absolute;right:-5px;top:-6px;margin:0;line-height:17px}.qq-gallery .qq-upload-cancel:hover{background-color:#525252}.qq-gallery .qq-upload-retry{cursor:pointer;position:absolute;top:30px;left:50%;margin-left:-31px;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 4px 4px rgba(0,0,0,.5),0 -2px 12px rgba(0,0,0,.08) inset;padding:3px 4px;border:1px solid #d2ddc7;border-radius:2px;color:inherit;background-color:#ebf6e0;z-index:1}.qq-gallery .qq-upload-retry:hover{background-color:#f7ffec}.qq-gallery .qq-file-info{padding:10px 6px 4px;margin-top:-3px;border-radius:0 0 2px 2px;text-align:left;overflow:hidden}.qq-gallery .qq-file-info .qq-file-name{position:relative}.qq-gallery .qq-upload-file{display:block;margin-right:0;margin-bottom:3px;width:auto;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden}.qq-gallery .qq-upload-spinner{display:inline-block;background:url(loading.gif);position:absolute;left:50%;margin-left:-7px;top:53px;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-drop-processing{display:block}.qq-gallery .qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-gallery .qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-gallery .qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-upload-fail .qq-upload-failed-text{display:inline}.qq-gallery .qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-gallery .qq-upload-list li.qq-upload-success{background-color:#f2f7ed}.qq-gallery .qq-upload-list li.qq-upload-fail{background-color:#f5eded;box-shadow:0 0 1px 0 red;border:0}.qq-gallery .qq-progress-bar{display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-gallery .qq-total-progress-bar{height:25px;border-radius:9px}.qq-gallery .qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}.qq-gallery .qq-upload-size{float:left;font-size:11px;color:#929292;margin-bottom:3px;margin-right:0;display:inline-block}.qq-gallery INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-gallery .qq-upload-file.qq-editable{cursor:pointer;margin-right:20px}.qq-gallery .qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer;position:absolute;right:0;top:0}.qq-gallery INPUT.qq-edit-filename.qq-editing{position:static;height:28px;width:90px;width:-moz-available;padding:0 8px;margin-bottom:3px;border:1px solid #ccc;border-radius:2px;font-size:13px;opacity:1}.qq-gallery .qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-delete-icon{background:url(trash.gif);width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-retry-icon{background:url(retry.gif);width:15px;height:15px;vertical-align:sub;display:inline-block;float:none}.qq-gallery .qq-continue-icon{background:url(continue.gif);width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-pause-icon{background:url(pause.gif);width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-hide{display:none}.qq-gallery .qq-in-progress .qq-thumbnail-wrapper{/* makes the spinner on top of the thumbnail more visible */opacity:.5}.qq-gallery .qq-thumbnail-wrapper{overflow:hidden;position:relative;height:120px;width:120px}.qq-gallery .qq-thumbnail-selector{border-radius:2px 2px 0 0;bottom:0;top:0;margin:auto;display:block}:root *>.qq-gallery .qq-thumbnail-selector{position:relative;top:50%;transform:translateY(-50%);-moz-transform:translateY(-50%);-ms-transform:translateY(-50%);-webkit-transform:translateY(-50%)}.qq-gallery.qq-uploader DIALOG{display:none}.qq-gallery.qq-uploader DIALOG[open]{display:block}.qq-gallery.qq-uploader DIALOG{display:none}.qq-gallery.qq-uploader DIALOG[open]{display:block}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-gallery.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-gallery .qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-gallery.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map index 41f0bbeb0..762454e29 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader-gallery.css"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader-gallery.css"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css index 58422f2f6..40bcea0a0 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css @@ -1 +1 @@ -.qq-btn,.qq-upload-button{box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-btn{padding:3px 4px;border:1px solid #CCC;border-radius:2px;color:inherit;background-color:#FFF}.qq-upload-delete{background-color:#e65c47;color:#FAFAFA;border-color:#dc523d;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-delete:hover{background-color:#f56b56}.qq-upload-cancel{background-color:#F5D7D7;border-color:#e6c8c8}.qq-upload-cancel:hover{background-color:#ffe1e1}.qq-upload-retry{background-color:#EBF6E0;border-color:#d2ddc7}.qq-upload-retry:hover{background-color:#f7ffec}.qq-upload-continue,.qq-upload-pause{background-color:#00ABC7;color:#FAFAFA;border-color:#2dadc2;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-continue:hover,.qq-upload-pause:hover{background-color:#0fbad6}.qq-upload-button{display:inline;width:105px;margin-bottom:10px;padding:7px 10px;text-align:center;float:left;background:#00ABC7;color:#FFF;border-radius:2px;border:1px solid #2dadc2}.qq-upload-button-hover{background:#33B6CC}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;background-color:#FDFDFD;border:1px dashed #CCC;padding:20px}.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#F9F9F9;border-radius:4px;border:1px dashed #CCC;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FDFDFD;border-radius:4px;border:1px dashed #CCC}.qq-upload-list{margin:0;padding:0;list-style:none;max-height:450px;overflow-y:auto;box-shadow:0 1px 0 rgba(15,15,50,.14);clear:both}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;color:#424242;background-color:#F6F6F6;border-top:1px solid #FFF;border-bottom:1px solid #DDD}.qq-upload-list li:first-child{border-top:none}.qq-upload-list li:last-child{border-bottom:none}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-file{vertical-align:middle;display:inline-block;width:300px;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;height:18px}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400;cursor:pointer;vertical-align:middle}.qq-upload-status-text{font-size:14px;font-weight:700;display:block}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text,.qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-upload-list li.qq-upload-success{background-color:#EBF6E0;color:#424242;border-bottom:1px solid #D3DED1;border-top:1px solid #F7FFF5}.qq-upload-list li.qq-upload-fail{background-color:#F5D7D7;color:#424242;border-bottom:1px solid #DECACA;border-top:1px solid #FCE6E6}.qq-progress-bar{display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer;margin-right:4px}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;height:28px;padding:0 8px;margin-right:10px;margin-bottom:-5px;border:1px solid #ccc;border-radius:2px;font-size:16px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:16px}.qq-thumbnail-selector{vertical-align:middle;margin-right:12px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-new.min.css.map */ \ No newline at end of file +.qq-btn{box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset;padding:3px 4px;border:1px solid #ccc;border-radius:2px;color:inherit;background-color:#fff}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-delete{background-color:#e65c47;color:#fafafa;border-color:#dc523d;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-delete:hover{background-color:#f56b56}.qq-upload-cancel{background-color:#f5d7d7;border-color:#e6c8c8}.qq-upload-cancel:hover{background-color:#ffe1e1}.qq-upload-retry{background-color:#ebf6e0;border-color:#d2ddc7}.qq-upload-retry:hover{background-color:#f7ffec}.qq-upload-continue,.qq-upload-pause{background-color:#00abc7;color:#fafafa;border-color:#2dadc2;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-continue:hover,.qq-upload-pause:hover{background-color:#0fbad6}.qq-upload-button{display:inline;width:105px;margin-bottom:10px;padding:7px 10px;text-align:center;float:left;background:#00abc7;color:#fff;border-radius:2px;border:1px solid #2dadc2;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-upload-button-hover{background:#33b6cc}.qq-upload-button-focus{outline:1px dotted #000}.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;background-color:#fdfdfd;border:1px dashed #ccc;padding:20px}.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#f9f9f9;border-radius:4px;border:1px dashed #ccc;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#fdfdfd;border-radius:4px;border:1px dashed #ccc}.qq-upload-list{margin:0;padding:0;list-style:none;max-height:450px;overflow-y:auto;box-shadow:0 1px 0 rgba(15,15,50,.14);clear:both}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;color:#424242;background-color:#f6f6f6;border-top:1px solid #fff;border-bottom:1px solid #ddd}.qq-upload-list li:first-child{border-top:none}.qq-upload-list li:last-child{border-bottom:none}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-file{vertical-align:middle;display:inline-block;width:300px;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;height:18px}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400;cursor:pointer;vertical-align:middle}.qq-upload-status-text{font-size:14px;font-weight:700;display:block}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-upload-list li.qq-upload-success{background-color:#ebf6e0;color:#424242;border-bottom:1px solid #d3ded1;border-top:1px solid #f7fff5}.qq-upload-list li.qq-upload-fail{background-color:#f5d7d7;color:#424242;border-bottom:1px solid #decaca;border-top:1px solid #fce6e6}.qq-progress-bar{display:block;display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer;margin-right:4px}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;height:28px;padding:0 8px;margin-right:10px;margin-bottom:-5px;border:1px solid #ccc;border-radius:2px;font-size:16px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:16px}.qq-hide{display:none}.qq-thumbnail-selector{vertical-align:middle;margin-right:12px}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-new.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map index 2dab29aa6..4ef57d350 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader-new.css"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader-new.css"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.core.js b/styles/bootstrap/fine-uploader/fine-uploader.core.js index 3a6c70071..229a128e1 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.core.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.core.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { var qq = function(element) { "use strict"; @@ -585,7 +585,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -603,9 +603,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -643,7 +640,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -903,7 +904,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -925,6 +927,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -941,6 +944,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -993,6 +1002,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1073,7 +1083,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1150,7 +1167,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1199,6 +1226,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1225,6 +1255,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1247,6 +1281,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1262,6 +1297,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1289,6 +1327,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1299,20 +1359,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1547,17 +1609,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1582,7 +1655,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1659,6 +1741,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -1760,7 +1845,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -1781,6 +1867,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -1933,7 +2041,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2006,19 +2114,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2078,6 +2176,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2173,7 +2276,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2322,6 +2425,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2329,8 +2433,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2358,7 +2464,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2411,9 +2517,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2421,6 +2538,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2519,7 +2639,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2537,6 +2657,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2606,7 +2727,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -2869,13 +2990,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -2894,13 +3016,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); diff --git a/styles/bootstrap/fine-uploader/fine-uploader.core.js.map b/styles/bootstrap/fine-uploader/fine-uploader.core.js.map index 48155fa23..5777241c4 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.core.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.core.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler"],"mappings":"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","file":"fine-uploader.core.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function u(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var l,c,d,p,f,q,h,m,g,_,b,v,S,w,y;return l=e(),p=l&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&u(),f=d&&t(),q=p&&qq.isFileChunkingSupported(),h=p&&q&&s(),m=p&&n(),g=l&&(void 0!==window.postMessage||p),b=i(),_=o(),v=r(),S=a(),w=p&&void 0!==window.FileReader,y=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:v,deleteFileCorsXdr:_,deleteFileCorsXhr:b,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:f,folderSelection:S,imagePreviews:w,imageValidation:w,itemSizeValidation:p,pause:q,progressBar:y,resume:h,scaling:w&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:l,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return u[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function f(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function h(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=v.push(e);if(s<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,f=p.normalizeResponse(n,!1);f.reset?l.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,f,r)||p.cleanup(t,f,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,f=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&u.onResume(e,n,a)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===f.length?l.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),u.onUploadChunk(e,n,o._getChunkDataForCallback(a)),f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](u,{getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t),a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);l[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(h("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;h(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){h("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(h("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||h("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,f=r.inputName,q=s.getUuid,h=s.log,m=new qq.WindowReceiveMessage({log:h});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",f),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(h("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){h("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){h("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,u=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,l=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,h=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),u&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,l(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,u);return d[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=l(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){u&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(u&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);u&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,l(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(u&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:l(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=l(e),a={simple:function(t,n){var i=c(e);t===n?h(e,r,i,i):h(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,d=a,p=c(e),f=l-(d-i),q=u;s[t]=f,qq.each(s,function(e,t){q+=t}),h(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,f=u.width,q=u.height,h=s.getContext("2d"),m=new qq.Promise;return h.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:f}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:f,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",f,q,c.newWidth,c.newHeight),"warn"),f=c.newWidth,q=c.newHeight)),a(s,f,q,u.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*f/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===f?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===f&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function f(e,r,s){var u=new qq.Promise,c=s.scale,f=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,f):d(e,r,u,f):p(e,r,u,f):n(r)?d(e,r,u,f):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),f(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,u,l,c=a.slice(0,4),p=e?n(c):parseInt(c,16),f=o.indexOf(p);if(f>=0&&(u=d[p].name,l=d[p].bytes,s=a.slice(i,i+2*l),r[u]=e?n(s):parseInt(s,16),o.splice(f,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,f=[],q=d.blob?d.blob:d,h=new qq.Identify(q,t);return h.isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});f.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),f.push({uuid:e,name:c,size:q.size,blob:i?q:null})):f.push({uuid:e,name:c,size:q.size,blob:q}),f},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,f=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),f.addReadOnly(t,n)}),l.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,f.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,f,p,h,q,m,g,_,b,v,S,w;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),f=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),p=d&&qq.isFileChunkingSupported(),h=d&&p&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),b=o(),v=r(),S=d&&void 0!==window.FileReader,w=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:p,deleteFileCors:b,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:f,folderSelection:v,imagePreviews:S,imageValidation:S,itemSizeValidation:d,pause:p,progressBar:w,resume:h,scaling:S&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e]&&S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function f(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function p(e){return function(){s(e)}}function h(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){if(S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},v.push(e)<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=f.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),f.cleanup(e,s,a)},function(t,o){var r=f.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||f.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,p=f.normalizeResponse(n,!1);if(p.reset)l.reset(t);else{var h=o._getFileState(t).chunking.inProgress;d=h?qq.indexOf(h,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,p,r)||f.cleanup(t,p,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),p=d.attemptingResume,h=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),p&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),p=!1),null==r&&0===h.length)l.finalize(e);else{h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:p};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=f.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],f.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),f.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=f.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),f.maybeNewUuid(e,r),f.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=f.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||f.cleanup(e,r,o)})}},f={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),f.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),f.maybeSendDeferredFiles(e),c.free(e)}),!1):f.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(f.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,f.now(i);else if(f.isDeferredEligibleForUpload(i))return!1})):(n=!0,f.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=f.normalizeResponse(n.responseJSON,!1);f.cleanup(e,o)}})},start:function(e){var t=f.getProxyOrBlob(e);return t?f.maybeDefer(e,t):(f.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&f.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?f.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){f.cancel(e)}):t!==!1&&f.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),f.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],f&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[h(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},f=r.isCors,p=r.inputName,h=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",p),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;f?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,f=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,f=c[t]||qq.sliceBlob(r,s,u);return c[t]=f,{part:t,start:s,end:u,count:l,blob:f,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=p(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:f(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,f=d(e),p=l-(c-i),h=u;s[t]=p,qq.each(s,function(e,t){h+=t}),m(e,r,h,f)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,f=n.naturalHeight,p=u.width,h=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:f,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:h,targetWidth:p}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:p,origHeight:h}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",p,h,c.newWidth,c.newHeight),"warn"),p=c.newWidth,h=c.newHeight)),a(s,p,h,u.orientation),qq.ios()?function(){e(n)&&(d/=2,f/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,f):1,c=Math.ceil(a*p/d),m=Math.ceil(a*h/f/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===p?function(){var t=e.src;n(r.srcImage,r.blob,i,f).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===p&&o(this.srcImage,this.blob,e,i,f),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,f=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;f.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),f.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function f(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function p(e,r,s){var u=new qq.Promise,c=s.scale,p=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?f(e,r,u,p):d(e,r,u,p):f(e,r,u,p):n(r)?d(e,r,u,p):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),p(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),f=i.indexOf(c);if(f>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(f,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var f=this,p=[],h=d.blob?d.blob:d;return new qq.Identify(h,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=f._determineOutputType({defaultType:r,requestedType:i.type,refType:h.type});p.push({uuid:qq.getUniqueId(),name:f._getName(c,{name:i.name,type:l,refType:h.type}),blob:new qq.BlobProxy(h,qq.bind(f._generateScaledImage,f,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),p.push({uuid:e,name:c,size:h.size,blob:i?h:null})):p.push({uuid:e,name:c,size:h.size,blob:h}),p},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,f=s.uploadData,p=s.paramsStore,h=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=f.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:h}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):f.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:f.retrieve({id:c}).uuid,qqparentsize:f.retrieve({id:c}).size};n[a]=f.retrieve({id:t}).uuid,f.setParentId(t,c),p.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=f.retrieve({id:c}).uuid,p.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){f(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(f(e,0,i),n[e]={loaded:0,total:i})},f=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){f(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5533,12 +5793,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5566,6 +5821,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5653,9 +5916,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5695,8 +5955,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5721,6 +5983,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -5773,7 +6037,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -5856,6 +6120,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6584,7 +6850,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6716,7 +6982,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -6780,15 +7046,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -6894,13 +7160,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -6912,6 +7178,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -6921,7 +7188,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } @@ -7411,4 +7678,4 @@ }); }; })(window); -//# sourceMappingURL=fine-uploader.js.map +//# sourceMappingURL=fine-uploader.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.js.map b/styles/bootstrap/fine-uploader/fine-uploader.js.map index f04b96e4a..a87518cba 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"
= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"
tag\n if (innerHtml && innerHtml.match(/^=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function u(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var l,c,d,p,f,q,h,m,g,_,b,v,S,w,y;return l=e(),p=l&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&u(),f=d&&t(),q=p&&qq.isFileChunkingSupported(),h=p&&q&&s(),m=p&&n(),g=l&&(void 0!==window.postMessage||p),b=i(),_=o(),v=r(),S=a(),w=p&&void 0!==window.FileReader,y=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:v,deleteFileCorsXdr:_,deleteFileCorsXhr:b,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:f,folderSelection:S,imagePreviews:w,imageValidation:w,itemSizeValidation:p,pause:q,progressBar:y,resume:h,scaling:w&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:l,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return u[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function f(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function h(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=v.push(e);if(s<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,f=p.normalizeResponse(n,!1);f.reset?l.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,f,r)||p.cleanup(t,f,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,f=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&u.onResume(e,n,a)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===f.length?l.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),u.onUploadChunk(e,n,o._getChunkDataForCallback(a)),f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](u,{getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t),a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);l[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(h("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;h(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){h("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(h("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||h("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,f=r.inputName,q=s.getUuid,h=s.log,m=new qq.WindowReceiveMessage({log:h});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",f),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(h("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){h("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){h("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,u=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,l=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,h=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),u&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,l(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,u);return d[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=l(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){u&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(u&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);u&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,l(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(u&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:l(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=l(e),a={simple:function(t,n){var i=c(e);t===n?h(e,r,i,i):h(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,d=a,p=c(e),f=l-(d-i),q=u;s[t]=f,qq.each(s,function(e,t){q+=t}),h(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,f=u.width,q=u.height,h=s.getContext("2d"),m=new qq.Promise;return h.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:f}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:f,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",f,q,c.newWidth,c.newHeight),"warn"),f=c.newWidth,q=c.newHeight)),a(s,f,q,u.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*f/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===f?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===f&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function f(e,r,s){var u=new qq.Promise,c=s.scale,f=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,f):d(e,r,u,f):p(e,r,u,f):n(r)?d(e,r,u,f):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),f(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,u,l,c=a.slice(0,4),p=e?n(c):parseInt(c,16),f=o.indexOf(p);if(f>=0&&(u=d[p].name,l=d[p].bytes,s=a.slice(i,i+2*l),r[u]=e?n(s):parseInt(s,16),o.splice(f,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,f=[],q=d.blob?d.blob:d,h=new qq.Identify(q,t);return h.isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});f.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),f.push({uuid:e,name:c,size:q.size,blob:i?q:null})):f.push({uuid:e,name:c,size:q.size,blob:q}),f},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,f=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),f.addReadOnly(t,n)}),l.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,f.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,f,p,h,q,m,g,_,b,v,S,w;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),f=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),p=d&&qq.isFileChunkingSupported(),h=d&&p&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),b=o(),v=r(),S=d&&void 0!==window.FileReader,w=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:p,deleteFileCors:b,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:f,folderSelection:v,imagePreviews:S,imageValidation:S,itemSizeValidation:d,pause:p,progressBar:w,resume:h,scaling:S&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e]&&S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function f(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function p(e){return function(){s(e)}}function h(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){if(S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},v.push(e)<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=f.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),f.cleanup(e,s,a)},function(t,o){var r=f.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||f.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,p=f.normalizeResponse(n,!1);if(p.reset)l.reset(t);else{var h=o._getFileState(t).chunking.inProgress;d=h?qq.indexOf(h,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,p,r)||f.cleanup(t,p,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),p=d.attemptingResume,h=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),p&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),p=!1),null==r&&0===h.length)l.finalize(e);else{h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:p};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=f.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],f.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),f.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=f.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),f.maybeNewUuid(e,r),f.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=f.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||f.cleanup(e,r,o)})}},f={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),f.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),f.maybeSendDeferredFiles(e),c.free(e)}),!1):f.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(f.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,f.now(i);else if(f.isDeferredEligibleForUpload(i))return!1})):(n=!0,f.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=f.normalizeResponse(n.responseJSON,!1);f.cleanup(e,o)}})},start:function(e){var t=f.getProxyOrBlob(e);return t?f.maybeDefer(e,t):(f.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&f.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?f.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){f.cancel(e)}):t!==!1&&f.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),f.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],f&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[h(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},f=r.isCors,p=r.inputName,h=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",p),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;f?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,f=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,f=c[t]||qq.sliceBlob(r,s,u);return c[t]=f,{part:t,start:s,end:u,count:l,blob:f,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=p(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:f(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,f=d(e),p=l-(c-i),h=u;s[t]=p,qq.each(s,function(e,t){h+=t}),m(e,r,h,f)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,f=n.naturalHeight,p=u.width,h=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:f,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:h,targetWidth:p}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:p,origHeight:h}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",p,h,c.newWidth,c.newHeight),"warn"),p=c.newWidth,h=c.newHeight)),a(s,p,h,u.orientation),qq.ios()?function(){e(n)&&(d/=2,f/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,f):1,c=Math.ceil(a*p/d),m=Math.ceil(a*h/f/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===p?function(){var t=e.src;n(r.srcImage,r.blob,i,f).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===p&&o(this.srcImage,this.blob,e,i,f),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,f=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;f.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),f.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function f(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function p(e,r,s){var u=new qq.Promise,c=s.scale,p=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?f(e,r,u,p):d(e,r,u,p):f(e,r,u,p):n(r)?d(e,r,u,p):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),p(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),f=i.indexOf(c);if(f>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(f,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var f=this,p=[],h=d.blob?d.blob:d;return new qq.Identify(h,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=f._determineOutputType({defaultType:r,requestedType:i.type,refType:h.type});p.push({uuid:qq.getUniqueId(),name:f._getName(c,{name:i.name,type:l,refType:h.type}),blob:new qq.BlobProxy(h,qq.bind(f._generateScaledImage,f,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),p.push({uuid:e,name:c,size:h.size,blob:i?h:null})):p.push({uuid:e,name:c,size:h.size,blob:h}),p},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,f=s.uploadData,p=s.paramsStore,h=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=f.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:h}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):f.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:f.retrieve({id:c}).uuid,qqparentsize:f.retrieve({id:c}).size};n[a]=f.retrieve({id:t}).uuid,f.setParentId(t,c),p.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=f.retrieve({id:c}).uuid,p.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){f(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(f(e,0,i),n[e]={loaded:0,total:i})},f=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){f(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5533,12 +5793,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5566,6 +5821,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5653,9 +5916,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5695,8 +5955,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5721,6 +5983,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -5773,7 +6037,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -5856,6 +6120,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6584,7 +6850,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6716,7 +6982,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -6780,15 +7046,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -6894,13 +7160,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -6912,6 +7178,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -6921,7 +7188,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } @@ -7411,4 +7678,4 @@ }); }; })(window); -//# sourceMappingURL=fine-uploader.js.map +//# sourceMappingURL=fine-uploader.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.js.map b/styles/bootstrap/fine-uploader/fine-uploader.js.map index f04b96e4a..a87518cba 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA,SCCT,SAASC,GACN,YAIA,SAASC,GAAKC,GACV,GAAIC,GAAcC,EAAmBF,OACjCG,EAAsBC,EAAuBH,EAKjD,OAHAI,GAASF,GACTG,EAAaL,EAAaE,GAEnBI,EAGX,QAASH,GAAuBI,GAC5B,GAAIC,GAAeC,EAAa,gBAC5BC,EAAYD,EAAa,eAG7B,OAAID,IAGAA,EAAeA,EAAaG,OAAO,GAAGC,cAAgBJ,EAAaK,MAAM,GAAGC,cAExEJ,EACO,GAAIK,IAAGL,GAAW,eAAiBF,GAAcD,GAGrD,GAAIQ,IAAG,eAAiBP,GAAcD,IAGzCG,EACO,GAAIK,IAAGL,GAAWM,aAAaT,GAGnC,GAAIQ,IAAGC,aAAaT,GAInC,QAASU,GAAUC,EAAKC,GACpB,GAAIC,GAAOd,EAAIc,KAAK,eAEpB,OAAID,IACaE,SAATD,IACAA,MAEJA,EAAKF,GAAOC,EACZb,EAAIc,KAAK,eAAgBA,GAJzB,QAOaC,SAATD,EACO,KAEJA,EAAKF,GAMpB,QAASd,GAASkB,GACd,MAAOL,GAAU,WAAYK,GAGjC,QAASb,GAAac,EAAQC,GAC1B,MAAOP,GAAUM,EAAQC,GAK7B,QAASnB,GAAaoB,EAAiBvB,GACnC,GAAIwB,GAAYD,EAAgBC,YAEhC7B,GAAE8B,KAAKzB,EAAoB0B,SAASF,UAAW,SAASG,EAAMC,GAC1D,GAAIC,GAAMC,CAEVD,GAAO,WAAWE,KAAKJ,GAAM,GAC7BE,EAAOA,EAAKG,UAAU,EAAG,GAAGpB,cAAgBiB,EAAKG,UAAU,GAC3DF,EAAsB1B,EAEtBoB,EAAUG,GAAQ,WACd,GAEIM,GAAyBC,EAFzBC,EAAeC,MAAMC,UAAU1B,MAAM2B,KAAKC,WAC1CC,IAGJ7C,GAAE8B,KAAKU,EAAc,SAASM,EAAKC,GAC/BF,EAAgBG,KAAKC,EAAkBF,MAG3CT,EAA0BL,EAAkBiB,MAAMC,KAAMX,EAExD,KACID,EAA4BJ,EAAoBiB,eAAelB,EAAMW,GAEzE,MAAOQ,GACHnC,GAAGoC,IAAI,uDAAyDD,EAAME,QAAS,SAInF,MAA+B,OAA3BjB,EACOA,EAEJC,KAIflC,EAAoB0B,SAASF,UAAYA,EAI7C,QAASzB,GAAmBoD,EAAQC,GAChC,GAAIC,GAASC,CAgDb,IA5CQD,EAFKlC,SAATiC,EAC4B,UAAxBD,EAAO7C,cACKiD,QAASnD,EAAI,OAOnBgD,EAGdzD,EAAE8B,KAAK0B,EAAQ,SAASxB,EAAMV,GACtBtB,EAAE6D,QAAQ7B,EAAM8B,IAAkB,EAClClD,EAAaoB,EAAMV,GAEdA,YAAetB,GACpB0D,EAAQ1B,GAAQV,EAAI,GAEftB,EAAE+D,cAAczC,IACrBoC,EAAQ1B,MACR5B,EAAmBkB,EAAKoC,EAAQ1B,KAE3BhC,EAAEgE,QAAQ1C,IACfqC,KACA3D,EAAE8B,KAAKR,EAAK,SAASwB,EAAKmB,GACtB,GAAIC,KAEAD,aAAoBjE,GACpBA,EAAEmE,MAAMR,EAAWM,GAEdjE,EAAE+D,cAAcE,IACrB7D,EAAmB6D,EAAUC,GAC7BP,EAAUX,KAAKkB,IAGfP,EAAUX,KAAKiB,KAGvBP,EAAQ1B,GAAQ2B,GAGhBD,EAAQ1B,GAAQV,IAIXE,SAATiC,EACA,MAAOC,GAIf,QAASU,GAAeC,GACpB,MAA2B,WAApBrE,EAAEsE,KAAKD,KACTA,EAAQE,MAAM,OACS/C,SAAxBjB,IAAW8D,GAKnB,QAASG,GAAgBH,GACrB,GAEII,GAFAC,KACAC,EAAWlC,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAOrD,OAJAxC,GAAmBuE,EAAUD,GAE7BD,EAASlE,IAAW8D,GAASnB,MAAM3C,IAAYmE,GAExCzB,EAAkBwB,GAI7B,QAASxB,GAAkB3B,GACvB,GAAIsD,GAAiBtD,CAUrB,OANW,OAAPA,GAA8B,gBAARA,IACL,IAAjBA,EAAIuD,UAAmC,IAAjBvD,EAAIuD,WAAmBvD,EAAIwD,YAEjDF,EAAiB5E,EAAEsB,IAGhBsD,EAlMX,GAAInE,GACAqD,GAAiB,eAAgB,eAoMrC9D,GAAE+E,GAAGC,aAAe,SAASC,GACzB,GAAIC,GAAO/B,KAAMgC,EAAWvC,UAAWwC,IAoBvC,OAlBAjC,MAAKrB,KAAK,SAASuD,EAAOC,GAGtB,GAFA7E,EAAMT,EAAEsF,GAEJ/E,KAAc6D,EAAea,IAG7B,GAFAG,EAAQpC,KAAKwB,EAAgBtB,MAAMgC,EAAMC,IAErB,IAAhBD,EAAKK,OACL,OAAO,MAGsB,gBAArBN,IAAkCA,EAI9CjF,EAAEqD,MAAM,UAAa4B,EAAmB,0CAHxChF,EAAKiD,MAAMgC,EAAMC,KAOF,IAAnBC,EAAQG,OACDH,EAAQ,GAEVA,EAAQG,OAAS,EACfH,EAGJjC,OAGbqC,QCtOD,SAASxF,GACN,YAIA,SAASC,GAAKC,GACLA,IACDA,MAGJA,EAAQuF,kBAAoBhF,EAC5B,IAAIN,GAAcC,EAAmBF,EAIrC,OAHAM,GAAaL,GACbuF,EAAI,GAAIxE,IAAGyE,YAAYxF,IAEhBM,EAGX,QAASW,GAAUC,EAAKC,GACpB,GAAIC,GAAOd,EAAIc,KAAKqE,EAEpB,OAAItE,IACaE,SAATD,IACAA,MAEJA,EAAKF,GAAOC,EACZb,EAAIc,KAAKqE,EAAarE,GAJtB,QAOaC,SAATD,EACO,KAEJA,EAAKF,GAIpB,QAASqE,GAAIjE,GACT,MAAOL,GAAU,cAAeK,GAGpC,QAASjB,GAAaoB,GAClB,GAAIC,GAAYD,EAAgBC,YAEhC7B,GAAE8B,KAAK,GAAIZ,IAAGyE,YAAY9D,UAAa,SAASG,EAAM6D,GAClD,GACIC,GADA5D,EAAOF,CAGX8D,GAAcrF,EAEdoB,EAAUG,GAAQ,WACd,GAAI+D,GAAOtD,MAAMC,UAAU1B,MAAM2B,KAAKC,WAClCoD,EAAsBF,EAAY1C,eAAelB,EAAM6D,EAE3D,OAAOC,MAMnB,QAAS5F,GAAmBoD,EAAQC,GAChC,GAAIC,GAASC,CAkCb,IA/BID,EADSlC,SAATiC,KAIUA,EAGdzD,EAAE8B,KAAK0B,EAAQ,SAASxB,EAAMV,GACtBA,YAAetB,GACf0D,EAAQ1B,GAAQV,EAAI,GAEftB,EAAE+D,cAAczC,IACrBoC,EAAQ1B,MACR5B,EAAmBkB,EAAKoC,EAAQ1B,KAE3BhC,EAAEgE,QAAQ1C,IACfqC,KACA3D,EAAE8B,KAAKR,EAAK,SAASwB,EAAKmB,GAClBA,YAAoBjE,GACpBA,EAAEmE,MAAMR,EAAWM,GAGnBN,EAAUX,KAAKiB,KAGvBP,EAAQ1B,GAAQ2B,GAGhBD,EAAQ1B,GAAQV,IAIXE,SAATiC,EACA,MAAOC,GAIf,QAASU,GAAeC,GACpB,MAA2B,WAApBrE,EAAEsE,KAAKD,IACE,YAAZA,GACmB7C,SAAnBkE,IAAMrB,GAGd,QAASG,GAAgBH,GACrB,GAAIK,MAAkBC,EAAWlC,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAEvE,OADAxC,GAAmBuE,EAAUD,GACtBgB,IAAMrB,GAASnB,MAAMwC,IAAOhB,GA1GvC,GACIjE,GADAmF,EAAc,iBA6GlB5F,GAAE+E,GAAGkB,gBAAkB,SAAShB,GAC5B,GAAIC,GAAO/B,KAAMgC,EAAWvC,UAAWwC,IAoBvC,OAlBAjC,MAAKrB,KAAK,SAASuD,EAAOC,GAGtB,GAFA7E,EAAMT,EAAEsF,GAEJI,KAAStB,EAAea,IAGxB,GAFAG,EAAQpC,KAAKwB,EAAgBtB,MAAMgC,EAAMC,IAErB,IAAhBD,EAAKK,OACL,OAAO,MAGsB,gBAArBN,IAAkCA,EAI9CjF,EAAEqD,MAAM,UAAa4B,EAAmB,kDAHxChF,EAAKiD,MAAMgC,EAAMC,KAOF,IAAnBC,EAAQG,OACDH,EAAQ,GAEVA,EAAQG,OAAS,EACfH,EAGJjC,OAGbqC,OC7IF,IAAItE,IAAK,SAAS0C,GACd,YAEA,QACIsC,KAAM,WAEF,MADAtC,GAAQuC,MAAMC,QAAU,OACjBjD,MAIXkD,OAAQ,SAAS/B,EAAMS,GAMnB,MALInB,GAAQ0C,iBACR1C,EAAQ0C,iBAAiBhC,EAAMS,GAAI,GAC5BnB,EAAQ2C,aACf3C,EAAQ2C,YAAY,KAAOjC,EAAMS,GAE9B,WACH7D,GAAG0C,GAAS4C,OAAOlC,EAAMS,KAIjCyB,OAAQ,SAASlC,EAAMS,GAMnB,MALInB,GAAQ6C,oBACR7C,EAAQ6C,oBAAoBnC,EAAMS,GAAI,GAC/BnB,EAAQ2C,aACf3C,EAAQ8C,YAAY,KAAOpC,EAAMS,GAE9B5B,MAGXwD,SAAU,SAASC,GAKf,QAAKA,IAKDhD,IAAYgD,IAIZhD,EAAQ+C,SACD/C,EAAQ+C,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwBjD,OAOrDkD,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAalD,EAASmD,GACnC5D,MAGX8D,OAAQ,WAEJ,MADArD,GAAQoD,WAAWE,YAAYtD,GACxBT,MAOXgE,IAAK,SAASC,GAEV,GAAqB,MAAjBxD,EAAQuC,MACR,KAAM,IAAIjF,IAAGmG,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1B1D,GAAQuC,MAAMmB,SAAqD,mBAArB1D,GAAe,UACpEwD,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9EpG,GAAGwG,OAAO9D,EAAQuC,MAAOiB,GAElBjE,MAGXwE,SAAU,SAASzF,EAAM0F,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAU5F,EAAO,QACrC,OAAO2F,GAAGE,KAAKnE,EAAQoE,eAAiBJ,IAAkBC,EAAGE,KAAKnE,EAAQoD,WAAWgB,aAGzFC,SAAU,SAAS/F,GAIf,MAHKhB,IAAG0C,GAAS+D,SAASzF,KACtB0B,EAAQoE,WAAa,IAAM9F,GAExBiB,MAGX+E,YAAa,SAAShG,GAClB,GAAI2F,GAAK,GAAIC,QAAO,QAAU5F,EAAO,QAErC,OADA0B,GAAQoE,UAAYpE,EAAQoE,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtEhF,MAGXiF,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASzE,EAAQ4E,cACV5E,EAAQ4E,cAAc,IAAMR,GAE9BpE,EAAQ6E,iBACN7E,EAAQ6E,iBAAiB,IAAMT,IAG1CM,EAAa1E,EAAQ8E,qBAAqB,KAE1CxH,GAAGY,KAAKwG,EAAY,SAASxF,EAAKxB,GAC1BJ,GAAGI,GAAKqG,SAASK,IACjBO,EAAOvF,KAAK1B,KAGb+G,EAAQE,EAAO,GAAKA,IAG/BI,gBAAiB,SAASX,GACtB,MAAO9G,IAAG0C,GAASwE,WAAWJ,GAAW,IAG7CY,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQjF,EAAQkF,WAEbD,GACoB,IAAnBA,EAAMhE,UACN+D,EAAS5F,KAAK6F,GAElBA,EAAQA,EAAME,WAGlB,OAAOH,IAGXI,QAAS,SAASC,GAGd,MAFArF,GAAQsF,UAAYD,EACpBrF,EAAQuF,YAAcF,EACf9F,MAGXiG,UAAW,WACP,MAAOlI,IAAG0C,GAASoF,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAI3F,GAAQyF,eAEHzF,EAAQyF,aAAaC,IAKkC,MAArD,WAAalH,KAAKwB,EAAQ4F,aAAaF,KAG9CC,EAAU3F,EAAQ0F,GAEF9H,SAAZ+H,GAKiC,MAA9B,WAAanH,KAAKmH,QAMxC,WACG,YAEArI,IAAGuI,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAO1I,IAAG2I,cAAcH,EAAOI,UAAUH,EAAMC,KAGnD1I,GAAG2I,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAAS7I,EAAMoI,GACxB,GAAIU,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOpJ,GACZmJ,EAAYE,QAAQjB,IAGpB,GAAIkB,OAAMtJ,IAAQ+C,KAAMqF,IAyB3C,OAlBIM,GADAF,EAAQe,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKjB,EAAQe,MAAM,KAAK,IAGxBG,UAAUlB,EAAQe,MAAM,KAAK,IAI9CX,EAAaJ,EAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBd,EAAc,GAAIkB,aAAYjB,EAAW1E,QACzC2E,EAAW,GAAIiB,YAAWnB,GAC1B9I,GAAGY,KAAKmI,EAAY,SAASnH,EAAKsI,GAC9BlB,EAASpH,GAAOsI,EAAUC,WAAW,KAGlCjB,EAAWJ,EAAaG,IAGnCjJ,GAAGoC,IAAM,SAASC,EAAS+H,GACnBhB,OAAOiB,UACFD,GAAmB,SAAVA,EAKNhB,OAAOiB,QAAQD,GACfhB,OAAOiB,QAAQD,GAAO/H,GAGtB+G,OAAOiB,QAAQjI,IAAI,IAAMgI,EAAQ,KAAO/H,GAR5C+G,OAAOiB,QAAQjI,IAAIC,KAc/BrC,GAAGsK,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAAS5G,UAAyD,oBAA7C6G,OAAOhJ,UAAUiJ,SAAShJ,KAAK8I,IAG5EvK,GAAG0K,WAAa,SAASH,GACrB,MAA6B,kBAAf,IASlBvK,GAAG8C,QAAU,SAAS6H,GAClB,MAAiD,mBAA1CH,OAAOhJ,UAAUiJ,SAAShJ,KAAKkJ,IACjCA,GAASvB,OAAOY,aAAeW,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBb,aAIrFhK,GAAG8K,WAAa,SAASC,GACrB,MAAyD,kCAAlDP,OAAOhJ,UAAUiJ,SAAShJ,KAAKsJ,IAK1C/K,GAAGgL,WAAa,SAASC,GACrB,MAAyD,sBAAlDT,OAAOhJ,UAAUiJ,SAAShJ,KAAKwJ,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CnL,GAAGoL,SAAW,SAASC,GACnB,MAAuD,oBAAhDb,OAAOhJ,UAAUiJ,SAAShJ,KAAK4J,IAG1CrL,GAAGsL,QAAU,SAASC,GAClB,MAAIC,QAAOhK,UAAUiK,KACVF,EAAOE,OAGXF,EAAOtE,QAAQ,aAAc,KAOxCjH,GAAG0L,OAAS,SAASC,GAEjB,GAAI9G,GAAQtD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,GAC9CkK,EAASD,EACTE,EAAmBD,EAAO/B,QAAQ,KAetC,OAbA7J,IAAGY,KAAKiE,EAAM,SAASjD,EAAKxB,GACxB,GAAI0L,GAAYF,EAAOzK,UAAU,EAAG0K,GAChCE,EAAWH,EAAOzK,UAAU0K,EAAmB,EAMnD,IAJAD,EAASE,EAAY1L,EAAM2L,EAC3BF,EAAmBD,EAAO/B,QAAQ,KAAMgC,EAAmBzL,EAAIiE,QAG3DwH,EAAmB,EACnB,OAAO,IAIRD,GAGX5L,GAAGgM,OAAS,SAASC,GACjB,MAAO7C,QAAO8C,MAAsD,kBAA9C1B,OAAOhJ,UAAUiJ,SAAShJ,KAAKwK,IAGzDjM,GAAGmM,WAAa,SAASC,GACrB,MAAOhD,QAAOiD,UAA8D,sBAAlD7B,OAAOhJ,UAAUiJ,SAAShJ,KAAK2K,IAG7DpM,GAAGsM,cAAgB,SAASC,GACxB,MAAOvM,IAAGgM,OAAOO,IAAqBvM,GAAGwM,QAAQD,IAGrDvM,GAAGwM,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAASvJ,GACxB,GAAIwJ,GAAiBxJ,EAAKrD,aAE1B,OAAI2M,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAIxD,OAAOyD,kBAC4C,8BAA/CrC,OAAOhJ,UAAUiJ,SAAShJ,KAAKgL,IAC3BA,EAAWrJ,MAAQuJ,EAAaF,EAAWrJ,WAKnDqJ,EAAWK,SAC8B,UAArCL,EAAWK,QAAQ/M,eACf0M,EAAWrJ,MAAQuJ,EAAaF,EAAWrJ,QAS3DpD,GAAG+M,OAAS,SAASC,GACjB,GAAI5D,OAAOO,MAAsD,kBAA9Ca,OAAOhJ,UAAUiJ,SAAShJ,KAAKuL,GAC9C,OAAO,GAIfhN,GAAGiN,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAM9J,KAAO,OAGU9C,SAAnB4M,EAAMG,UACc,mBAATnB,OACa,mBAAboB,WACoC,mBAAnCtN,IAAGuN,oBAAqBC,QAI5CxN,GAAGuN,kBAAoB,WACnB,GAAInE,OAAOqE,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOvL,GAEH,MADAnC,IAAGoC,IAAI,wCAAyC,SACzC,OAIfpC,GAAG2N,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMxJ,OAAS,GAC5BuJ,EAAaC,MAAM,GAAGC,kBAG9B9N,GAAG+N,wBAA0B,WACzB,OAAQ/N,GAAGgO,gBACPhO,GAAGiN,yBACuB3M,SAAzB4L,KAAK1K,UAAU1B,OAAsDQ,SAA/B4L,KAAK1K,UAAUyM,aAAyD3N,SAA5B4L,KAAK1K,UAAU0M,WAG1GlO,GAAGmO,UAAY,SAASC,EAAYC,EAAOC,GACvC,GAAIC,GAASH,EAAWtO,OAASsO,EAAWF,UAAYE,EAAWH,WAEnE,OAAOM,GAAO9M,KAAK2M,EAAYC,EAAOC,IAG1CtO,GAAGwO,iBAAmB,SAAS5D,GAC3B,GAAI6D,GAAa,GACbC,EAAQ,GAAIzE,YAAWW,EAY3B,OAVA5K,IAAGY,KAAK8N,EAAO,SAAS9M,EAAK+M,GACzB,GAAIC,GAAeD,EAAIlE,SAAS,GAE5BmE,GAAavK,OAAS,IACtBuK,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXzO,GAAG6O,cAAgB,SAASC,EAAMC,EAAa1K,GAC3C,GAAI2K,GAAchP,GAAGmO,UAAUW,EAAMC,EAAaA,EAAc1K,GAC5D4K,EAAa,GAAIC,YACjBC,EAAU,GAAInP,IAAGoP,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQtP,GAAGwO,iBAAiBS,EAAW5H,UAGnD4H,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGXnP,GAAGwG,OAAS,SAASW,EAAOuI,EAAQC,GAahC,MAZA3P,IAAGY,KAAK8O,EAAQ,SAAS5O,EAAMV,GACvBuP,GAAgB3P,GAAGsK,SAASlK,IACRE,SAAhB6G,EAAMrG,KACNqG,EAAMrG,OAEVd,GAAGwG,OAAOW,EAAMrG,GAAOV,GAAK,IAG5B+G,EAAMrG,GAAQV,IAIf+G,GAaXnH,GAAG4P,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACAzN,EAASwN,EAASC,EAUtB,OARA/P,IAAGY,KAAK0B,EAAQ,SAAS0N,EAAaC,GACN3P,SAAxBuP,EAAOG,KACPD,EAAOC,GAAeH,EAAOG,IAGjCH,EAAOG,GAAeC,IAGnBJ,GAMX7P,GAAG6J,QAAU,SAASqG,EAAKC,EAAKC,GAC5B,GAAIF,EAAIrG,QACJ,MAAOqG,GAAIrG,QAAQsG,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAI7L,MAMd,KAJI+L,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIXpQ,GAAGuQ,YAAc,WACb,MAAO,uCAAuCtJ,QAAQ,QAAS,SAASuJ,GAEpE,GAAIC,GAAoB,GAAhBnK,KAAKoK,SAAgB,EAAGC,EAAS,KAALH,EAAWC,EAAS,EAAJA,EAAU,CAC9D,OAAOE,GAAElG,SAAS,OAM1BzK,GAAG4Q,GAAK,WACJ,MAAOC,WAAUC,UAAUjH,QAAQ,WAAY,GAC3CgH,UAAUC,UAAUjH,QAAQ,cAAe,GAGnD7J,GAAG+Q,IAAM,WACL,MAAOF,WAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGgR,IAAM,WACL,MAAOH,WAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGiR,KAAO,WACN,MAAOJ,WAAUC,UAAUjH,QAAQ,cAAe,GAGtD7J,GAAGkR,KAAO,WACN,MAAOlR,IAAG4Q,MAAQC,UAAUC,UAAUjH,QAAQ,YAAa,GAG/D7J,GAAGmR,KAAO,WACN,MAAON,WAAUC,UAAUjH,QAAQ,SAAW,GAGlD7J,GAAGoR,OAAS,WACR,MAA4B9Q,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,YAAa,GAGnF7J,GAAGsR,OAAS,WACR,MAA4BhR,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,aAAc,GAGpF7J,GAAGuR,MAAQ,WACP,MAA4BjR,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,YAAa,GAGnF7J,GAAGwR,QAAU,WACT,OAASxR,GAAGmR,SAAWnR,GAAGkR,QAAUL,UAAUC,UAAUjH,QAAQ,cAAe,GAA2BvJ,SAArBuQ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrIrR,GAAGyR,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrB1R,GAAG2R,QAAU,WACT,MAAOd,WAAUC,UAAU/Q,cAAc8J,QAAQ,cAAe,GAKpE7J,GAAGgO,aAAe,WACd,MAAOhO,IAAG2R,WAAad,UAAUC,UAAU/Q,cAAc8J,QAAQ,UAAY,GAGjF7J,GAAG4R,KAAO,WACN,MAAO5R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAGjE7J,GAAG8R,KAAO,WACN,MAAO9R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAGjE7J,GAAG+R,KAAO,WACN,MAAO/R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAIjE7J,GAAGgS,OAAS,WACR,MAAOhS,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,eAAgB,GAGnE7J,GAAG6R,IAAM,WAEL,MAAOhB,WAAUC,UAAUjH,QAAQ,WAAY,GACxCgH,UAAUC,UAAUjH,QAAQ,WAAY,GACxCgH,UAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGiS,UAAY,WACX,MAAOjS,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,YAAa,GAGhE7J,GAAGkS,UAAY,WACX,MAAOlS,IAAG6R,QAAU7R,GAAGiS,aAAepB,UAAUC,UAAUjH,QAAQ,aAAc,GAGpF7J,GAAGmS,iBAAmB,WAClB,MAAOnS,IAAG6R,QAAU7R,GAAGiS,cAAgBjS,GAAGkS,aAM9ClS,GAAGoS,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxBtS,GAAGuS,UAAa,WACZ,GAAIC,GAAMrF,SAASC,cAAc,MACjC,OAAO,UAASqF,GACZD,EAAIE,UAAYD,CAChB,IAAI/P,GAAU8P,EAAI5K,UAElB,OADA4K,GAAIxM,YAAYtD,GACTA,MAKf1C,GAAGY,KAAO,SAAS+R,EAAcC,GAC7B,GAAIC,GAAYtP,CAEhB,IAAIoP,EAEA,GAAIvJ,OAAO0J,SAAWH,EAAa9H,cAAgBzB,OAAO0J,QACtD,IAAKD,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASD,EAAaxS,IAAI0S,GAAaF,EAAaI,QAAQJ,EAAaxS,IAAI0S,KAClFtP,KAAW,GAFoCsP,SAStD,IAAI7S,GAAG8C,QAAQ6P,IAAiB3S,GAAG8K,WAAW6H,IAAiB3S,GAAGgL,WAAW2H,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASC,EAAYF,EAAaE,IACvCtP,KAAW,GAFoCsP,SAOtD,IAAI7S,GAAGoL,SAASuH,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASC,EAAYF,EAAa/S,OAAOiT,IAC9CtP,KAAW,GAFoCsP,SAQvD,KAAKA,IAAcF,GACf,GAAInI,OAAOhJ,UAAU8O,eAAe7O,KAAKkR,EAAcE,KACnDtP,EAASqP,EAASC,EAAYF,EAAaE,IACvCtP,KAAW,GACX,OASxBvD,GAAGgT,KAAO,SAASC,EAASC,GACxB,GAAIlT,GAAG0K,WAAWuI,GAAU,CACxB,GAAIpO,GAAQtD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAElD,OAAO,YACH,GAAIyR,GAAUnT,GAAGwG,UAAW3B,EAI5B,OAHInD,WAAU2C,SACV8O,EAAUA,EAAQC,OAAO7R,MAAMC,UAAU1B,MAAM2B,KAAKC,aAEjDuR,EAAQjR,MAAMkR,EAASC,IAItC,KAAM,IAAIhN,OAAM,wCAmBpBnG,GAAGqT,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQ1M,KAAK0M,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAW3R,KACa,gBAAZ8R,GACF5T,GAAGqT,QAAQO,EAASE,GAAU,GACe,sBAA5CtJ,OAAOhJ,UAAUiJ,SAAShJ,KAAKmS,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAK7M,KAAK0M,GAAU,MAAM1M,KAAK0M,GAAS,GAAK,IAAM,IAC7DE,EAAW3R,KAAKyR,GAChBE,EAAW3R,KAAK9B,GAAGqT,QAAQC,KACqB,mBAAxC9I,OAAOhJ,UAAUiJ,SAAShJ,KAAK6R,IAA8C,mBAARA,GAC7EtT,GAAGY,KAAK0S,EAAK,SAAS1R,EAAKxB,GACvBuT,EAAIvT,EAAKwB,KAEU,mBAAR0R,IAAiC,OAARA,GAAiC,gBAARA,GACjEtT,GAAGY,KAAK0S,EAAK,SAASxS,EAAMV,GACxBuT,EAAIvT,EAAKU,KAGb2S,EAAW3R,KAAKiS,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBzM,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7BjH,GAAGiU,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAI5G,WAGnBtN,GAAGY,KAAK0S,EAAK,SAASnT,EAAKC,GACvBD,EAAMgU,EAAeA,EAAe,IAAMhU,EAAM,IAAMA,EAElDH,GAAGsK,SAASlK,GACZJ,GAAGiU,aAAa7T,EAAK8T,EAAU/T,GAE1BH,GAAG0K,WAAWtK,GACnB8T,EAASzK,OAAOtJ,EAAKC,KAGrB8T,EAASzK,OAAOtJ,EAAKC,KAItB8T,GAGXlU,GAAGoU,WAAa,SAASd,EAAKe,GAC1B,GAAInH,EAeJ,OAbKmH,KACDA,EAAOlH,SAASC,cAAc,SAGlCpN,GAAGiU,aAAaX,GACZ7J,OAAQ,SAAStJ,EAAKC,GAClB8M,EAAQC,SAASC,cAAc,SAC/BF,EAAMoH,aAAa,OAAQnU,GAC3B+M,EAAMoH,aAAa,QAASlU,GAC5BiU,EAAKE,YAAYrH,MAIlBmH,GAOXrU,GAAGwU,UAAY,SAASC,MAEpB,MAAIrL,QAAOsL,MAAQ1U,GAAG0K,WAAWgK,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjCzU,GAAG6U,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAASzQ,OAAS0Q,IAIzD/U,GAAGkV,YAAc,SAASC,GAGtB,MAAInV,IAAGwM,QAAQ2I,GAEJA,EAAgBxK,MAAM1D,QAAQ,YAAa,IAE7CjH,GAAGgM,OAAOmJ,IACkB,OAA7BA,EAAgBC,UAAkD9U,SAA7B6U,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgBnU,MAM3BhB,GAAGqV,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIXrQ,OAAQ,WACJ,GAAIN,GAAOnD,SAEXO,MAAKyT,YAAY1V,GAAG6E,EAAK,IAAIM,OAAOnD,MAAMC,KAAMV,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,MAI1FgU,YAAa,SAASC,GAClBL,EAAUxT,KAAK6T,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAO5V,MAGY,mBAAX8V,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAU/V,GAGjBnB,OAAOmB,GAAKA,MCRnB,WACG,YAEAA,IAAGmG,MAAQ,SAAS9D,GAChBJ,KAAKI,QAAU,kBAAoBrC,GAAGgW,QAAU,KAAO3T,GAG3DrC,GAAGmG,MAAM3E,UAAY,GAAI2E,UCV7BnG,GAAGgW,QAAU,SCAbhW,GAAGiW,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAYhJ,SAASC,cAAc,SACnC+I,EAAU/S,KAAO,OACjBpD,GAAGmW,GAAWnR,OAEVmR,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQvW,GAAGsR,UAAYtR,GAAGuR,UAC+CjR,SAArEuQ,UAAUC,UAAUzN,MAAM,uCAIlC,QAASmT,KACL,OAAQxW,GAAGsR,UAAYtR,GAAGuR,UAC+CjR,SAArEuQ,UAAUC,UAAUzN,MAAM,uCAIlC,QAASoT,KACL,GAAIrN,OAAOqE,eAAgB,CACvB,GAAIiJ,GAAM1W,GAAGuN,mBAGb,OAA+BjN,UAAxBoW,EAAIC,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiCtW,UAA1B8I,OAAOyN,eAKlB,QAASC,KACL,QAAIL,KAIGG,IAGX,QAASG,KAEL,MAA2DzW,UAApD6M,SAASC,cAAc,SAAS4J,gBAG3C,QAASC,KACL,IACI,QAAS7N,OAAO8N,cAEZlX,GAAG0K,WAAWtB,OAAO8N,aAAaC,SAE1C,MAAOhV,GAEH,OAAO,GAIf,QAASiV,KACL,GAAIC,GAAOlK,SAASC,cAAc,OAElC,QAAQ,aAAeiK,IAAS,eAAiBA,IAAQ,UAAYA,MAChErX,GAAG2R,YAAc3R,GAAG6R,MAhG7B,GAAIyF,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAnCAd,GAAoBpB,IAEpBuB,EAA4BH,GAAqBtX,GAAGiN,uBAEpDsK,EAAyBE,IAA8BzX,GAAGgO,eAE1DwJ,EAAmBC,GAA6BL,IAEhDM,EAAqBF,GAAoBjB,IAEzCoB,EAAmBF,GAA6BzX,GAAG+N,0BAEnD6J,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BjB,IAEtDsB,EAAqBR,IAA6ChX,SAAvB8I,OAAOiP,aAA6BZ,GAE/EO,EAA4BvB,IAE5BsB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmDnX,SAAtB8I,OAAO8F,WAE5DkJ,EAA0B,WACtB,QAAIX,KACQzX,GAAGgO,iBAAmBhO,GAAGiS,iBAMrCqG,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiBzP,OAAO0P,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAczZ,GAAGoR,SACjBsI,0BAA2B1Z,GAAG6R,MAC9B8H,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxB7X,GAAGga,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQla,GAAG0K,WAAWuP,EAAaC,QAG9Ela,GAAGoP,QAAU,WACT,YAEA,IAAI+K,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZxa,IAAGwG,OAAOvE,MACNiY,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiBvY,KAAK2Y,GAEtBC,GACAJ,EAAiBxY,KAAK4Y,IAGrBF,KAAU,EACfE,GAAaA,EAAU1Y,MAAM,KAAMoY,GAE9BK,GACLA,EAAUzY,MAAM,KAAMmY,GAGnBlY,MAGX0Y,KAAM,SAAS/H,GAQX,MAPc,KAAV4H,EACAD,EAAczY,KAAK8Q,GAGnBA,EAAS5Q,MAAM,KAAsB1B,SAAhB8Z,EAA4BD,EAAcC,GAG5DnY,MAGXqN,QAAS,WAgBL,MAfAkL,GAAQ,EACRL,EAAczY,UAEV2Y,EAAiBhW,QACjBrE,GAAGY,KAAKyZ,EAAkB,SAASzY,EAAKgR,GACpCA,EAAS5Q,MAAM,KAAMmY,KAIzBI,EAAclW,QACdrE,GAAGY,KAAK2Z,EAAe,SAAS3Y,EAAKgR,GACjCA,EAAS5Q,MAAM,KAAMmY,KAItBlY,MAGXuN,QAAS,WAgBL,MAfAgL,IAAQ,EACRJ,EAAc1Y,UAEV4Y,EAAiBjW,QACjBrE,GAAGY,KAAK0Z,EAAkB,SAAS1Y,EAAKgR,GACpCA,EAAS5Q,MAAM,KAAMoY,KAIzBG,EAAclW,QACdrE,GAAGY,KAAK2Z,EAAe,SAAS3Y,EAAKgR,GACjCA,EAAS5Q,MAAM,KAAMoY,KAItBnY,SC3EnBjC,GAAG4a,UAAY,SAASC,EAAeC,GACnC,YAEA9a,IAAGwG,OAAOvE,MACN4Y,cAAeA,EAEfE,OAAQ,WACJ,MAAOD,GAASD,OCF5B7a,GAAGgb,aAAe,SAASC,GACvB,YA0CA,SAASC,KACL,GAAIhO,GAAQC,SAASC,cAAc,QAmEnC,OAjEAF,GAAMoH,aAAatU,GAAGgb,aAAaG,oBAAqBC,GACxDlO,EAAMoH,aAAa,QAAStV,EAAQqc,OAEpCrX,EAAKsX,YAAYtc,EAAQqO,SAAUH,GAE/BlO,EAAQuc,SAAWvb,GAAGiW,kBAAkBgD,iBAExC/L,EAAMoH,aAAa,kBAAmB,IAGtCtV,EAAQwc,aACRtO,EAAMoH,aAAa,SAAUtV,EAAQwc,aAGzCtO,EAAMoH,aAAa,OAAQ,QAC3BpH,EAAMoH,aAAa,OAAQtV,EAAQgC,MAEnChB,GAAGkN,GAAOjH,KACNwV,SAAU,WAIVC,MAAO,EACPC,IAAK,EACLC,WAAY,QASZC,SAAU7b,GAAG4Q,OAAS5Q,GAAGgR,MAAQ,SAAW,QAC5C8K,OAAQ,EACRC,QAAS,EACTC,OAAQ,UACR5V,QAAS,KAKZpG,GAAG+Q,OAAS/Q,GAAGkN,GAAOjH,KAAKgW,OAAQ,SAEpCjd,EAAQ0D,QAAQ6R,YAAYrH,GAE5BgP,EAAe/W,OAAO+H,EAAO,SAAU,WACnClO,EAAQmd,SAASjP,KAIrBgP,EAAe/W,OAAO+H,EAAO,YAAa,WACtClN,GAAGhB,EAAQ0D,SAASqE,SAAS/H,EAAQod,cAEzCF,EAAe/W,OAAO+H,EAAO,WAAY,WACrClN,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQod,cAG5CF,EAAe/W,OAAO+H,EAAO,QAAS,WAClClN,GAAGhB,EAAQ0D,SAASqE,SAAS/H,EAAQqd,cAEzCH,EAAe/W,OAAO+H,EAAO,OAAQ,WACjClN,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQqd,cAGrCnP,EA5GX,GAgCIA,GAAOkO,EAhCPpX,EAAO/B,KAEPia,EAAiB,GAAIlc,IAAGqV,eAExBrW,GAEIwc,YAAa,KAGb9Y,QAAS,KAET2Z,WAAY,yBAGZd,SAAS,EAGTa,WAAY,yBAEZE,4BAA4B,EAG5BjP,UAAU,EAGVrM,KAAM,SAGNmb,SAAU,SAASjP,KAEnBmO,MAAO,KAKfrb,IAAGwG,OAAOxH,EAASic,GAEnBG,EAAWpb,GAAGuQ,cA2EdvQ,GAAGhB,EAAQ0D,SAASuD,KAChBwV,SAAU,WACVc,SAAU,SAEVC,UAAW,QAIfxc,GAAGwG,OAAOvE,MACNwa,SAAU,WACN,MAAOvP,IAGXwP,YAAa,WACT,MAAOtB,IAGXE,YAAa,SAASqB,EAAYC,GAC9B,GAAI1P,GAAQ0P,GAAY3a,KAAKwa,UAKzBzd,GAAQsd,4BAA8Btc,GAAG+R,SAAW/R,GAAGiS,aAAejS,GAAGmS,oBACzEjF,EAAMoH,aAAa,WAAY,IAI3BqI,EACAzP,EAAMoH,aAAa,WAAY,IAG/BpH,EAAM2P,gBAAgB,aAKlCC,eAAgB,SAAStB,GACjBA,IAAgBxc,EAAQwc,aACxBtO,EAAMoH,aAAa,SAAUkH,IAIrCuB,MAAO,WACC7P,EAAMpH,YACN9F,GAAGkN,GAAOnH,SAGd/F,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQqd,YACxCnP,EAAQ,KACRA,EAAQgO,OAIhBhO,EAAQgO,KAGZlb,GAAGgb,aAAaG,oBAAsB,eCxLtCnb,GAAGgd,WAAa,SAASC,GACrB,YAQA,SAASC,GAAaC,GAClB,GAAInd,GAAG8C,QAAQqa,GAAU,CACrB,GAAIC,KAMJ,OAJApd,IAAGY,KAAKuc,EAAS,SAASvb,EAAKyb,GAC3BD,EAAQtb,KAAKzB,EAAKgd,MAGfD,EAGX,MAAO/c,GAAK8c,GAGhB,QAASG,GAAeC,GACpB,GAAIvd,GAAG8C,QAAQya,GAAQ,CACnB,GAAIH,KAMJ,OAJApd,IAAGY,KAAK2c,EAAO,SAAS3b,EAAK4b,GACzBJ,EAAQtb,KAAKzB,EAAKod,EAAOD,OAGtBJ,EAGX,MAAO/c,GAAKod,EAAOF,IAGvB,QAASG,GAAgBC,GACrB,GAAIC,MACAC,KAAczK,OAAOuK,EAYzB,OAVA3d,IAAGY,KAAKid,EAAU,SAAS1Z,EAAO2Z,GAC9B,GAAIC,GAAsBC,EAASF,EAEPxd,UAAxByd,GACA/d,GAAGY,KAAKmd,EAAqB,SAASlK,EAAGoK,GACrCL,EAAc9b,KAAKzB,EAAK4d,QAK7BL,EAhDX,GAAIvd,MACAod,KACAO,KACAE,KACAC,IA+CJne,IAAGwG,OAAOvE,MAeNmc,QAAS,SAASC,GACd,GAAIV,GAASU,EAAKV,QAAU3d,GAAG2d,OAAOW,WAClCjB,EAAKhd,EAAKyB,MACNd,KAAMqd,EAAKrd,KACXud,aAAcF,EAAKrd,KACnBwc,KAAMa,EAAKb,KACXgB,KAAmB,MAAbH,EAAKG,MAAe,EAAKH,EAAKG,KACpCb,OAAQA,IACP,CA8BT,OA5BIU,GAAKI,UACLpe,EAAKgd,GAAIoB,QAAUJ,EAAKI,QAEQne,SAA5B6d,EAAUE,EAAKI,WACfN,EAAUE,EAAKI,aAEnBN,EAAUE,EAAKI,SAAS3c,KAAKub,IAG7BgB,EAAKK,eACLre,EAAKgd,GAAIqB,aAAeL,EAAKK,aAEape,SAAtC4d,EAAeG,EAAKK,gBACpBR,EAAeG,EAAKK,kBAExBR,EAAeG,EAAKK,cAAc5c,KAAKub,IAG3Chd,EAAKgd,GAAIA,GAAKA,EACdI,EAAOY,EAAKb,MAAQH,EAEK/c,SAArB0d,EAASL,KACTK,EAASL,OAEbK,EAASL,GAAQ7b,KAAKub,GAEtBJ,EAAc0B,eAAetB,EAAI,KAAMM,GAEhCN,GAGXuB,SAAU,SAASC,GACf,MAAI7e,IAAGsK,SAASuU,IAAmBxe,EAAKgE,OACV/D,SAAtBue,EAAexB,GACRH,EAAa2B,EAAexB,IAGN/c,SAAxBue,EAAerB,KACbF,EAAeuB,EAAerB,MAGhCqB,EAAelB,OACbD,EAAgBmB,EAAelB,QADrC,OAKE3d,GAAGwG,UAAWnG,GAAM,IAInC0c,MAAO,WACH1c,KACAod,KACAO,KACAG,MAGJW,UAAW,SAASzB,EAAI0B,GACpB,GAAIC,GAAY3e,EAAKgd,GAAIM,OACrBsB,EAAyBjf,GAAG6J,QAAQmU,EAASgB,GAAY3B,EAE7DW,GAASgB,GAAWE,OAAOD,EAAwB,GAEnD5e,EAAKgd,GAAIM,OAASoB,EAEUze,SAAxB0d,EAASe,KACTf,EAASe,OAEbf,EAASe,GAAWjd,KAAKub,GAEzBJ,EAAc0B,eAAetB,EAAI2B,EAAWD,IAGhDI,YAAa,SAAS9B,EAAI+B,GACtB,GAAIC,GAAUhf,EAAKgd,GAAIG,IAEvBnd,GAAKgd,GAAIG,KAAO4B,EAChB3B,EAAO2B,GAAW/B,QACXI,GAAO4B,IAGlBC,WAAY,SAASjC,EAAIkC,GACrBlf,EAAKgd,GAAIrc,KAAOue,GAGpBC,WAAY,SAASnC,EAAIoC,GACrBpf,EAAKgd,GAAImB,KAAOiB,GAIpBC,YAAa,SAASC,EAAUC,GAC5Bvf,EAAKsf,GAAUC,SAAWA,GAG9BC,mBAAoB,SAASxC,GACzB,GAAIqB,GAAere,EAAKgd,GAAIqB,YAE5B,OAAIA,GACOR,EAAeQ,OAK9BoB,cAAe,SAASzC,GACpB,GAAIoB,GAAUpe,EAAKgd,GAAIoB,OAEvB,OAAON,GAAUM,OAK7Bze,GAAG2d,QACCW,WAAY,aACZyB,UAAW,YACXC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,UAAW,YACXC,gBAAiB,kBACjBC,kBAAmB,oBACnBC,cAAe,gBACfC,cAAe,gBACfC,SAAU,WACVC,QAAS,WCxMZ,WACG,YAEA1gB,IAAG2gB,eAECC,SAAU,SAASC,EAAiBrhB,EAAQshB,GACxC7e,KAAK8e,SAASF,EAAiBrhB,EAAQshB,IAG3CE,gBAAiB,SAASC,GACtB,GAAIjd,GAAO/B,IAEXjC,IAAGY,KAAKqgB,EAAgB,SAAS9c,EAAO+c,GACpCld,EAAKmd,eAAeD,MAI5BH,SAAU,SAAS1gB,EAAMb,EAAQshB,GAC7B7e,KAAKmf,kCAEL,IAAI3C,GAAqC,IAA3Bxc,KAAKof,WAAWhd,OAAerE,GAAGuQ,cAAgBtO,KAAKqf,gBAEjEC,EAAcvhB,GAAGgT,KAAK,SAASlE,GAC3B7M,KAAKuf,gBACD1S,KAAMA,EACN9N,KAAMiB,KAAKpB,SAAS4gB,MAAMC,aAC3BjD,EAASkD,IACb1f,MAEH2f,EAAkB5hB,GAAGgT,KAAK,SAAS6O,GAC/B5f,KAAKuf,eAAeK,EAAUpD,EAASkD,IACxC1f,MAEH6f,EAAgB9hB,GAAGgT,KAAK,SAASxK,GAC7B,GAAIsG,GAAO9O,GAAGuI,aAAaC,EAE3BvG,MAAKuf,gBACD1S,KAAMA,EACN9N,KAAMiB,KAAKpB,SAAS4gB,MAAMC,YAAc,QACzCjD,EAASkD,IACb1f,MAEH8f,EAAoB/hB,GAAGgT,KAAK,SAASgP,GACjC,GAAIC,GAAoBD,EAAWtZ,SAAWsZ,EAAWtZ,QAAU,IAC/DoG,EAAO9O,GAAGuI,aAAayZ,EAAWxZ,OAAQwZ,EAAW5e,KAAM6e,EAE/DhgB,MAAKuf,gBACD1S,KAAMA,EACN9N,KAAMghB,EAAWhhB,MAClByd,EAASkD,IACb1f,MAEHigB,EAAqBliB,GAAGgT,KAAK,SAASmP,GAClC,GAAIniB,GAAGwM,QAAQ2V,IAAgBniB,GAAGiW,kBAAkBqC,cAAe,CAC/D,GAAI8J,GAAQ7gB,MAAMC,UAAU1B,MAAM2B,KAAK0gB,EAAYC,OAC/Cpe,EAAO/B,IAEXjC,IAAGY,KAAKwhB,EAAO,SAASxgB,EAAKygB,GACzBre,EAAKwd,eAAea,EAAM5D,EAASkD,SAIvC1f,MAAKuf,eAAeW,EAAa1D,EAASkD,IAE/C1f,MAEHqgB,EAAgB,WACRtiB,GAAGmM,WAAW9L,KACdA,EAAOkB,MAAMC,UAAU1B,MAAM2B,KAAKpB,IAEtCA,KAAU+S,OAAO/S,IAGrB2D,EAAO/B,KACP0f,IAEJ1f,MAAKqf,gBAAkB7C,EAEnBpe,IACAiiB,IAEAtiB,GAAGY,KAAKP,EAAM,SAASuB,EAAK2gB,GACpBviB,GAAGsM,cAAciW,GACjBL,EAAmBK,GAEdviB,GAAG+M,OAAOwV,GACfhB,EAAYgB,GAEPviB,GAAGsK,SAASiY,GACbA,EAAczT,MAAQyT,EAAcvhB,KACpC4gB,EAAgBW,GAEXA,EAAc/Z,QAAU+Z,EAAcvhB,MAC3C+gB,EAAkBQ,GAGjBA,EAAczV,SAAmD,WAAxCyV,EAAczV,QAAQ/M,cACpD+hB,EAAcS,GAGdve,EAAK5B,IAAImgB,EAAgB,6CAA8C,UAI/EtgB,KAAKG,IAAI,YAAcuf,EAActd,OAAS,WAC9CpC,KAAKugB,uBAAuBb,EAAeniB,EAAQshB,KAI3D2B,OAAQ,SAASpF,GACbpb,KAAKygB,SAASD,OAAOpF,IAGzBsF,UAAW,WACP,GAAIC,MACA5e,EAAO/B,IAEXjC,IAAGwG,OAAOoc,EAAe3gB,KAAKof,YAC9BrhB,GAAGY,KAAKgiB,EAAe,SAAShhB,EAAKihB,GACjC7e,EAAKye,OAAOI,KAGhB5gB,KAAKygB,SAASC,aAGlBG,iBAAkB,WACd7gB,KAAKof,eAGT0B,eAAgB,SAAS1F,GACrB,GAAI2F,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAEhD,UAAKrd,GAAGiW,kBAAkBoD,QAAUpX,KAAKpB,SAAS4X,SAASyK,WAIvDF,EAAWrF,SAAW3d,GAAG2d,OAAOwC,QAChCle,KAAKG,IAAIpC,GAAG0L,OAAO,yDAA0D2R,EAAIpb,KAAKkhB,QAAQ9F,KAC9Fpb,KAAKmhB,YAAY/F,IACV,IAGPpb,KAAKG,IAAIpC,GAAG0L,OAAO,sDAAuD2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,UAG9F,KAGXgG,WAAY,SAAShG,GACjB,MAAOpb,MAAKqhB,gBAAgBjG,IAIhCkG,UAAW,SAASC,GAChB,MAAOvhB,MAAKygB,SAASe,QAAQD,IAOjCE,cAAe,SAASC,EAAQC,EAAaC,EAASC,EAAYC,GAC9D,GACIC,GAAWhlB,EADXilB,EAAkB,GAAIjkB,IAAGoP,OAqC7B,OAlCInN,MAAKiiB,iBACLF,EAAY/hB,KAAKkiB,eAAeR,GAChC3kB,GACI+kB,qBAAsBA,EACtBF,QAASA,EAAU,EAAIA,EAAU,KACjCO,MAAOP,EAAU,IAKhBC,GAAc9jB,GAAGiW,kBAAkBiD,gBACpC8K,EAAY/hB,KAAKoiB,QAAQV,IAIZ,MAAbK,EACAC,EAAgBzU,SAAS8U,UAAWV,EAAazhB,MAAO,2BAGxDF,KAAKiiB,gBAAgBK,SAASP,EAAWJ,EAAa5kB,GAASkb,KAC3D,SAAiBsK,GACbP,EAAgB3U,QAAQkV,IAG5B,SAAiBF,EAAWG,GACxBR,EAAgBzU,SAAS8U,UAAWA,EAAWniB,MAAOsiB,GAAU,oCAM5ER,EAAgBzU,SAAS8U,UAAWV,EAAazhB,MAAO,mCAGrD8hB,GAGXS,UAAW,SAASf,GAChB,MAAO1hB,MAAK0iB,WAAW1iB,KAAK2iB,qBAAqBjB,KAGrDkB,YAAa,SAASlB,GAClB,MAAO1hB,MAAK6iB,eAAeC,IAAIpB,IAGnCU,QAAS,SAASb,GACd,MAAOvhB,MAAKygB,SAAS2B,QAAQb,IAAiB,MAGlDwB,cAAe,WACX,MAAO/iB,MAAKghB,YAAYrE,UACpBjB,QACI3d,GAAG2d,OAAOyC,UACVpgB,GAAG2d,OAAO0C,gBACVrgB,GAAG2d,OAAOsC,UAEf5b,QAGP8e,QAAS,SAAS9F,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKrc,MAI/CikB,YAAa,SAAS5H,GAClB,GAAI6H,GAAkBjjB,KAAKkjB,YAAY9H,GAAIA,IACvCuC,EAAW,IAQf,OANIsF,IACiC5kB,SAA7B4kB,EAAgBtF,WAChBA,EAAWsF,EAAgBtF,UAI5BA,GAGXwF,sBAAuB,WACnB,MAAOnjB,MAAKygB,SAAS0C,yBAGzBC,QAAS,SAAShI,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKmB,MAG/C8G,cAAe,WACX,MAAOrjB,MAAKsjB,cAGhBC,yBAA0B,WACtB,GAAIC,GAAexjB,KAAKyjB,iBAExB,OAAID,GAAe,EACRA,EAAexjB,KAAK0jB,qBAGxB,MAGXR,WAAY,SAAStG,GACjB,MAAO5c,MAAKghB,YAAYrE,SAASC,IAGrC+G,QAAS,SAASvI,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKG,MAG/Cpb,IAAK,SAASuJ,EAAKvB,IACXnI,KAAKpB,SAASglB,OAAWzb,GAAmB,SAAVA,EAG7BA,GAAmB,SAAVA,GACdpK,GAAGoC,IAAI,kBAAoBpC,GAAGgW,QAAU,KAAOrK,EAAKvB,GAHpDpK,GAAGoC,IAAI,kBAAoBpC,GAAGgW,QAAU,KAAOrK,IAQvDma,YAAa,SAASzI,GAClB,GAAI2F,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAEhD,KAAKrd,GAAGiW,kBAAkBoD,QAAUpX,KAAKpB,SAAS4X,SAASyK,QACvD,OAAO,CAIX,IAAIljB,GAAG6J,SAAS7J,GAAG2d,OAAOyC,UAAWpgB,GAAG2d,OAAO0C,iBAAkB2C,EAAWrF,SAAW,EAAG,CACtF,GAAI1b,KAAKygB,SAASrJ,MAAMgE,GAEpB,MADApb,MAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOwC,SAClC,CAGPle,MAAKG,IAAIpC,GAAG0L,OAAO,mCAAoC2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,aAIlFpb,MAAKG,IAAIpC,GAAG0L,OAAO,wDAAyD2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,QAGvG,QAAO,GAGXN,MAAO,WACH9a,KAAKG,IAAI,yBAETH,KAAKygB,SAAS3F,QACd9a,KAAKof,cACLpf,KAAK8jB,gBACL9jB,KAAK+jB,kBACL/jB,KAAKgkB,mBACLhkB,KAAKkiB,kBAELnkB,GAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjCA,EAAOpJ,UAGX9a,KAAKmkB,aAAarJ,QAClB9a,KAAK6iB,eAAe/H,QACpB9a,KAAK0jB,qBAAuB,EAC5B1jB,KAAKsjB,aAAe,EACpBtjB,KAAKghB,YAAYlG,QACjB9a,KAAK2iB,wBAEL3iB,KAAKokB,eAAiBpkB,KAAKokB,cAActJ,QACzC9a,KAAKpB,SAASylB,QAAQC,gBAAkBtkB,KAAKukB,sBAE7CvkB,KAAKwkB,kCACLxkB,KAAKykB,+BAELzkB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAe5J,SAG/C6J,MAAO,SAASvJ,GACZ,MAAOpb,MAAK4kB,aAAaxJ,IAG7ByJ,WAAY,SAASzJ,EAAI0J,GACrB,GAAI/iB,GAAO/B,IAEX,OAAOjC,IAAGgnB,OAAOxlB,UAAUslB,WAAWzJ,EAAI0J,GACtC3kB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBqgB,QAASrkB,GAAGgT,KAAKhP,EAAKqgB,QAASrgB,GAC/Bgf,WAAYhf,EAAKif,eAIzBgE,iBAAkB,SAASC,EAAS7J,GAChCpb,KAAKklB,oBAAoBC,IAAIF,EAAS7J,IAG1CgK,2BAA4B,SAASH,EAAS7J,GAC1Cpb,KAAKqlB,8BAA8BF,IAAIF,EAAS7J,IAGpDkK,sBAAuB,SAASzG,EAAUzD,GACtCpb,KAAKulB,yBAAyBJ,IAAItG,EAAUzD,IAGhDoK,oBAAqB,SAASjoB,EAAQ6d,GAClCpb,KAAKylB,uBAAuBN,IAAI5nB,EAAQ6d,IAI5CsK,YAAa,SAAS7G,EAAUzD,GAC5Bpb,KAAK6iB,eAAesC,IAAItG,EAAUzD,IAGtCuK,QAAS,SAASC,GACd5lB,KAAK6lB,4BAA4BD,IAGrCE,aAAc,SAASC,GACnB/lB,KAAKyjB,kBAAoBsC,GAG7BC,QAAS,SAAS5K,EAAIkC,GAClBtd,KAAKghB,YAAY3D,WAAWjC,EAAIkC,IAGpC2I,UAAW,SAAS1oB,EAAQ6d,GACxBpb,KAAKmkB,aAAagB,IAAI5nB,EAAQ6d,IAGlC8K,QAAS,SAAS9K,EAAI+B,GAClB,MAAOnd,MAAKghB,YAAY9D,YAAY9B,EAAI+B,IAG5CgJ,kBAAmB,WACgB,IAA3BnmB,KAAKof,WAAWhd,OAChBpC,KAAKomB,WAAW,gBAGhBpmB,KAAKqmB,uBAQjBtoB,GAAGuoB,gBAECpH,eAAgB,SAASqH,GACrB,GAAInL,GAAKpb,KAAKghB,YAAY7E,SACtBZ,KAAMgL,EAAYhL,KAClBxc,KAAMwnB,EAAYxnB,KAClBwd,KAAMgK,EAAYhK,KAClBb,OAAQ3d,GAAG2d,OAAO2C,mBAatB,OAVAkI,GAAYC,oBAAsBxmB,KAAKslB,sBAAsBiB,EAAYC,mBAAoBpL,GAC7FmL,EAAYE,kBAAoBzmB,KAAKwlB,oBAAoBe,EAAYE,iBAAkBrL,GAEnFmL,EAAYG,eACZ1mB,KAAKkiB,eAAe9G,GAAMmL,EAAYG,cAG1C1mB,KAAKsjB,eACLtjB,KAAK0jB,uBAEEtI,GAGXuL,sBAAuB,SAASvG,EAAMwG,GAC9B7oB,GAAGgM,OAAOqW,KACVA,EAAKyG,WAAa7mB,KAAK8mB,aAAaF,KAI5CG,YAAa,SAAS3mB,GAClBJ,KAAKpB,SAASF,UAAUsoB,QAAQ,KAAM,KAAM5mB,EAAS/B,SAGzD4oB,qBAAsB,WAClB,GAAIllB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGmpB,yBACVC,OAAQnnB,KAAKpB,SAASwiB,WAAW+F,OAAOvpB,cACxCwpB,eAAgBpnB,KAAKpB,SAASwoB,eAC9BC,cAAernB,KAAKpB,SAAS0oB,QAAQC,SACrCC,cAAexnB,KAAKqlB,8BACpBoC,YAAaznB,KAAKylB,uBAClBiC,cAAe1nB,KAAKulB,yBACpBoC,KAAM3nB,KAAKpB,SAAS+oB,KACpBxnB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvB6lB,SAAU,SAASxM,GACfrZ,EAAK8lB,UAAUzM,GACfrZ,EAAKnD,SAASF,UAAUkpB,SAASxM,IAErC0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,GACrCjmB,EAAKkmB,kBAAkB7M,EAAI2M,EAAUC,GACrCjmB,EAAKnD,SAASF,UAAUopB,iBAAiB1M,EAAI2M,EAAUC,OAMnEE,oBAAqB,WACjB,GAAInmB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGoqB,cACVC,cAAepoB,KAAKpB,SAASypB,MAAMD,cACnC1pB,WACIyB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBumB,cAAe,SAASzb,GACpB9K,EAAKwmB,wBACDxpB,KAAM,kBACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAU8pB,gBAAiBzmB,EAAM8K,GACjE2L,UAAWza,GAAGgT,KAAKhP,EAAK0mB,oBAAqB1mB,EAAM8K,GACnD6b,WAAY,sBAOhCC,aAAc,SAASC,EAAcC,GACjC,GAAIC,MACAC,EAAWH,EACXI,KACAC,EAAiBJ,EACjBK,EAAO,SAASC,GACZ,MAAIprB,IAAGsK,SAAS8gB,GACLprB,GAAGwG,UAAW4kB,GAElBA,GAEXC,EAAoB,WAChB,MAAIrrB,IAAG0K,WAAWwgB,GACPA,IAEJA,GAEXI,EAAwB,SAASjO,EAAIkO,GAC7BL,GAAkBlrB,GAAGsK,SAASihB,IAC9BvrB,GAAGwG,OAAO+kB,EAAUF,KAGpBJ,EAAoB5N,IACpBrd,GAAGwG,OAAO+kB,EAAUN,EAAoB5N,IAIpD,QACI+J,IAAK,SAAShnB,EAAKid,GAEL,MAANA,GACA0N,KACAC,EAAWG,EAAK/qB,IAGhB2qB,EAAM1N,GAAM8N,EAAK/qB,IAIzB2kB,IAAK,SAAS1H,GACV,GAAImO,EAYJ,OARIA,GADM,MAANnO,GAAc0N,EAAM1N,GACX0N,EAAM1N,GAGN8N,EAAKH,GAGlBM,EAAsBjO,EAAImO,GAEnBL,EAAKK,IAGhBC,YAAa,SAASpO,EAAImO,GAElBxrB,GAAGsK,SAASygB,KAED,OAAP1N,EACIrd,GAAG0K,WAAW8gB,GACdN,EAAiBM,GAGjBN,EAAiBA,MACjBlrB,GAAGwG,OAAO0kB,EAAgBM,KAI9BP,EAAoB5N,GAAM4N,EAAoB5N,OAC9Crd,GAAGwG,OAAOykB,EAAoB5N,GAAKmO,MAK/CzlB,OAAQ,SAAS4d,GACb,aAAcoH,GAAMpH,IAGxB5G,MAAO,WACHgO,KACAE,KACAD,EAAWH,KAKvBa,yBAA0B,WACtB,GAAI1nB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGgd,YACVmG,QAAS,SAAS9F,GACd,MAAOrZ,GAAKmf,QAAQ9F,IAExBuI,QAAS,SAASvI,GACd,MAAOrZ,GAAK4hB,QAAQvI,IAExBgI,QAAS,SAAShI,GACd,MAAOrZ,GAAKqhB,QAAQhI,IAExBsB,eAAgB,SAAStB,EAAI2B,EAAWD,GACpC/a,EAAK2nB,sBAAsBtO,EAAI2B,EAAWD,GAC1C/a,EAAKnD,SAASF,UAAUge,eAAetB,EAAI2B,EAAWD,GACtD/a,EAAK4nB,kBAAkBvO,EAAI0B,GAEvB/a,EAAK2iB,gBACLkF,WAAW,WACP7nB,EAAK2iB,eAAehI,eAAetB,EAAI2B,EAAWD,IACnD,OAcnB+M,oBAAqB,SAASzN,GAM1B,QAAS0N,KACL,QAAI/rB,GAAGiW,kBAAkBqC,kBAEjBtU,EAAKnD,SAASmrB,YAAYC,gBAC1BjsB,GAAG6R,QACF7R,GAAG4R,QACJ5N,EAAKkoB,oBAAoBC,EAAmB,WAK1B7rB,SAAlB+d,EAAKhR,SACErJ,EAAKnD,SAASwM,SAGlBgR,EAAKhR,WApBpB,GAGI8Y,GAHAniB,EAAO/B,KACPuZ,EAAc6C,EAAK+N,QAAUnqB,KAAKpB,SAASwrB,WAAW7Q,YACtD2Q,EAAoB9N,EAAK8N,mBAAqBlqB,KAAKpB,SAASwrB,WAAWF,iBA6C3E,OArBAhG,GAAS,GAAInmB,IAAGgb,cACZQ,YAAaA,EACb9Y,QAAS2b,EAAK3b,QACd2Z,WAAYpa,KAAKpB,SAASyrB,QAAQC,YAClChR,QAAS8C,EAAK9C,QACda,WAAYna,KAAKpB,SAASyrB,QAAQE,YAClClQ,2BAA4Bra,KAAKpB,SAASmrB,YAAYS,iBACtDpf,SAAU0e,IACV/qB,KAAMiB,KAAKpB,SAAS0oB,QAAQmD,UAC5BvQ,SAAU,SAASjP,GACflJ,EAAK2oB,eAAezf,IAExBmO,MAAqB,MAAdgD,EAAKhD,MAAgBpZ,KAAKpB,SAASkH,KAAK6kB,eAAiBvO,EAAKhD,QAGzEpZ,KAAK4qB,gBAAgBnX,YAAY,WAC7ByQ,EAAO5Q,YAGXvR,EAAKkiB,SAASpkB,KAAKqkB,GAEZA,GAGX2G,qBAAsB,SAASC,EAAmBptB,GAC9C,GAAIqE,GAAO/B,KACP+qB,KACAhuB,GACI6mB,MAAO5jB,KAAKpB,SAASglB,MACrBwD,eAAgBpnB,KAAKpB,SAASwoB,eAC9BO,KAAM3nB,KAAKpB,SAAS+oB,KACpBF,YAAaznB,KAAKmkB,aAClBuD,cAAe1nB,KAAK6iB,eACpBrM,SAAUxW,KAAKpB,SAAS4X,SACxBc,OAAQtX,KAAKpB,SAAS0Y,OACtBkI,MAAOxf,KAAKpB,SAAS4gB,MACrBrf,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBipB,kBAAmBhrB,KAAKpB,SAAS+lB,MAAMsG,6BACvCC,WAAY,SAAS9P,EAAIrc,EAAMosB,EAAQC,GAC/BD,EAAS,GAAKC,EAAQ,IAItBL,EAAe3P,GACX2P,EAAe3P,GAAI+P,SAAWA,GAAUJ,EAAe3P,GAAIgQ,QAAUA,IACrErpB,EAAKspB,YAAYjQ,EAAIrc,EAAMosB,EAAQC,GACnCrpB,EAAKnD,SAASF,UAAUwsB,WAAW9P,EAAIrc,EAAMosB,EAAQC,KAIzDrpB,EAAKspB,YAAYjQ,EAAIrc,EAAMosB,EAAQC,GACnCrpB,EAAKnD,SAASF,UAAUwsB,WAAW9P,EAAIrc,EAAMosB,EAAQC,IAGzDL,EAAe3P,IAAO+P,OAAQA,EAAQC,MAAOA,KAGjDE,WAAY,SAASlQ,EAAIrc,EAAMqG,EAAQqP,SAC5BsW,GAAe3P,EAEtB,IACI9Z,GADAoa,EAAS3Z,EAAKmhB,YAAY9H,GAAIA,IAAKM,MAOnCA,KAAW3d,GAAG2d,OAAO2C,mBAAqB3C,IAAW3d,GAAG2d,OAAO4C,gBAInEhd,EAASS,EAAKwpB,YAAYnQ,EAAIrc,EAAMqG,EAAQqP,GAIxCnT,YAAmBvD,IAAGoP,QACtB7L,EAAOoX,KAAK,WACR3W,EAAKnD,SAASF,UAAU4sB,WAAWlQ,EAAIrc,EAAMqG,EAAQqP,KAIzD1S,EAAKnD,SAASF,UAAU4sB,WAAWlQ,EAAIrc,EAAMqG,EAAQqP,KAG7D+W,SAAU,SAASpQ,EAAIrc,EAAM0sB,GACzB,GAAIve,GAAU,GAAInP,IAAGoP,OAgBrB,OAdApL,GAAKwmB,wBACDxpB,KAAM,WACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAU8sB,SAAUzpB,EAAMqZ,EAAIrc,GAC9D0Z,UAAWvL,EAAQK,QACnBiL,UAAW,WACPiT,EAAyBxT,KAAK,WAC1BlW,EAAK2pB,UAAUtQ,EAAIrc,KAGvBmO,EAAQG,WAEZqb,WAAYtN,IAGTlO,GAEXye,aAAc5tB,GAAGgT,KAAK/Q,KAAK4rB,cAAe5rB,MAC1C6rB,SAAU,SAASzQ,EAAIrc,GACnBgD,EAAK+pB,UAAU1Q,EAAIrc,GACnBgD,EAAKnD,SAASF,UAAUmtB,SAASzQ,EAAIrc,IAEzCgtB,cAAe,SAAS3Q,EAAIrc,EAAMitB,GAC9BjqB,EAAKkqB,eAAe7Q,EAAI4Q,GACxBjqB,EAAKnD,SAASF,UAAUqtB,cAAc3Q,EAAIrc,EAAMitB,IAEpDE,qBAAsB,SAAS9Q,EAAI4Q,EAAW5mB,EAAQqP,GAClD1S,EAAKnD,SAASF,UAAUwtB,qBAAqBnsB,MAAMgC,EAAMtC,YAE7D0sB,SAAU,SAAS/Q,EAAIrc,EAAMitB,GACzB,MAAOjqB,GAAKnD,SAASF,UAAUytB,SAAS/Q,EAAIrc,EAAMitB,IAEtDI,YAAa,SAAShR,EAAIrc,EAAMstB,EAAc5X,GAC1C,MAAO1S,GAAKuqB,aAAavsB,MAAMgC,EAAMtC,YAEzC8sB,cAAe,SAASnR,EAAI+B,GACxBpb,EAAK5B,IAAI,sCAAwC4B,EAAK4hB,QAAQvI,GAAM,SAAW+B,EAAU,KACzFpb,EAAKmkB,QAAQ9K,EAAI+B,IAErB+D,QAASnjB,GAAGgT,KAAKhP,EAAKmf,QAASnf,GAC/B4hB,QAAS5lB,GAAGgT,KAAKhP,EAAK4hB,QAAS5hB,GAC/BqhB,QAASrlB,GAAGgT,KAAKhP,EAAKqhB,QAASrhB,GAC/ByqB,QAASzuB,GAAGgT,KAAKhP,EAAK0qB,SAAU1qB,GAChC2qB,cAAe,SAASnR,GACpB,MAAOxZ,GAAKmhB,YAAY3H,KAAMA,KAElCoR,SAAU,SAASvR,GACf,GAAIM,GAAS3Z,EAAKmhB,YAAY9H,GAAIA,IAAKM,MACvC,OAAOA,KAAW3d,GAAG2d,OAAOsC,QACxBtC,IAAW3d,GAAG2d,OAAOoC,WACrBpC,IAAW3d,GAAG2d,OAAO0C,iBACrB1C,IAAW3d,GAAG2d,OAAOwC,QAE7BN,mBAAoB7b,EAAKif,YAAYpD,mBACrCC,cAAe9b,EAAKif,YAAYnD,cAexC,OAZA9f,IAAGY,KAAKqB,KAAKpB,SAAS0oB,QAAS,SAASzoB,EAAMV,GAC1CpB,EAAQ8B,GAAQV,IAGpBpB,EAAQyqB,cAAgBxnB,KAAKklB,oBAEzB4F,GACA/sB,GAAGY,KAAKmsB,EAAmB,SAAS5sB,EAAKC,GACrCpB,EAAQmB,GAAOC,IAIhB,GAAIJ,IAAG6uB,wBAAwB7vB,EAASW,IAGnDmvB,oBAAqB,SAASzR,GAC1Bpb,KAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOqC,WAG7C+O,YAAa,SAASrgB,GAClB,GAAc,IAAVA,EACA,MAAOA,GAAQzM,KAAKpB,SAASkH,KAAKinB,YAAY,EAElD,IAAInb,IAAI,CACR,GACInF,IAAgB,IAChBmF,UACKnF,EAAQ;AAEjB,MAAOpI,MAAK2oB,IAAIvgB,EAAO,IAAKwgB,QAAQ,GAAKjtB,KAAKpB,SAASkH,KAAKinB,YAAYnb,IAK5Esb,0BAA2B,WACvB,GAAInrB,GAAO/B,IAEXA,MAAKmtB,qBAELpvB,GAAGY,KAAKqB,KAAKpB,SAASwuB,aAAc,SAASztB,EAAK0tB,GAC9C,GAAIjiB,GAAWiiB,EAAuBjiB,SAClCgf,EAAarsB,GAAGwG,UAAWxC,EAAKnD,SAASwrB,YAAY,GACrDkD,EAAkBvvB,GAAGwG,UAAW8oB,EAEnBhvB,UAAb+M,IACAA,EAAWrJ,EAAKnD,SAASwM,UAGzBkiB,EAAgBlD,YAChBrsB,GAAGwG,OAAO6lB,EAAYiD,EAAuBjD,YAAY,GAG7DrsB,GAAGwG,OAAO+oB,GACNliB,SAAUA,EACVgf,WAAYA,IACb,GAEHroB,EAAKwrB,iBAAiBD,MAI9B5K,WAAY,SAASvJ,GACjB,GAAIqU,GAAmBxtB,KAAKmtB,kBAAkBhU,EAE9C,OAAIqU,GACOA,EAAiB/sB,QAEnB0Y,IAAanZ,KAAKytB,iBAChBztB,KAAKpB,SAASslB,OADpB,QAYT4C,aAAc,SAAS4G,GACnB,GAAIC,GAAQC,EACRC,EAAkBH,CAQtB,IALIG,YAA2B9vB,IAAG4a,YAC9BkV,EAAkBA,EAAgBjV,eAIlCiV,IAAoB9vB,GAAG+M,OAAO+iB,GAAkB,CAChD,GAAI9vB,GAAGgM,OAAO8jB,GACV,MAAOA,GAAgBhH,UAEtB,IAA8C,UAA1CgH,EAAgBhjB,QAAQ/M,eACU,SAAvC+vB,EAAgB1sB,KAAKrD,cAErB,MAAO+vB,GAAgBxnB,aAAatI,GAAGgb,aAAaG,oBAYxD,IATAyU,EAASE,EAAgBtoB,qBAAqB,SAE9CxH,GAAGY,KAAKgvB,EAAQ,SAAShuB,EAAKsL,GAC1B,GAAmC,SAA/BA,EAAM5E,aAAa,QAEnB,MADAunB,GAAY3iB,GACL,IAIX2iB,EACA,MAAOA,GAAUvnB,aAAatI,GAAGgb,aAAaG,uBAK1D4U,gBAAiB,WACb,MAAO9tB,MAAKghB,YAAYrE,UACpBjB,QACI3d,GAAG2d,OAAOyC,UACVpgB,GAAG2d,OAAO0C,gBACVrgB,GAAG2d,OAAOsC,OACVjgB,GAAG2d,OAAOW,WACVte,GAAG2d,OAAOoC,UACV/f,GAAG2d,OAAOwC,UAEf9b,QAKP2rB,mBAAoB,SAAS5U,GACzB,GAAImU,GAAkBttB,KAAKmtB,kBAAkBhU,EAE7C,OAAOmU,GAAkBA,EAAgBlD,WAAapqB,KAAKpB,SAASwrB,YAGxE4D,yBAA0B,SAASC,GAC/B,MAAIA,GAAY7N,eAAgBriB,IAAG4a,WAE3B5Z,KAAMhB,GAAGkV,YAAYgb,EAAY7N,KAAKxH,eACtC2D,KAAM0R,EAAY7N,KAAKxH,cAAc2D,OAKzCxd,KAAMiB,KAAKkjB,YAAY9H,GAAI6S,EAAY7S,KAAKrc,KAC5Cwd,KAAMvc,KAAKkjB,YAAY9H,GAAI6S,EAAY7S,KAAKmB,OAIpD2R,0BAA2B,SAASC,GAChC,GAAIpsB,GAAO/B,KACPouB,IAMJ,OAJArwB,IAAGY,KAAKwvB,EAAc,SAASxuB,EAAKsuB,GAChCG,EAAgBvuB,KAAKkC,EAAKisB,yBAAyBC,MAGhDG,GAIXC,oBAAqB,WACjB,GAAIruB,KAAKpB,SAAS0vB,OAAO1e,KAAO7R,GAAG6R,MAAO,CACtC,GAAI2e,GAAkB,yBAClBrK,EAASlkB,KAAKpB,SAAS0vB,OAAOpK,OAC9B/K,EAAW+K,EAASlkB,KAAK8mB,aAAa5C,GAAUlkB,KAAKytB,iBACrDe,EAAaxuB,KAAKpB,QAGlBua,IAAYA,IAAanZ,KAAKytB,mBAC9Be,EAAaxuB,KAAKmtB,kBAAkBhU,IAIxCqV,EAAWpjB,UAAW,EAGoB,OAAtCojB,EAAWpE,WAAW7Q,YACtBiV,EAAWpE,WAAW7Q,YAAcgV,EAGpCC,EAAWpE,WAAW7Q,aAAe,IAAMgV,EAI/CxwB,GAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjC,GAAIA,EAAOzJ,gBAAkBtB,EAIzB,MAHA+K,GAAO7K,YAAYmV,EAAWpjB,UAC9B8Y,EAAOrJ,eAAe2T,EAAWjV,cAE1B,MAMvBgP,uBAAwB,SAASkG,GAC7B,GAAI1sB,GAAO/B,KACP0uB,EAAiBD,EAAQ9d,UAE7B,OAAI5S,IAAGga,iBAAiB2W,IACpB1uB,KAAKG,IAAIsuB,EAAQ1vB,KAAO,kBAAoB0vB,EAAQ1vB,KAAO,gCAAkC0vB,EAAQ/F,YAC9FgG,EAAezW,KAClB,SAAS0W,GACL5sB,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,YAC1D+F,EAAQjW,UAAUmW,IAEtB,WACQF,EAAQhW,WACR1W,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,YAC1D+F,EAAQhW,aAGR1W,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,gBAKtEgG,KAAmB,EACnBD,EAAQjW,UAAUkW,GAGdD,EAAQhW,WACRzY,KAAKG,IAAIsuB,EAAQ1vB,KAAO,mCAAqC0vB,EAAQ/F,WAAa,iCAClF+F,EAAQhW,aAGRzY,KAAKG,IAAIsuB,EAAQ1vB,KAAO,mCAAqC0vB,EAAQ/F,WAAa,wBAInFgG,IAIXnP,eAAgB,SAASa,EAAM5D,EAASoS,GACpC,GAAI7sB,GAAO/B,KACPub,EAAOxd,GAAGuQ,cACViO,GAAO,EACPxd,EAAOhB,GAAGkV,YAAYmN,GACtByO,EAAazO,EAAKvT,MAAQuT,EAC1B0O,EAAU9uB,KAAK+uB,sBACX/uB,KAAK+uB,sBACLhxB,GAAGgT,KAAKhP,EAAKitB,sBAAuBjtB,IAEvChE,GAAGwM,QAAQskB,IAAeA,EAAWtS,MAAQ,IAC9CA,EAAOsS,EAAWtS,MAGtBuS,EAAQD,EAAY9vB,EAAMwc,EAAMgB,EAAMqS,EAAoBpS,EAASxc,KAAKpB,SAAS0oB,QAAQC,UACrFxG,WAAYhf,EAAKif,YACjByG,YAAa1lB,EAAKoiB,aAClB8K,iBAAkB,SAAS7T,EAAIgF,GAC3Bre,EAAK0e,SAAS/O,IAAI0J,EAAIgF,GACtBre,EAAK2hB,uBACL3hB,EAAKmtB,aAAa9T,OAK9B4T,sBAAuB,SAAS5O,EAAMrhB,EAAMwc,EAAMgB,EAAM4S,EAAU3S,GAC9D,GAAIpB,GAAKpb,KAAKghB,YAAY7E,SAASZ,KAAMA,EAAMxc,KAAMA,EAAMwd,KAAMA,EAAMC,QAASA,GAEhFxc,MAAKygB,SAAS/O,IAAI0J,EAAIgF,GACtBpgB,KAAKkvB,aAAa9T,GAElBpb,KAAK0jB,uBAELyL,EAAStvB,MAAMub,GAAIA,EAAIgF,KAAMA,KAGjCqI,oBAAqB,SAAS5b,EAAMuiB,GAChC,GAAIC,GAAYxiB,EAAK1L,KAAKwG,MAAM,KAAK,GACjC5I,EAAOqwB,CAGC,OAARrwB,IACAA,EAAOiB,KAAKpB,SAASypB,MAAM5I,aAG/B1gB,GAAQ,IAAMswB,EAEdrvB,KAAK8e,UACD/f,KAAMA,EACN8N,KAAMA,KAKd0gB,iBAAkB,SAASnR,GACvB,GAAI8H,GAASlkB,KAAK6pB,qBACdM,OAAQ/N,EAAKgO,WAAW7Q,YACxB2Q,kBAAmB9N,EAAKgO,WAAWF,kBACnCzpB,QAAS2b,EAAK3b,QACd6Y,QAAS8C,EAAK9C,QACdlO,SAAUgR,EAAKhR,SACfgO,MAAOgD,EAAKuO,gBAGhB3qB,MAAKmtB,kBAAkBjJ,EAAOzJ,eAAiB2B,GAGnDkT,0BAA2B,WACvBtvB,KAAKuvB,aAAexxB,GAAGyxB,aAAe,GAAIzxB,IAAGyxB,YACzCxvB,KAAKpB,SAASwT,KAAMrU,GAAGgT,KAAK/Q,KAAKmmB,kBAAmBnmB,MAAOjC,GAAGgT,KAAK/Q,KAAKG,IAAKH,OAG7EA,KAAKuvB,cAAgBvvB,KAAKuvB,aAAaE,gBACvCzvB,KAAKmkB,aAAenkB,KAAK2oB,aACrB3oB,KAAKpB,SAAS0oB,QAAQ/pB,OAASyC,KAAKuvB,aAAaG,uBAGrD1vB,KAAKpB,SAAS+wB,WAAa3vB,KAAKuvB,aAAaK,cACzC5vB,KAAKuvB,aAAaM,cAClB7vB,KAAKpB,SAAS0oB,QAAQzI,SAAW7e,KAAKuvB,aAAaM,cAIvD7vB,KAAKmkB,aAAenkB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQ/pB,SAIpEuyB,kBAAmB,WACf,SAAK/xB,GAAGmpB,0BAA4BlnB,KAAKpB,SAASwiB,WAAWH,YAIzDjhB,KAAKpB,SAAS+oB,KAAKoI,aACfhyB,GAAGiW,kBAAkB2C,sBAIrB5Y,GAAGiW,kBAAkB0C,oBAAqB1W,KAAKpB,SAAS+oB,KAAKqI,aAUzE/F,oBAAqB,SAASgG,EAAS9c,GACnC,GAAI+c,IAAQ,CAEZ,QAAKD,EAAQ7tB,SAIbrE,GAAGY,KAAKsxB,EAAS,SAAStwB,EAAKwwB,GAK3B,GAAIpyB,GAAGoL,SAASgnB,GAAa,CAEzB,GAAIC,GAAW,GAAIzrB,QAAO,MAAQwrB,EAAa,IAAK,IAEpD,IAAgC,MAA5Bhd,EAAS/R,MAAMgvB,GAEf,MADAF,IAAQ,GACD,KAKZA,IAWX9J,WAAY,SAASiK,EAAMC,EAAkBrnB,GASzC,QAASuF,GAAEzP,EAAMwxB,GAAenwB,EAAUA,EAAQ4E,QAAQjG,EAAMwxB,GARhE,GAMIC,GAAsBC,EANtBrwB,EAAUJ,KAAKpB,SAAS8xB,SAASL,GACjCnG,KACAyG,KAAWxf,OAAOmf,GAClBvxB,EAAO4xB,EAAM,GACbxX,EAAWnZ,KAAK8mB,aAAa7d,GAC7B2nB,EAAiB5wB,KAAK+tB,mBAAmB5U,EA+B7C,OA1BApb,IAAGY,KAAKiyB,EAAe1G,kBAAmB,SAASvqB,EAAKkxB,GAKhD9yB,GAAGoL,SAAS0nB,IACZ3G,EAAkBrqB,KAAKgxB,KAI/BL,EAAuBtG,EAAkBnY,KAAK,MAAMjU,cAEpD0Q,EAAE,SAAUxO,KAAKpB,SAASkyB,eAAe/xB,IACzCyP,EAAE,eAAgBgiB,GAClBhiB,EAAE,cAAexO,KAAK8sB,YAAY8D,EAAeG,YACjDviB,EAAE,iBAAkBxO,KAAK8sB,YAAY8D,EAAeI,eAEpDP,EAAmBrwB,EAAQgB,MAAM,cACR,OAArBqvB,GACA1yB,GAAGY,KAAK8xB,EAAkB,SAAS9wB,EAAKsxB,GACpCziB,EAAEyiB,EAAaN,EAAMhxB,MAI7BK,KAAKpB,SAASF,UAAUsoB,QAAQ,KAAMjoB,EAAMqB,EAAS/B,QAE9C+B,GAYXwkB,aAAc,SAASxJ,EAAIzK,GACvB,GAAI3Q,KAAKkxB,qBAAqB9V,GAW1B,MAVApb,MAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO0C,iBAErCzN,EACAA,EAASyK,GAGTpb,KAAKygB,SAASkE,MAAMvJ,IAGjB,GAIfuO,kBAAmB,SAASvO,EAAIM,GAC5B,GAAI3Z,GAAO/B,KACPmxB,EAAcnxB,KAAK8tB,iBAEnBpS,KAAW3d,GAAG2d,OAAO2C,kBACrBre,KAAKwkB,+BAA+B3kB,KAAKub,GAEpCM,IAAW3d,GAAG2d,OAAO4C,eAC1Bte,KAAKykB,4BAA4B5kB,KAAKub,GAGtB,IAAhB+V,IACCnxB,KAAKwkB,+BAA+BpiB,QAAUpC,KAAKykB,4BAA4BriB,SAEhFwnB,WAAW,WACP7nB,EAAKqvB,eAAervB,EAAKyiB,+BAAgCziB,EAAK0iB,8BAC/D,IAIXtF,iCAAkC,WAC9B,GAAIpd,GAAO/B,IAEX,IAAIA,KAAKpB,SAASmrB,YAAYsH,mBAAqBtzB,GAAGgS,UAAYhS,GAAGkS,YAIjE,KAHA2Z,YAAW,WACPziB,OAAOmqB,MAAMvvB,EAAKnD,SAAS8xB,SAASa,+BACrC,GACG,GAAIxzB,IAAGmG,MAAMlE,KAAKpB,SAAS8xB,SAASa,+BAIlDC,8BAA+B,SAASpW,EAAIrc,EAAM0yB,EAAUhd,GAGxD,IAAKgd,EAASpkB,QACV,GAAIoH,GAAsB,MAAfA,EAAIiH,SAAmB+V,EAASvxB,MACvCF,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,8BAAgC0V,EAAIiH,OAAQjH,OAErF,CACD,GAAIid,GAAcD,EAASvxB,MAAQuxB,EAASvxB,MAAQF,KAAKpB,SAASkH,KAAK6rB,oBACvE3xB,MAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM2yB,EAAajd,KAKnEmd,6CAA8C,SAASC,EAAWjmB,EAAO1J,EAAO3E,EAAQshB,GACpF,GAAI9c,GAAO/B,IAEX,IAAI4L,EAAMxJ,OAASF,EACf,GAAI2vB,IAAc7xB,KAAKpB,SAASwrB,WAAW0H,uBAEvClI,WAAW,WACP,GAAImI,GAAuBhwB,EAAKisB,yBAAyBpiB,EAAM1J,IAC3DiX,EAAWpX,EAAK+kB,aAAalb,EAAM1J,GAAOke,MAC1C8D,EAASniB,EAAK2gB,WAAWvJ,EAE7BpX,GAAKwmB,wBACDxpB,KAAM,aACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAUszB,WAAYjwB,EAAMgwB,EAAsB7N,GAClF1L,UAAWza,GAAGgT,KAAKhP,EAAKkwB,2BAA4BlwB,EAAM6J,EAAO1J,EAAO3E,EAAQshB,GAChFpG,UAAW1a,GAAGgT,KAAKhP,EAAKmwB,2BAA4BnwB,EAAM6J,EAAO1J,EAAO3E,EAAQshB,GAChF6J,WAAY,SAAWqJ,EAAqBhzB,KAAO,YAAcgzB,EAAqBxV,QAE3F,OAEF,KAAKsV,EACN,KAAO3vB,EAAQ0J,EAAMxJ,OAAQF,IACzBH,EAAK8qB,oBAAoBjhB,EAAM1J,GAAOkZ,KAMtDgW,eAAgB,SAASe,EAAYC,GACjCpyB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAe2N,cAAcF,EAAYC,EAAQpyB,KAAKgkB,iBAElFhkB,KAAKpB,SAASF,UAAU2zB,cAAct0B,GAAGwG,UAAW4tB,GAAap0B,GAAGwG,UAAW6tB,IAE/EpyB,KAAKwkB,kCACLxkB,KAAKykB,gCAeT6H,aAAc,SAASlR,EAAIrc,EAAMstB,EAAc5X,EAAK9D,GAChD,GAAI5O,GAAO/B,IAIX,IAFA+B,EAAKiiB,gBAAgB5I,GAAMiR,EAAatqB,EAAKnD,SAAS+lB,MAAMsG,8BAExDlpB,EAAKuwB,iBAAiBlX,EAAIrc,EAAMstB,GAAe,CAC/C,GAAIkG,GAAyD,IAAvCxwB,EAAKnD,SAAS+lB,MAAM6N,gBAkB1C,OAhBAzwB,GAAKyvB,8BAA8BzxB,MAAMgC,EAAMtC,WAC/CsC,EAAKnD,SAASF,UAAU0tB,YAAYhR,EAAIrc,EAAMgD,EAAK+hB,aAAa1I,IAChErZ,EAAK0wB,mBAAmBrX,EAAIrc,GAE5BgD,EAAKif,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO0C,iBACzCrc,EAAKgiB,eAAe3I,GAAMwO,WAAW,WACjC7nB,EAAK5B,IAAI,sBAAwBpB,EAAO,OAEpC4R,EACAA,EAASyK,GAGTrZ,EAAK0e,SAASkE,MAAMvJ,IAEzBmX,IAEI,IAIfE,mBAAoB,SAASrX,EAAIrc,GAC7BiB,KAAKG,IAAI,WAAaH,KAAKpB,SAAS+lB,MAAM6N,iBAAmB,4BAA8BzzB,EAAO,QAItGmyB,qBAAsB,SAAS9V,GAC3B,GACIjI,GADAuf,EAAY1yB,KAAKyjB,iBAGrB,OAAIzjB,MAAKgkB,gBAAgB5I,IACrBpb,KAAKG,IAAI,gCAAkCib,EAAI,SACxC,GAEFpb,KAAKygB,SAASe,QAAQpG,IAC3BjI,EAAWnT,KAAKkhB,QAAQ9F,GAEpBpb,KAAKpB,SAASF,UAAUi0B,cAAcvX,EAAIjI,MAAc,IAIxDuf,EAAY,GAAK1yB,KAAK0jB,qBAAuB,EAAIgP,GACjD1yB,KAAKomB,WAAW,0BACT,IAGXpmB,KAAKG,IAAI,wBAA0BgT,EAAW,UAAYiI,EAAK,SACxD,MAGPpb,KAAKG,IAAI,IAAMib,EAAK,2BAA4B,UACzC,IAIfsQ,UAAW,SAAStQ,EAAIrc,GACpBiB,KAAK0jB,uBAELkP,aAAa5yB,KAAK+jB,eAAe3I,GAEjC,IAAIyX,GAAkB90B,GAAG6J,QAAQ5H,KAAKof,WAAYhE,IAC7Cpb,KAAKpB,SAAS+wB,YAAckD,GAAmB,GAChD7yB,KAAKof,WAAWnC,OAAO4V,EAAiB,GAG5C7yB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOuC,WAG7CsN,YAAa,SAASnQ,EAAIrc,EAAMqG,EAAQqP,GAoBpC,MAnBKrP,GAAOiI,SASJjI,EAAOshB,eACP1mB,KAAKkiB,eAAe9G,GAAMhW,EAAOshB,cAGrC1mB,KAAKsjB,eACLtjB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO2C,qBAbzCre,KAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO4C,eAErClZ,EAAOpF,KAAKpB,SAAS+lB,MAAMsG,iCAAkC,IAC7DjrB,KAAKgkB,gBAAgB5I,IAAM,IAYnCpb,KAAKwxB,8BAA8BpW,EAAIrc,EAAMqG,EAAQqP,KAE9CrP,EAAOiI,SAGlBwa,UAAW,SAASzM,GAChBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO8C,WAG7CyJ,kBAAmB,SAAS7M,EAAI2M,EAAUC,GACtC,GAAIjpB,GAAOiB,KAAKkhB,QAAQ9F,EAEpB4M,IACAhoB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO6C,eACzCve,KAAKG,IAAI,uBAAyBpB,EAAO,gBAAiB,SAIzBV,SAA7B0pB,EAASrT,gBACT1U,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,wBAAyBgpB,GAGnE/nB,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,4CAA8CgpB,EAASrM,OAAQqM,KAI7G/nB,KAAK0jB,uBACL1jB,KAAKsjB,eACLtjB,KAAKygB,SAASqS,QAAQ1X,GACtBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO+C,SACzCze,KAAKG,IAAI,uBAAyBpB,EAAO,sBAIjD2rB,eAAgB,SAASzf,GACrB,GAAI8nB,EAEJ,IAAIh1B,GAAGiW,kBAAkBqC,cAAe,CACpC,IAAK0c,EAAY,EAAGA,EAAY9nB,EAAMkV,MAAM/d,OAAQ2wB,IAChD/yB,KAAK2mB,sBAAsB1b,EAAMkV,MAAM4S,GAAY9nB,EAGvDjL,MAAK8e,SAAS7T,EAAMkV,WAGflV,GAAMvC,MAAMtG,OAAS,GAC1BpC,KAAK8e,SAAS7T,EAGlBlN,IAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjCA,EAAOpJ,WAIfuQ,YAAa,SAASjQ,EAAIrc,EAAMosB,EAAQC,GACpCprB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAesO,qBAAqB5X,EAAI+P,EAAQC,IAGhF6H,UAAW,SAAS7X,EAAIrc,KAIxBm0B,yBAA0B,SAAS9X,EAAIrc,GACnCiB,KAAKizB,UAAUlzB,MAAMC,KAAMP,WAC3BO,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOoC,WACzC9d,KAAKmzB,aAAapzB,MAAMC,KAAMP,WAE1BO,KAAKpB,SAAS+wB,YACd3vB,KAAKpB,SAASF,UAAU00B,YAAYrzB,MAAMC,KAAMP,WAChDO,KAAKmhB,YAAY/F,KAGjBpb,KAAKqzB,eAAejY,GACpBpb,KAAKpB,SAASF,UAAU00B,YAAYrzB,MAAMC,KAAMP,aAIxD4hB,gBAAiB,SAASjG,EAAIkY,EAAmBC,GAC7C,GACIC,GADAjY,EAAOvb,KAAK2jB,QAAQvI,EAOxB,OAJIkY,KACAE,EAA4Bz1B,GAAGgT,KAAKuiB,EAAmBtzB,KAAMob,EAAIG,EAAMgY,IAGvEvzB,KAAK8vB,qBACL9vB,KAAKuoB,wBACDxpB,KAAM,iBACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU+0B,eAAgBzzB,KAAMob,GAChE5C,UAAWgb,GACPz1B,GAAGgT,KAAK/Q,KAAK0zB,eAAeC,WAAY3zB,KAAMob,EAAIG,EAAMgY,GAC5D7K,WAAYtN,KAET,IAGPpb,KAAKG,IAAI,iCAAmCib,EAAK,wHACuB,SACjE,IAIf+X,aAAc,SAAS/X,KAIvBwY,iBAAkB,SAASzI,EAAQC,GAC/BprB,KAAKpB,SAASF,UAAUm1B,gBAAgB1I,EAAQC,IAGpDQ,cAAe,SAASxQ,KAIxB0Q,UAAW,SAAS1Q,EAAIrc,GACpBiB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOyC,YAG7C8N,eAAgB,SAAS7Q,EAAI4Q,KAI7BtC,sBAAuB,SAAStO,EAAI2B,EAAWD,GAEvCA,IAAc/e,GAAG2d,OAAOwC,QACxB0U,aAAa5yB,KAAK+jB,eAAe3I,KAIzC0Y,gCAAiC,SAAS3F,GACtC,GAAIpsB,GAAO/B,IAEXjC,IAAGY,KAAKwvB,EAAc,SAASxuB,EAAKsuB,GAChClsB,EAAK8qB,oBAAoBoB,EAAY7S,OAI7C2Y,gCAAiC,SAASC,EAAuBpoB,EAAOrO,EAAQshB,EAAUqF,GACtF,GAAI+P,GACAvB,EAAY1yB,KAAKyjB,kBACjByQ,EAAmCl0B,KAAK0jB,oBAE1B,KAAdgP,GAAmBwB,GAAoCxB,EACnD9mB,EAAMxJ,OAAS,EACfpC,KAAKuoB,wBACDxpB,KAAM,aACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAUszB,WAAYhyB,KAAMg0B,EAAsB,GAAI9P,GACtF1L,UAAWza,GAAGgT,KAAK/Q,KAAKiyB,2BAA4BjyB,KAAM4L,EAAO,EAAGrO,EAAQshB,GAC5EpG,UAAW1a,GAAGgT,KAAK/Q,KAAKkyB,2BAA4BlyB,KAAM4L,EAAO,EAAGrO,EAAQshB,GAC5E6J,WAAY,SAAW9c,EAAM,GAAGwU,KAAKrhB,KAAO,YAAc6M,EAAM,GAAGwU,KAAK7D,OAI5Evc,KAAKomB,WAAW,iBAIpBpmB,KAAK8zB,gCAAgCloB,GACrCqoB,EAAej0B,KAAKpB,SAAS8xB,SAASyD,kBACjCnvB,QAAQ,gBAAiBkvB,GACzBlvB,QAAQ,iBAAkB0tB,GAC/B1yB,KAAK+mB,YAAYkN,KAIzB/B,2BAA4B,SAAStmB,EAAO1J,EAAO3E,EAAQshB,GACvD,GAAIuV,GAAYlyB,EAAQ,CAExBlC,MAAK6sB,oBAAoBjhB,EAAM1J,GAAOkZ,GAAIxP,EAAM1J,GAAOke,KAAKrhB,MAE5DiB,KAAK4xB,8CAA6C,EAAOhmB,EAAOwoB,EAAW72B,EAAQshB,IAGvFoT,2BAA4B,SAASrmB,EAAO1J,EAAO3E,EAAQshB,GACvD,GAAI9c,GAAO/B,KACPo0B,EAAYlyB,EAAQ,EACpB6vB,EAAuB/xB,KAAKguB,yBAAyBpiB,EAAM1J,GAE/DlC,MAAKq0B,wBAAwBzoB,EAAM1J,GAAQ6vB,GACtC9Z,KACD,WACIlW,EAAKuyB,QAAQ1oB,EAAM1J,GAAOkZ,GAAI7d,EAAQshB,GACtC9c,EAAK6vB,8CAA6C,EAAMhmB,EAAOwoB,EAAW72B,EAAQshB,IAEtF,WACI9c,EAAK6vB,8CAA6C,EAAOhmB,EAAOwoB,EAAW72B,EAAQshB,MAK/F0B,uBAAwB,SAAS3U,EAAOrO,EAAQshB,GAC5C,GAAqB,IAAjBjT,EAAMxJ,OAEN,WADApC,MAAKomB,WAAW,eAIpB,IAAI4N,GAAwBh0B,KAAKkuB,0BAA0BtiB,GACvDuN,EAAWnZ,KAAK8mB,aAAalb,EAAM,GAAGwU,MACtC8D,EAASlkB,KAAK0iB,WAAWvJ,EAE7BnZ,MAAKuoB,wBACDxpB,KAAM,kBACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU61B,gBAAiBv0B,KAAMg0B,EAAuB9P,GACxF1L,UAAWza,GAAGgT,KAAK/Q,KAAK+zB,gCAAiC/zB,KAAMg0B,EAAuBpoB,EAAOrO,EAAQshB,EAAUqF,GAC/GzL,UAAW1a,GAAGgT,KAAK/Q,KAAK8zB,gCAAiC9zB,KAAM4L,GAC/D8c,WAAY,sBAIpB8L,wBAAyB,WACrB,GAAIzyB,GAAO/B,IAEXA,MAAK4qB,gBAAgB1nB,OAAOiE,OAAQ,eAAgB,SAASiJ,GACzD,GAAIrO,EAAKghB,gBAKL,MAJA3S,GAAIA,GAAKjJ,OAAOstB,MAEhBrkB,EAAEC,YAActO,EAAKnD,SAAS8xB,SAASgE,QAEhC3yB,EAAKnD,SAAS8xB,SAASgE,WAQ1CnQ,oBAAqB,WACjB,GAAIxiB,GAAO/B,KACPjD,EAAUiD,KAAKpB,SAASylB,OAGxBtmB,IAAG42B,SAA6C,MAAlC30B,KAAKpB,SAASylB,QAAQxF,WAC/B7e,KAAK40B,WACN72B,GAAGwG,OAAOxH,GAAU4qB,KAAM3nB,KAAKpB,SAAS+oB,OAExC5qB,EAAQoD,IAAMpC,GAAGgT,KAAK/Q,KAAKG,IAAKH,MAChCjD,EAAQ83B,cAAgB92B,GAAGgT,KAAK/Q,KAAKkf,eAAgBlf,MAErDA,KAAK40B,SAAW,GAAI72B,IAAG42B,QAAQ53B,IAGnC6sB,WAAW,WACP7nB,EAAK6yB,SAASE,UAAU7c,KAAK,SAASwZ,EAAU1J,GAC5ChmB,EAAKgzB,0BACLhzB,EAAKnD,SAASF,UAAUs2B,yBAAyBvD,GAAU,EAAM1J,IAElE,SAAS0J,EAAU1J,GAElBhmB,EAAKnD,SAASF,UAAUs2B,yBAAyBvD,GAAU,EAAO1J,MAEvE,KAIXgN,wBAAyB,aAEzBtI,SAAU,SAASrR,EAAIoC,GACnBxd,KAAKghB,YAAYzD,WAAWnC,EAAIoC,GAChCxd,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAeuQ,UAAU7Z,IAGzDkX,iBAAkB,SAASlX,EAAIrc,EAAMstB,GACjC,GAAItL,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAGhD,WAAKpb,KAAKgkB,gBAAgB5I,IACnBpb,KAAKpB,SAAS+lB,MAAMuQ,YACpBnU,EAAWrF,SAAW3d,GAAG2d,OAAOwC,SAEL7f,SAA1B2B,KAAK8jB,aAAa1I,KAClBpb,KAAK8jB,aAAa1I,GAAM,GAGxBpb,KAAK8jB,aAAa1I,GAAMpb,KAAKpB,SAAS+lB,MAAMwQ,oBAC5Cn1B,KAAK8jB,aAAa1I,IAAO,GAClB,IAOnBiY,eAAgB,SAASjY,GACrBpb,KAAKof,WAAWvf,KAAKub,IAIzB8T,aAAc,SAAS9T,GACnB,GAAIjC,EAGAA,GADApb,GAAGiW,kBAAkBqC,cACVrW,KAAKygB,SAAS2B,QAAQhH,GAAIyL,WAG1B7mB,KAAK8mB,aAAa9mB,KAAKygB,SAASjG,SAASY,IAGpDjC,IACAnZ,KAAK2iB,qBAAqBvH,GAAMjC,IAIxC0M,4BAA6B,SAASuP,GAClCp1B,KAAKpB,SAASwT,KAAK3R,QAAU20B,EAE7Bp1B,KAAKuvB,aAAexxB,GAAGyxB,aAAe,GAAIzxB,IAAGyxB,YACrCxvB,KAAKpB,SAASwT,KAAMrU,GAAGgT,KAAK/Q,KAAKmmB,kBAAmBnmB,MAAOjC,GAAGgT,KAAK/Q,KAAKG,IAAKH,OAGjFA,KAAKuvB,cAAgBvvB,KAAKuvB,aAAaE,iBACvCzvB,KAAKmkB,aAAaqF,YAAY,KAAMxpB,KAAKuvB,aAAaG,uBAEtD1vB,KAAKpB,SAAS+wB,WAAa3vB,KAAKuvB,aAAaK,cACzC5vB,KAAKuvB,aAAaM,aAClB7vB,KAAK0lB,YAAY1lB,KAAKuvB,aAAaM,eAK/CyE,QAAS,SAASlZ,EAAI7d,EAAQshB,GAC1B,GAAI9f,GAAOiB,KAAKkhB,QAAQ9F,EAEpB7d,IACAyC,KAAKimB,UAAU1oB,EAAQ6d,GAGvByD,GACA7e,KAAK0lB,YAAY7G,EAAUzD,GAG/Bpb,KAAKuoB,wBACDxpB,KAAM,WACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU22B,SAAUr1B,KAAMob,EAAIrc,GAC9DyZ,UAAWza,GAAGgT,KAAK/Q,KAAKkzB,yBAA0BlzB,KAAMob,EAAIrc,GAC5D0Z,UAAW1a,GAAGgT,KAAK/Q,KAAK6sB,oBAAqB7sB,KAAMob,EAAIrc,GACvD2pB,WAAYtN,KAIpB+F,YAAa,SAAS/F,GACbpb,KAAKygB,SAASlV,OAAO6P,IACtBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOsC,SAIjDqI,mBAAoB,WAIhB,IAHA,GAAIiP,GAAYC,EACZxzB,EAAO/B,KAEJA,KAAKof,WAAWhd,QACnBkzB,EAAat1B,KAAKof,WAAW5L,QAC7BxT,KAAKmhB,YAAYmU,EAIrBC,GAAkBv1B,KAAKkjB,YAAYxH,OAAQ3d,GAAG2d,OAAOW,aAAaja,OAC9DmzB,IACAx3B,GAAGoC,IAAI,qBAAuBo1B,EAAkB,yEAChD3L,WAAW,WACP7nB,EAAKskB,sBACN,OAYXgO,wBAAyB,SAASpG,EAAa8D,GAC3C,GAAIhwB,GAAO/B,KACPogB,EAAQ,WACJ,MAAI6N,GAAY7N,eAAgBriB,IAAG4a,UACxBsV,EAAY7N,KAAKxH,cAErBqV,EAAY7N,QAEvBrhB,EAAOgzB,EAAqBhzB,KAC5Bwd,EAAOwV,EAAqBxV,KAC5BpD,EAAWnZ,KAAK8mB,aAAamH,EAAY7N,MACzCwQ,EAAiB5wB,KAAK+tB,mBAAmB5U,GACzCqc,EAAkB,GAAIz3B,IAAGoP,OAQ7B,OANAqoB,GAAgBvd,KACZ,aACA,WACIlW,EAAK8qB,oBAAoBoB,EAAY7S,GAAIrc,KAG7ChB,GAAGsM,cAAc+V,KAAUpgB,KAAKiqB,oBAAoB2G,EAAe1G,kBAAmBnrB,IACtFiB,KAAKomB,WAAW,YAAarnB,EAAMqhB,GAC5BoV,EAAgBjoB,WAGtBvN,KAAKpB,SAASwrB,WAAWqL,YAAuB,IAATlZ,EAKxCA,EAAO,GAAKqU,EAAeG,WAAaxU,EAAOqU,EAAeG,WAC9D/wB,KAAKomB,WAAW,YAAarnB,EAAMqhB,GAC5BoV,EAAgBjoB,WAGvBgP,EAAO,GAAKA,EAAOqU,EAAeI,cAClChxB,KAAKomB,WAAW,eAAgBrnB,EAAMqhB,GAC/BoV,EAAgBjoB,YAGvBxP,GAAG23B,iBAAmB33B,GAAGiW,kBAAkBiD,eAAiBlZ,GAAGgM,OAAOqW,GACtE,GAAIriB,IAAG23B,gBAAgBtV,EAAMriB,GAAGgT,KAAKhP,EAAK5B,IAAK4B,IAAO4zB,SAAS/E,EAAegF,OAAO3d,KACjFud,EAAgBnoB,QAChB,SAASwoB,GACL9zB,EAAKqkB,WAAWyP,EAAY,aAAc92B,EAAMqhB,GAChDoV,EAAgBjoB,YAKxBioB,EAAgBnoB,UAGbmoB,IA3BHx1B,KAAKomB,WAAW,aAAcrnB,EAAMqhB,GAC7BoV,EAAgBjoB,YA6B/BuoB,eAAgB,WACZ,GAAI/zB,GAAMg0B,EAAcl3B,CAExBkD,GAAO/B,KAEP+1B,EAAe,SAASh3B,EAAM4R,EAAU/N,GACpC,GAAIozB,EAEJ,KACI,MAAOrlB,GAAS5Q,MAAMgC,EAAMa,GAEhC,MAAOqzB,GACHD,EAAWC,EAAU71B,SAAW61B,EAAUztB,WAC1CzG,EAAK5B,IAAI,wBAA0BpB,EAAO,gBAAkBi3B,EAAU,UAK9E,KAAKn3B,IAAQmB,MAAKpB,SAASF,WACtB,WACG,GAAIw3B,GAAcC,CAClBD,GAAer3B,EACfs3B,EAAep0B,EAAKnD,SAASF,UAAUw3B,GACvCn0B,EAAKnD,SAASF,UAAUw3B,GAAgB,WACpC,MAAOH,GAAaG,EAAcC,EAAc12B,oBCh0DvE,WACG,YAEA1B,IAAGq4B,kBAAoB,SAASpd,GAC5B,GAAIjX,GAAO/B,IAGXA,MAAKpB,UACDglB,OAAO,EACPM,OAAQ,KACR9Y,UAAU,EACVgc,eAAgB,EAChBiP,6BAA6B,EAC7B1G,YAAY,EAEZrI,SACIE,iBACA3I,SAAU,iBACVyX,cAAe,aACfC,gBAAgB,EAChB9L,UAAW,SACXtD,OAAQ,OACR5pB,UACAi5B,cAAc,EACdC,kBAAmB,kBACnBlP,SAAU,UAGd6C,YACIF,qBACA6G,UAAW,EACXC,aAAc,EACd0B,UAAW,EACXZ,wBAAwB,EACxBvY,YAAa,KACbqc,OACIc,UAAW,EACXC,SAAU,EACVC,UAAW,EACXC,SAAU,GAEdpB,YAAY,GAGhB/2B,WACI22B,SAAU,SAASja,EAAIrc,KACvBq0B,YAAa,SAAShY,EAAIrc,KAC1BusB,WAAY,SAASlQ,EAAIrc,EAAMstB,EAAcyK,KAC7CzE,cAAe,SAASF,EAAYC,KACpC5G,SAAU,SAASpQ,EAAIrc,KACvB8sB,SAAU,SAASzQ,EAAIrc,KACvBgtB,cAAe,SAAS3Q,EAAIrc,EAAMitB,KAClCE,qBAAsB,SAAS9Q,EAAI4Q,EAAWK,EAAc5X,KAC5D0X,SAAU,SAAS/Q,EAAIjI,EAAU6Y,KACjCd,WAAY,SAAS9P,EAAIrc,EAAMosB,EAAQC,KACvCyI,gBAAiB,SAAS1I,EAAQC,KAClCpE,QAAS,SAAS5L,EAAIrc,EAAMyjB,EAAQuU,KACpC3K,YAAa,SAAShR,EAAIrc,EAAMi4B,KAChCrE,cAAe,SAASvX,EAAIrc,KAC5Bw1B,gBAAiB,SAAS0C,KAC1BjF,WAAY,SAASiF,KACrBxD,eAAgB,SAASrY,KACzBwM,SAAU,SAASxM,KACnB0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,KACzCQ,gBAAiB,SAAS3b,KAC1B6P,eAAgB,SAAStB,EAAI2B,EAAWD,KACxCkY,yBAA0B,SAASvD,EAAUpkB,EAAS0a,MAG1D2I,UACIwG,UAAW,qEACXC,UAAW,yDACXC,aAAc,4DACdC,WAAY,yDACZC,aAAc,sBACdnD,kBAAmB,6EACnBoD,oBAAqB,qBACrBC,mBAAoB,qBACpBC,oBAAqB,4BACrBC,mBAAoB,4BACpBC,sBAAuB,mDACvBjD,QAAS,8EACTnD,6BAA8B,6KAGlC5M,OACIuQ,YAAY,EACZC,gBAAiB,EACjB3C,iBAAkB,EAClBvH,6BAA8B,gBAGlCZ,SACIE,YAAa,yBACbD,YAAa,0BAGjB9T,UACIyK,SAAS,EACT2W,YACI3W,SAAS,GAEb4W,WAAW,EACXC,YACIC,UAAW,cACXC,eAAgB,mBAChBC,UAAW,cACXC,cAAe,kBACfC,WAAY,gBAEhBC,SAAU,IAEV/qB,SACIwR,SAAU,OAIlBvH,QACI2J,SAAS,EACToX,gBAAiB,EACjBP,YACIQ,SAAU,aAIlBxH,eAAgB,SAASyH,GACrB,MAAOA,IAGXzyB,MACI6rB,qBAAsB,gCACtBhH,eAAgB,aAChBoC,aAAc,KAAM,KAAM,KAAM,KAAM,KAAM,OAGhD3L,YACIH,SAAS,EACTkG,OAAQ,SACRtI,SAAU,iBACV2I,iBACAjqB,WAGJoqB,MACIoI,UAAU,EACVyI,iBAAiB,EACjBxI,UAAU,GAGdxQ,OACIC,YAAa,aAGjB4I,OACID,cAAe,KACf3I,YAAa,gBAGjB6O,QACI1e,KAAK,EAGLsU,OAAQ,MASZkJ,gBAIA/I,SACIxF,SAAU,KACVthB,UACAiqB,iBACAlD,gBAAgB,GAIpBlS,MAEI3R,QAAS,UAGTkvB,YAAY,EAGZ8I,iBAAiB,GAIrBlhB,SACImhB,cAAe,KAGfC,cAAc,EAGdC,QAAQ,EAIRC,YAAa,KAEbC,eAAgB,GAEhBC,YAAa,kBAEbC,aAAa,EAGbC,UAGJlP,aACIC,gBAAgB,EAChBqH,mBAAmB,EACnB7G,kBAAkB,IAK1BzsB,GAAGwG,OAAOvE,KAAKpB,SAAUoa,GAAG,GAE5BhZ,KAAKikB,YACLjkB,KAAKmtB,qBACLntB,KAAK2iB,wBAEL3iB,KAAK81B,iBACL91B,KAAK4qB,gBAAmB,GAAI7sB,IAAGqV,eAE/BpT,KAAKof,cACLpf,KAAK8jB,gBACL9jB,KAAK+jB,kBACL/jB,KAAKgkB,mBACLhkB,KAAKkiB,kBAELliB,KAAK0jB,qBAAuB,EAC5B1jB,KAAKsjB,aAAe,EACpBtjB,KAAKghB,YAAchhB,KAAKypB,2BAExBzpB,KAAKsvB,4BAELtvB,KAAKklB,oBAAsBllB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQE,eACnExnB,KAAKqlB,8BAAgCrlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAWoG,eAEhFxnB,KAAKylB,uBAAyBzlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAW7jB,QAEzEyC,KAAK6iB,eAAiB7iB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQzI,UAC9D7e,KAAKulB,yBAA2BvlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAWvC,UAE3E7e,KAAKygB,SAAWzgB,KAAK6qB,uBAErB7qB,KAAK0zB,eAAiB31B,GAAGmpB,yBAA2BlnB,KAAKinB,uBAErDjnB,KAAKpB,SAASslB,SACdlkB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAKpB,SAASslB,OACvB9K,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGPza,KAAKktB,4BAELltB,KAAKquB,sBAEDruB,KAAKpB,SAASypB,MAAMD,gBAChBrqB,GAAGoqB,aACHnoB,KAAKokB,cAAgBpkB,KAAKkoB,sBAG1BloB,KAAKG,IAAI,iCAAkC,UAInDH,KAAKw0B,0BAELx0B,KAAKiiB,gBAAkBlkB,GAAGm7B,gBAAkB,GAAIn7B,IAAGm7B,eAAen7B,GAAGgT,KAAK/Q,KAAKG,IAAKH,OACpFA,KAAKukB,sBAELvkB,KAAKwkB,kCACLxkB,KAAKykB,+BAELzkB,KAAKm5B,QAAWp7B,GAAGgnB,QAAU,GAAIhnB,IAAGgnB,OAAO/kB,KAAKpB,SAAS2Y,QAASxZ,GAAGgT,KAAK/Q,KAAKG,IAAKH,WAChFA,KAAKm5B,QAAQlY,UACbjhB,KAAK+uB,sBAAwBhxB,GAAGgT,KAAK/Q,KAAKm5B,QAAQC,cAAep5B,KAAKm5B,UAGtEp7B,GAAGs7B,eAAiBt7B,GAAGiW,kBAAkBqD,cACzCrX,KAAK0kB,eAAiB,GAAI3mB,IAAGs7B,cACzBt7B,GAAGgT,KAAK/Q,KAAK4zB,iBAAkB5zB,MAE/B,SAASob,GACL,GAAIke,GAAQv3B,EAAKif,YAAYrE,UAAUvB,GAAIA,GAC3C,OAAQke,IAASA,EAAM/c,MAAS,KAK5Cvc,KAAKyjB,kBAAoBzjB,KAAKpB,SAASwrB,WAAWsI,WAItD30B,GAAGq4B,kBAAkB72B,UAAYxB,GAAG2gB,cACpC3gB,GAAGwG,OAAOxG,GAAGq4B,kBAAkB72B,UAAWxB,GAAGuoB,mBCnTjDvoB,GAAGw7B,cAAgB,SAASvgB,GACxB,YA2CA,SAASwgB,KACL,MAAOz7B,IAAG6J,SAAS,MAAO,OAAQ,QAAS7K,EAAQoqB,SAAW,EAMlE,QAASsS,GAAyBxU,GAC9B,GAAIyU,IAAoB,CASxB,OAPA37B,IAAGY,KAAK+6B,EAAmB,SAAS/5B,EAAKg6B,GACrC,GAAI57B,GAAG6J,SAAS,SAAU,kBAAmB,mBAAoB,gBAAiB+xB,GAAU,EAExF,MADAD,IAAoB,GACb,IAIRA,EAGX,QAASE,GAAMnlB,GAEX,MAAO1X,GAAQ4qB,KAAKoI,UAAoC1xB,SAAxBoW,EAAIC,gBAIxC,QAASmlB,KACL,GAAI9R,EAeJ,QAbI5gB,OAAOqE,gBAAkBrE,OAAOsE,iBAChCsc,EAAWhqB,GAAGuN,oBAEmBjN,SAA7B0pB,EAASrT,kBACTqT,EAAW,GAAInT,gBAEfmT,EAAS3a,OAAS,aAClB2a,EAASza,QAAU,aACnBya,EAAS+R,UAAY,aACrB/R,EAASgS,WAAa,eAIvBhS,EAIX,QAASiS,GAAY5e,EAAI6e,GACrB,GAAIlS,GAAWmS,EAAY9e,GAAI3G,GAkB/B,OAhBKsT,KAEGA,EADAkS,EACWA,EAGPl9B,EAAQ4qB,KAAKoI,SACF8J,IAGA97B,GAAGuN,oBAItB4uB,EAAY9e,GAAI3G,IAAMsT,GAGnBA,EAIX,QAASoS,GAAQ/e,GACb,GAEIgf,GAFAxoB,EAAI7T,GAAG6J,QAAQyyB,EAAOjf,GACtB4R,EAAMjwB,EAAQqqB,qBAGX8S,GAAY9e,GACnBif,EAAMpd,OAAOrL,EAAG,GAEZyoB,EAAMj4B,QAAU4qB,GAAOpb,EAAIob,IAC3BoN,EAASC,EAAMrN,EAAM,GACrBsN,EAAYF,IAIpB,QAAS9O,GAAWlQ,EAAImf,GACpB,GAAI9lB,GAAMulB,EAAY5e,GAClB+L,EAASpqB,EAAQoqB,OACjBa,EAAUuS,KAAa,CAE3BJ,GAAQ/e,GAEJ4M,EACA7nB,EAAIgnB,EAAS,gBAAkB/L,EAAK,cAAe,SAE7Cwe,EAAMnlB,IAAS+lB,EAAqB/lB,EAAIiH,UAC9CsM,GAAU,EACV7nB,EAAIgnB,EAAS,gBAAkB/L,EAAK,+BAAiC3G,EAAIiH,OAAQ,UAGrF3e,EAAQuuB,WAAWlQ,EAAI3G,EAAKuT,GAGhC,QAASyS,GAAUrf,GACf,GAEI7d,GAFAm9B,EAAiBR,EAAY9e,GAAIuf,iBACjCC,EAAiB79B,EAAQ69B,cAqB7B,OAlBI79B,GAAQ0qB,YAAY3E,MACpBvlB,EAASR,EAAQ0qB,YAAY3E,IAAI1H,IAGjCsf,GACA38B,GAAGY,KAAK+7B,EAAgB,SAAS37B,EAAMZ,GACnCZ,EAASA,MACTA,EAAOwB,GAAQZ,IAInBy8B,GACA78B,GAAGY,KAAKi8B,EAAgB,SAAS77B,EAAMZ,GACnCZ,EAASA,MACTA,EAAOwB,GAAQZ,IAIhBZ,EAGX,QAAS+8B,GAAYlf,EAAIyf,GACrB,GAIIC,GAJArmB,EAAMulB,EAAY5e,EAAIyf,GACtB1T,EAASpqB,EAAQoqB,OACjB5pB,EAASk9B,EAAUrf,GACnB2f,EAAUb,EAAY9e,GAAI2f,OA+C9B,OA5CAh+B,GAAQi+B,OAAO5f,GAEf0f,EAAMG,EAAU7f,EAAI7d,EAAQ28B,EAAY9e,GAAI8f,uBAGxCtB,EAAMnlB,IACNA,EAAIrH,OAAS+tB,EAAkB/f,GAC/B3G,EAAInH,QAAU8tB,EAAmBhgB,IAGjC3G,EAAI4mB,mBAAqBC,EAA8BlgB,GAG3DmgB,EAA0BngB,GAG1B3G,EAAI+mB,KAAKrU,EAAQ2T,GAAK,GAIlB/9B,EAAQ4qB,KAAKoI,UAAYhzB,EAAQ4qB,KAAK6Q,kBAAoBoB,EAAMnlB,KAChEA,EAAIC,iBAAkB,GAG1B+mB,EAAWrgB,GAEXjb,EAAI,WAAagnB,EAAS,gBAAkB/L,GAExC2f,EACAtmB,EAAIinB,KAAKX,GAEJY,IAAgCp+B,EACrCkX,EAAIinB,OAECn+B,GAAUR,EAAQ6+B,aAAe7+B,EAAQ6+B,YAAY99B,cAAc8J,QAAQ,sCAAwC,EACxH6M,EAAIinB,KAAK39B,GAAGqT,QAAQ7T,EAAQ,KAEvBA,GAAUR,EAAQ6+B,aAAe7+B,EAAQ6+B,YAAY99B,cAAc8J,QAAQ,qBAAuB,EACvG6M,EAAIinB,KAAKjpB,KAAKopB,UAAUt+B,IAGxBkX,EAAIinB,KAAKn+B,GAGNkX,EAGX,QAASwmB,GAAU7f,EAAI7d,EAAQ29B,GAC3B,GAAIrc,GAAW9hB,EAAQ2qB,cAAc5E,IAAI1H,GACrC0gB,EAAY5B,EAAY9e,GAAI0gB,SAehC,OAZiBz9B,SAAby9B,IACAjd,GAAY,IAAMid,GAGlBH,GAA+Bp+B,IAC/BshB,EAAW9gB,GAAGqT,QAAQ7T,EAAQshB,IAG9Bqc,IACArc,EAAW9gB,GAAGqT,QAAQ8pB,EAAuBrc,IAG1CA,EAKX,QAASyc,GAA8BlgB,GACnC,MAAO,YACgC,IAA/B4e,EAAY5e,GAAI2gB,YAChBzQ,EAAWlQ,IAKvB,QAASmgB,GAA0BngB,GAC/B,GAAI8P,GAAanuB,EAAQmuB,UAErBA,KACA8O,EAAY5e,GAAI7P,OAAOwuB,WAAa,SAAS3pB,GACrCA,EAAE4rB,kBACF9Q,EAAW9P,EAAIhL,EAAE+a,OAAQ/a,EAAEgb,SAQ3C,QAAS+P,GAAkB/f,GACvB,MAAO,YACHkQ,EAAWlQ,IAMnB,QAASggB,GAAmBhgB,GACxB,MAAO,YACHkQ,EAAWlQ,GAAI,IAIvB,QAASqgB,GAAWrgB,GAChB,GAAI3G,GAAMulB,EAAY5e,GAClBoM,EAAgBzqB,EAAQyqB,cACxByU,EAAkB/B,EAAY9e,GAAI8gB,sBAClC/U,EAASpqB,EAAQoqB,OACjBgV,IAGCvC,GAAMnlB,KACP1X,EAAQq/B,cAAgB3nB,EAAI4nB,iBAAiB,SAAUt/B,EAAQq/B,cAG3Dr/B,EAAQu/B,qCAKHv/B,EAAQ4qB,KAAKoI,UAAcyJ,MAAoBC,EAAyBjS,KACzE/S,EAAI4nB,iBAAiB,mBAAoB,kBACzC5nB,EAAI4nB,iBAAiB,gBAAiB,eAI1Ct/B,EAAQ6+B,aAA2B,SAAXzU,GAAgC,QAAXA,GAC7C1S,EAAI4nB,iBAAiB,eAAgBt/B,EAAQ6+B,aAGjD79B,GAAGwG,OAAO43B,EAAYp+B,GAAG0K,WAAW+e,GAAiBA,EAAcpM,GAAMoM,GACzEzpB,GAAGwG,OAAO43B,EAAYF,GAEtBl+B,GAAGY,KAAKw9B,EAAY,SAASp9B,EAAMZ,GAC/BsW,EAAI4nB,iBAAiBt9B,EAAMZ,MAKvC,QAASq8B,GAAqB+B,GAC1B,MAAOx+B,IAAG6J,QAAQ7K,EAAQy/B,wBAAwBz/B,EAAQoqB,QAASoV,IAAiB,EAGxF,QAASE,GAAcrhB,EAAIyf,EAAQiB,EAAWnB,EAAkBO,EAAuBgB,EAAmBnB,GACtGb,EAAY9e,IACR0gB,UAAWA,EACXnB,iBAAkBA,EAClBO,sBAAuBA,EACvBgB,kBAAmBA,EACnBnB,QAASA,EAGb,IAAI3sB,GAAMisB,EAAMx6B,KAAKub,EAGrB,IAAIhN,GAAOrR,EAAQqqB,eACf,MAAOkT,GAAYlf,EAAIyf,GA7U/B,GAAI16B,GAAKw7B,EACLtB,KACAH,KACAn9B,GACIq/B,aAAc,KACdM,cAAe,QAAS,OAAQ,OAChCvV,OAAQ,OACRyU,YAAa,oCACbxU,eAAgB,EAChBI,iBACAE,iBACAD,eACAmT,kBACA0B,oCAAoC,EACpCE,yBACIG,QAAS,IAAK,IAAK,KACnBC,OAAQ,IAAK,IAAK,IAAK,IAAK,KAC5BC,MAAO,IAAK,IAAK,IAAK,IAAK,KAC3BC,KAAM,IAAK,IAAK,IAAK,IAAK,KAC1BC,KAAM,MAEVpV,MACIoI,UAAU,EACVyI,iBAAiB,GAErBr4B,IAAK,SAASuJ,EAAKvB,KACnB6yB,OAAQ,SAAS5f,KACjBkQ,WAAY,SAASlQ,EAAI2M,EAAUC,KACnCkD,WAAY,KAMpB,IAHAntB,GAAGwG,OAAOxH,EAASic,GACnB7Y,EAAMpD,EAAQoD,IAEVpC,GAAG6J,QAAQ7K,EAAQ2/B,aAAc3/B,EAAQoqB,QAAU,EACnD,KAAM,IAAIjjB,OAAM,IAAMnH,EAAQoqB,OAAS,wDA8S3CwU,GAAiD,QAAnB5+B,EAAQoqB,QAAuC,WAAnBpqB,EAAQoqB,OAElEppB,GAAGwG,OAAOvE,MAENg9B,cAAe,SAAS5hB,GACpB,GAAI6hB,GAAM1/B,EAAQ0nB,EAAS8V,EAASmC,EAAahC,CAEjD,QAEIiC,SAAU,SAASC,GAEf,MADAH,GAAOG,EACAp9B,MAOXq9B,WAAY,SAAS1C,GAEjB,MADAp9B,GAASo9B,EACF36B,MAGXs9B,gBAAiB,SAASC,GAEtB,MADArC,GAAwBqC,EACjBv9B,MAIXw9B,YAAa,SAAStB,GAElB,MADAjX,GAAUiX,EACHl8B,MAIXy9B,YAAa,SAASC,GAElB,MADA3C,GAAU2C,EACH19B,MAIX29B,gBAAiB,WAEb,MADAT,IAAc,EACPl9B,MAIX07B,KAAM,SAASb,GAKX,MAJIqC,IAAen/B,GAAG6J,SAAS,MAAO,UAAW7K,EAAQoqB,SAAW,IAChE5pB,EAAOqgC,aAAc,GAAIC,OAAOC,WAG7BrB,EAAcrhB,EAAIyf,EAAQoC,EAAM1/B,EAAQ29B,EAAuBjW,EAAS8V,MAK3FgD,SAAU,SAAS3iB,GACf+e,EAAQ/e,OC1YpBrd,GAAGigC,cAAgB,SAAS5hB,GACxB,YAEA,IAAI6hB,GAAQ7hB,EAAK6hB,MACbC,KACA1S,EAAWyS,EAAMzS,SACjBtK,EAAU+c,EAAM/c,OAEpBnjB,IAAGwG,OAAOvE,MACN0R,IAAK,SAAS0J,EAAI+iB,GACdD,EAAU9iB,GAAM+iB,EAChBD,EAAU9iB,GAAI9J,SAGlBkP,OAAQ,SAASpF,GACb,GAAIrZ,GAAO/B,KACPyrB,EAA2B,GAAI1tB,IAAGoP,QAClCixB,EAAiB5S,EAASpQ,EAAI8F,EAAQ9F,GAAKqQ,EAE/C2S,GAAenmB,KAAK,WACZlW,EAAKyf,QAAQpG,KACb8iB,EAAU9iB,GAAI2iB,UAAW,EACzBh8B,EAAK+wB,QAAQ1X,IAEjBqQ,EAAyBpe,aAIjCylB,QAAS,SAAS1X,SACP8iB,GAAU9iB,IAGrBijB,oBAAqB,SAASjjB,GAC1B,MAAO8iB,GAAU9iB,GAAIld,KAGzBsjB,QAAS,SAASpG,GACd,MAAyB/c,UAAlB6/B,EAAU9iB,IAGrBN,MAAO,WACHojB,MAGJI,cAAe,SAASljB,GACpB,MAAO8iB,GAAU9iB,IAGrBmjB,qBAAsB,SAASnjB,EAAIojB,GAC/BN,EAAU9iB,GAAIld,IAAMsgC,GAGxBC,aAAc,SAASrjB,GACnB,QAAS8iB,EAAU9iB,GAAI2iB,aCpDnChgC,GAAG6uB,wBAA0B,SAAS5T,EAAGtb,GACrC,YAEA,IAGcghC,GAAsBv+B,EAAK2uB,EAHrC6P,EAAa3+B,KACb4+B,GAAmB,EACnBC,GAA6B,EAGjC9hC,GACI0qB,eACAL,eAAgB,EAChB5Q,UACIyK,SAAS,EACT7V,UACI6V,SAAS,IAGjB9gB,IAAK,SAASuJ,EAAKvB,KACnB+iB,WAAY,SAAS9P,EAAIjI,EAAUgY,EAAQC,KAC3CE,WAAY,SAASlQ,EAAIjI,EAAUse,EAAUhd,KAC7C+W,SAAU,SAASpQ,EAAIjI,KACvBwY,aAAc,SAASvQ,KACvByQ,SAAU,SAASzQ,EAAIjI,KACvB4Y,cAAe,SAAS3Q,EAAIjI,EAAU6Y,KACtCE,qBAAsB,SAAS9Q,EAAI4Q,EAAWyF,EAAUhd,KACxD2X,YAAa,SAAShR,EAAIjI,EAAUse,EAAUhd,KAC9C0X,SAAU,SAAS/Q,EAAIjI,EAAU6Y,KACjCO,cAAe,SAASnR,EAAI+B,KAC5B+D,QAAS,SAAS9F,KAClBoR,QAAS,SAASpR,EAAIoC,KACtBmP,SAAU,SAASvR,KACnBwC,mBAAoB,SAASxC,KAC7ByC,cAAe,SAASzC,MAG5B0jB,GAEIpmB,KAAM,SAAS0C,EAAI2jB,EAAUtN,EAAUhd,GACnC,GAAIuX,GAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,EAE1CjQ,GAAQwP,cAAcljB,GAAI6jB,kBAAmB,QAEtCnQ,GAAQwP,cAAcljB,GAAI9J,KAAK4tB,cAAcH,GACpDjQ,EAAQwP,cAAcljB,GAAI+P,QAAUa,EAAUzP,KAE9Cxf,EAAQmvB,qBAAqB9Q,EAAI0T,EAAQqQ,yBAAyBnT,GAAYyF,EAAUhd,IAK5F2qB,SAAU,SAAShkB,GACf,GAAImB,GAAOxf,EAAQqmB,QAAQhI,GACvBrc,EAAOhC,EAAQmkB,QAAQ9F,EAE3Bjb,GAAI,qCAAuCib,EAAK,qBAChD0T,EAAQuQ,eAAejkB,GAAInD,KACvB,SAASwZ,EAAUhd,GACftU,EAAI,2BAA6Bib,EAEjC,IAAIkkB,GAAoB/zB,EAAOg0B,kBAAkB9N,GAAU,EAE3D10B,GAAQmuB,WAAW9P,EAAIrc,EAAMwd,EAAMA,GACnCuS,EAAQ0Q,+BAA+BpkB,GACvC7P,EAAOk0B,QAAQrkB,EAAIkkB,EAAmB7qB,IAE1C,SAASgd,EAAUhd,GACf,GAAI6qB,GAAoB/zB,EAAOg0B,kBAAkB9N,GAAU,EAE3DtxB,GAAI,yCAA2Cib,EAAK,MAAQkkB,EAAkBp/B,MAAO,SAEjFo/B,EAAkBxkB,OAClBgkB,EAAQhkB,MAAMM,GAGbre,EAAQqvB,YAAYhR,EAAIrc,EAAMugC,EAAmB7qB,IAClDlJ,EAAOk0B,QAAQrkB,EAAIkkB,EAAmB7qB,MAMtDirB,cAAe,SAASX,EAAU3jB,EAAIqW,EAAUhd,GAC5C,GAAI1V,GAAOhC,EAAQmkB,QAAQ9F,EAE3Bjb,GAAI,qCAAuCib,EAAK,WAAa2jB,GAE7DjQ,EAAQ6Q,iBAAiBvkB,EAAI2jB,EAE7B,IACIa,GADAC,EAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,EAGtDoO,GAAiB/kB,MACjBgkB,EAAQhkB,MAAMM,IAGdwkB,EAAgB7hC,GAAG6J,QAAQknB,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAYf,GACtEa,GAAiB,IACjB9Q,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAW7iB,OAAO2iB,EAAe,GACpE9Q,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAUC,QAAQjB,KAMxDjQ,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,gBAG5BpB,IACA/P,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,eAAgB,EAE/C9/B,EAAIpC,GAAG0L,OAAO,mFAAoFgJ,KAAKopB,UAAUtzB,OAAO23B,KAAKpR,EAAQqR,SAAS/kB,KAAO3I,KAAKopB,UAAU/M,EAAQwP,cAAcljB,GAAI5E,SAASspB,cACvM/hC,GAAGY,KAAKmwB,EAAQqR,SAAS/kB,GAAK,SAASglB,EAAMC,GACzClgC,EAAIpC,GAAG0L,OAAO,sDAAuD2R,EAAIglB,EAAMC,EAAMtE,aACrFsE,EAAMC,QAGND,EAAME,YAAa,IAIvBzR,EAAQ0R,0BAA0BplB,GAIlCqlB,EAAkBC,KAAKtlB,GAAI,IAG1Bre,EAAQqvB,YAAYhR,EAAIrc,EAAM8gC,EAAkBprB,IAIjDlJ,EAAOk0B,QAAQrkB,EAAIykB,EAAkBprB,KAKjDksB,aAAc,SAASvlB,GACnB,QAAS0T,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAU39B,QAG1Dw+B,SAAU,SAASxlB,GACf,GAAIylB,GAAU/R,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAUvsB,OAM3D,OAJIqtB,IAAW/R,EAAQgS,gBAAgB1lB,KACnCylB,EAAU,MAGPA,GAGX/lB,MAAO,SAASM,GACZjb,EAAI,8FAAgGib,EAAI,SAExG0T,EAAQ0Q,+BAA+BpkB,GACvC0T,EAAQiS,mBAAmB3lB,GAC3B0T,EAAQwP,cAAcljB,GAAI+P,OAAS,GAGvC6V,SAAU,SAAS5lB,GACf,GAAImB,GAAOxf,EAAQqmB,QAAQhI,GACvBrc,EAAOhC,EAAQmkB,QAAQ9F,GACvB2jB,EAAWD,EAAQ8B,SAASxlB,GAC5B4Q,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCzG,EAAWxJ,EAAQwP,cAAcljB,GAAI6jB,iBACrCgC,EAAmBnS,EAAQwP,cAAcljB,GAAI5E,SAASspB,cAElB,OAApChR,EAAQwP,cAAcljB,GAAI+P,SAC1B2D,EAAQwP,cAAcljB,GAAI+P,OAAS,GAInCmN,GAAYv7B,EAAQovB,SAAS/Q,EAAIrc,EAAMitB,MAAe,IACtD8S,EAAQhkB,MAAMM,GACd2jB,EAAWD,EAAQ8B,SAASxlB,GAC5B4Q,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCzG,GAAW,GAIC,MAAZyG,GAAgD,IAA5BkC,EAAiB7+B,OACrC08B,EAAQM,SAAShkB,IAKjBjb,EAAIpC,GAAG0L,OAAO,oEAAqE2R,EAAI2jB,EAAU/S,EAAU5f,MAAQ,EAAG4f,EAAU3f,IAAKkQ,IACrIxf,EAAQgvB,cAAc3Q,EAAIrc,EAAM+vB,EAAQqQ,yBAAyBnT,IACjEiV,EAAiBphC,KAAKk/B,GACtBjQ,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAamB,EAE5CpC,GACA4B,EAAkBjF,KAAKpgB,EAAI2jB,GAG3BF,GAA8B4B,EAAkBS,aAAepS,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAU39B,QAC5G08B,EAAQkC,SAAS5lB,GAGO,IAAxB4Q,EAAUnf,KAAK0P,MACfpc,EAAIpC,GAAG0L,OAAO,+DAAgEs1B,EAAU3jB,GAAK,SAC7F0jB,EAAQY,cAAcX,EAAU3jB,EAAI,8BAA+B,OAGnE0T,EAAQqS,YAAY/lB,EAAI2jB,EAAUzG,GAAUrgB,KAExC,SAAiBwZ,EAAUhd,GACvBtU,EAAI,wCAA0Cib,EAAK,WAAa2jB,GAEhEjQ,EAAQ6Q,iBAAiBvkB,EAAI2jB,EAE7B,IAAIkC,GAAmBnS,EAAQwP,cAAcljB,GAAI5E,SAASspB,eACtDD,EAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,GACtD2P,EAAqBrjC,GAAG6J,QAAQq5B,EAAkBlC,EAEtD5+B,GAAIpC,GAAG0L,OAAO,8CAA+Cs1B,EAAU3jB,IAEvE0jB,EAAQpmB,KAAK0C,EAAI2jB,EAAUc,EAAkBprB,GAEzC2sB,GAAsB,GACtBH,EAAiBhkB,OAAOmkB,EAAoB,GAGhDtS,EAAQuS,0BAA0BjmB,GAE7B0jB,EAAQ6B,aAAavlB,IAAmC,IAA5B6lB,EAAiB7+B,OAGzC08B,EAAQ6B,aAAavlB,GAC1B0jB,EAAQkC,SAAS5lB,GAGjBjb,EAAIpC,GAAG0L,OAAO,oGAAqG2R,EAAI3I,KAAKopB,UAAUoF,KANtInC,EAAQM,SAAShkB,IAWzB,SAAiBqW,EAAUhd,GACvBqqB,EAAQY,cAAcX,EAAU3jB,EAAIqW,EAAUhd,KAGjDiE,KAAK,WACFoW,EAAQwS,SAASlmB,EAAI2jB,QAO7C0B,GACIc,SACAC,eACAC,YAEAP,UAAW,WACP,GAAIlU,GAAMjwB,EAAQqqB,eACdsa,EAAwB,EACxBC,EAAkB,CAOtB,OALA5jC,IAAGY,KAAK8hC,EAAkBe,YAAa,SAAS9f,EAAQkgB,GACpDF,IACAC,GAAmBC,EAAiBx/B,SAGjC4qB,GAAOyT,EAAkBc,MAAMn/B,OAASs/B,EAAwBC,IAM3EjB,KAAM,SAAStlB,EAAIymB,GACf,GAGIzH,GAHA0H,GAAaD,EACbE,EAAehkC,GAAG6J,QAAQ64B,EAAkBgB,SAAUrmB,GACtD4mB,EAAmBjkC,GAAG6J,QAAQ64B,EAAkBc,MAAOnmB,SAGpDqlB,GAAkBe,YAAYpmB,GAEjC7P,EAAO02B,eAAe7mB,YAAerd,IAAG4a,YACxCxY,EAAI,uCAAyCib,EAAK,qCAC3C0T,GAAQwP,cAAcljB,GAAIgF,MAIjC2hB,GAAgB,EAChBtB,EAAkBgB,SAASxkB,OAAO8kB,EAAc,GAG3CD,GAAaE,GAAoB,IACtCvB,EAAkBc,MAAMtkB,OAAO+kB,EAAkB,GAEjD5H,EAASqG,EAAkBgB,SAASjuB,QAChC4mB,GAAU,IACVqG,EAAkBc,MAAM1hC,KAAKu6B,GAC7B7uB,EAAOa,MAAMguB,MAKzB8H,sBAAuB,WACnB,GAAIC,KAqBJ,OAjBApkC,IAAGY,KAAK8hC,EAAkBe,YAAa,SAAS9f,EAAQ0gB,GAChDA,GAAUA,EAAOhgC,QACjB+/B,EAAmBtiC,KAAKwiC,SAAS3gB,MAMzC3jB,GAAGY,KAAK8hC,EAAkBc,MAAO,SAAS5hC,EAAK+hB,GACtC+e,EAAkBe,YAAY9f,IAC/BygB,EAAmBtiC,KAAKwiC,SAAS3gB,MAKzCygB,EAAqBA,EAAmBhxB,OAAOsvB,EAAkBgB,WAKrEa,kBAAmB,SAASlnB,GACxB,MAAOrd,IAAG6J,QAAQ64B,EAAkBc,MAAOnmB,IAAO;EAGtDogB,KAAM,SAASpgB,EAAI2jB,GAKf,MAJgB,OAAZA,GACA0B,EAAkBgB,SAAS5hC,KAAKub,KAGhCqlB,EAAkBS,cACF,MAAZnC,GACA0B,EAAkBgB,SAASc,MAC3B9B,EAAkBc,MAAM1hC,KAAKub,KAG5B,WACG,GAAIonB,GAAkB/B,EAAkBe,YAAYpmB,MACpDonB,GAAgB3iC,KAAKk/B,GACrB0B,EAAkBe,YAAYpmB,GAAMonB,MAIrC,IAMf1nB,MAAO,WACH2lB,EAAkBgB,YAClBhB,EAAkBc,WAI1BkB,GACI/G,KAAM,SAAStgB,EAAIrc,GACf+vB,EAAQwP,cAAcljB,GAAI+P,OAAS,EAEnChrB,EAAI,qCAAuCib,GAC3C0T,EAAQ4T,WAAWtnB,GAAInD,KACnB,SAASwZ,EAAUoJ,GACf16B,EAAI,uCAAyCib,EAE7C,IAAIykB,GAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,GACtDlV,EAAOxf,EAAQqmB,QAAQhI,EAE3Bre,GAAQmuB,WAAW9P,EAAIrc,EAAMwd,EAAMA,GACnChR,EAAOo3B,aAAavnB,EAAIykB,GACxBt0B,EAAOk0B,QAAQrkB,EAAIykB,EAAkBhF,IAGzC,SAASpJ,EAAUoJ,GACf16B,EAAI,oCAAsCib,EAE1C,IAAIykB,GAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,EAErD10B,GAAQqvB,YAAYhR,EAAIrc,EAAM8gC,EAAkBhF,IACjDtvB,EAAOk0B,QAAQrkB,EAAIykB,EAAkBhF,OAOzDtvB,GACIiV,OAAQ,SAASpF,GACbjb,EAAI,cAAgBib,GACpBre,EAAQ0qB,YAAY3jB,OAAOsX,GAC3BqlB,EAAkBC,KAAKtlB,IAG3BqkB,QAAS,SAASrkB,EAAIqW,EAAUoJ,GAC5B,GAAI97B,GAAOhC,EAAQmkB,QAAQ9F,EAE3Bre,GAAQuuB,WAAWlQ,EAAIrc,EAAM0yB,EAAUoJ,GAEnC/L,EAAQwP,cAAcljB,IACtB0T,EAAQ8T,YAAc9T,EAAQ8T,WAAWxnB,GAG7CqlB,EAAkBC,KAAKtlB,IAK3B6mB,eAAgB,SAAS7mB,GACrB,MAAQ0T,GAAQ+T,UAAY/T,EAAQ+T,SAASznB,IACxC0T,EAAQ1M,SAAW0M,EAAQ1M,QAAQhH,IAG5C0nB,YAAa,WACT,GAAIC,GAAcrlC,EAAYK,GAAGL,GAAaK,GAAGilC,YAC7CC,EAAuBllC,GAAGiW,kBAAkBqC,cAAgB,MAAQ,MAExEyY,GAAU,GAAIiU,GAAYE,EAAuB,iBAC7ClmC,GAEI2vB,cAAe3vB,EAAQ2vB,cACvBxL,QAASnkB,EAAQmkB,QACjBkC,QAASrmB,EAAQqmB,QACjBO,QAAS5mB,EAAQ4mB,QACjBxjB,IAAKA,EACLqrB,SAAUzuB,EAAQyuB,SAClBN,WAAYnuB,EAAQmuB,WACpBqB,cAAexvB,EAAQwvB,gBAI3BuC,EAAQoU,+BACRpU,EAAQoU,iCAIhBC,4BAA6B,SAAS/nB,GAClC,MAAOre,GAAQ4vB,SAASvR,IAM5BgoB,WAAY,SAAShoB,EAAIvO,GAIrB,MAAIA,KAASiiB,EAAQ1M,QAAQhH,IAAOvO,YAAgB9O,IAAG4a,WAKnD5b,EAAQ4uB,aAAavQ,GAErBjb,EAAI,+CAAiDib,GACrDvO,EAAKiM,SAASb,KAAK,SAASorB,GACxBljC,EAAI,mCAAqCib,GAGzC0T,EAAQwU,WAAWloB,EAAIioB,GAGvBtmC,EAAQyvB,QAAQpR,EAAIioB,EAAc9mB,MAGlCuS,EAAQiS,mBAAmB3lB,GAE3B7P,EAAOg4B,uBAAuBnoB,IAIlC,SAAS6Y,GACL,GAAIuP,KAEAvP,KACAuP,EAActjC,MAAQ+zB,GAG1B9zB,EAAIpC,GAAG0L,OAAO,yDAA0D2R,EAAI6Y,GAAe,SAE3Fl3B,EAAQuuB,WAAWlQ,EAAIre,EAAQmkB,QAAQ9F,GAAKrd,GAAGwG,OAAOi/B,EAAe9E,GAAuB,MAC5FnzB,EAAOg4B,uBAAuBnoB,GAC9BqlB,EAAkBC,KAAKtlB,MAOxB,GAHI7P,EAAOg4B,uBAAuBnoB,IAO7CmoB,uBAAwB,SAASnoB,GAC7B,GAAIqoB,GAAa1mC,EAAQ6gB,mBAAmBxC,GACxCsoB,GAAiB,CAoBrB,OAlBID,IAAcA,EAAWrhC,QACzBjC,EAAI,0CAA4Cib,GAEhDrd,GAAGY,KAAK8kC,EAAY,SAAS9jC,EAAKgkC,GAC9B,GAAIp4B,EAAO43B,4BAA4BQ,IAAgB7U,EAAQ1M,QAAQuhB,GACnED,EAAiBC,IAAcvoB,EAC/B7P,EAAOq4B,IAAID,OAEV,IAAIp4B,EAAO43B,4BAA4BQ,GACxC,OAAO,MAKfD,GAAiB,EACjBn4B,EAAOq4B,IAAIxoB,IAGRsoB,GAGXf,aAAc,SAASvnB,EAAIqW,GACEpzB,SAArBozB,EAAStU,SACTpgB,EAAQwvB,cAAcnR,EAAIqW,EAAStU,UAO3CoiB,kBAAmB,SAASsE,EAAkB1R,GAC1C,GAAIV,GAAWoS,CAcf,OAVK9lC,IAAGsK,SAASw7B,KACbpS,KAEI1zB,GAAGoL,SAAS06B,KAAsB1R,IAClCV,EAASvxB,MAAQ2jC,IAIzBpS,EAASpkB,QAAU8kB,EAEZV,GAGXmS,IAAK,SAASxoB,GACV,GAAIrc,GAAOhC,EAAQmkB,QAAQ9F,EAE3B,KAAKujB,EAAWnd,QAAQpG,GACpB,KAAM,IAAIrd,IAAGmG,MAAMkX,EAAK,qCAG5Bre,GAAQ8uB,SAASzQ,EAAIrc,GAEjB6/B,GAAoB9P,EAAQgV,qBAAqB1oB,GACjD0jB,EAAQkC,SAAS5lB,GAGjBqnB,EAAO/G,KAAKtgB,EAAIrc,IAIxBqN,MAAO,SAASgP,GACZ,GAAI2oB,GAAex4B,EAAO02B,eAAe7mB,EAEzC,OAAI2oB,GACOx4B,EAAO63B,WAAWhoB,EAAI2oB,IAG7Bx4B,EAAOq4B,IAAIxoB,IACJ,IAKnBrd,IAAGwG,OAAOvE,MAIN0R,IAAK,SAAS0J,EAAIgF,GACd0O,EAAQpd,IAAI3R,MAAMC,KAAMP,YAM5B8L,OAAQ,SAAS6P,GACb,QAAIqlB,EAAkBjF,KAAKpgB,IAChB7P,EAAOa,MAAMgP,IAK5BuJ,MAAO,SAASvJ,GAWZ,MANIyjB,KACA/P,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,eAAgB,GAK/CQ,EAAkB6B,kBAAkBlnB,GAC7B7P,EAAOa,MAAMgP,GAObujB,EAAWpzB,OAAO6P,IAOjCoF,OAAQ,SAASpF,GACb,GAAI4oB,GAAelV,EAAQtO,OAAOpF,EAE9Brd,IAAGga,iBAAiBisB,GACpBA,EAAa/rB,KAAK,WACd1M,EAAOiV,OAAOpF,KAGb4oB,KAAiB,GACtBz4B,EAAOiV,OAAOpF,IAOtBsF,UAAW,WACP,GACI9O,GADAuwB,EAAqB1B,EAAkByB,uBAK3C,IAAIC,EAAmB//B,OACnB,IAAKwP,EAAIuwB,EAAmB//B,OAAS,EAAGwP,GAAK,EAAGA,IAC5C+sB,EAAWne,OAAO2hB,EAAmBvwB,GAI7C6uB,GAAkB3lB,SAKtBsH,QAAS,SAAShH,GACd,MAAI0T,GAAQ+T,UAAY/T,EAAQ+T,SAASznB,GAC9B0T,EAAQ+T,SAASznB,GAAIxC,cAGzBkW,EAAQ1M,SAAW0M,EAAQ1M,QAAQhH,IAI9C6oB,UAAW,SAAS7oB,GAChB,SAAU0T,EAAQ+T,WAAY/T,EAAQ+T,SAASznB,KAGnDZ,SAAU,SAASY,GACf,GAAI0T,EAAQtU,SACR,MAAOsU,GAAQtU,SAASY,IAIhCN,MAAO,WACH3a,EAAI,4BACJw+B,EAAWje,YACX+f,EAAkB3lB,QAClBgU,EAAQhU,SAGZgY,QAAS,SAAS1X,GACd,GAAIujB,EAAWnd,QAAQpG,GACnB,MAAO0T,GAAQgE,QAAQ1X,IAO/BoG,QAAS,SAASpG,GACd,MAAO0T,GAAQtN,QAAQpG,IAG3B+H,sBAAuB,WACnB,MAAI2L,GAAQ3L,sBACD2L,EAAQ3L,4BAavBkb,oBAAqB,SAASjjB,GAC1B,GAAIujB,EAAWnd,QAAQpG,GACnB,MAAO0T,GAAQuP,oBAAoBjjB,IAS3ChE,MAAO,SAASgE,GACZ,SAAIujB,EAAWuF,YAAY9oB,IAAO0T,EAAQ1X,OAASunB,EAAWnd,QAAQpG,IAAO0T,EAAQ1X,MAAMgE,MACvFqlB,EAAkBC,KAAKtlB,GACvB0T,EAAQ0R,0BAA0BplB,IAC3B,IAMf8oB,YAAa,SAAS9oB,GAClB,QAAS0T,EAAQoV,aAAepV,EAAQoV,YAAY9oB,MAI5Drd,GAAGwG,OAAOxH,EAASic,GACnB7Y,EAAMpD,EAAQoD,IACdy+B,EAAmB7hC,EAAQyZ,SAASyK,SAAWljB,GAAGiW,kBAAkBwC,SACpEqoB,EAA6BD,GAAoB7hC,EAAQyZ,SAASohB,WAAW3W,QAE7Eyd,EAAwB,WACpB,GAAIjN,KAIJ,OAFAA,GAAS10B,EAAQiuB,oBAAqB,EAE/ByG,KAGXlmB,EAAOu3B,eC9uBX/kC,GAAGomC,qBAAuB,SAASnrB,GAC/B,YAEA,IAAIjc,IACIoD,IAAK,SAASC,EAAS+H,MAE3Bi8B,IAEJrmC,IAAGwG,OAAOxH,EAASic,GAEnBjb,GAAGwG,OAAOvE,MACNqkC,eAAgB,SAASjpB,EAAIzK,GACzB,GAAI2zB,GAA2B,SAAS7P,GAChC9jB,EAAS8jB,EAAMr2B,MAGnB+I,QAAOiP,YACPguB,EAAyBhpB,GAAMrd,GAAGoJ,QAAQjE,OAAO,UAAWohC,GAG5DnkC,IAAI,wDAAyD,UAIrEokC,sBAAuB,SAASnpB,GAC5B,GAAIjU,OAAOiP,YAAa,CACpB,GAAIouB,GAAWJ,EAAyBhpB,EACpCopB,IACAA,SCvBpBzmC,GAAG0mC,kBAAoB,SAASroB,GAC5B,YAoBA,SAASsoB,GAAYtpB,SACVupB,GAAiBvpB,GAKpBwpB,IACAhS,aAAaiS,EAA0BzpB,UAChCypB,GAA0BzpB,GACjC0pB,EAAoBP,sBAAsBnpB,GAG9C,IAAI2pB,GAAS75B,SAAS85B,eAAelW,EAAQmW,eAAe7pB,GACxD2pB,KAIAA,EAAO1yB,aAAa,MAAO,qBAE3BtU,GAAGgnC,GAAQjhC,UAQnB,QAASohC,GAAuBC,GAC5B,MAAOA,GAAWx9B,MAAM,KAAK,GAUjC,QAASy9B,GAAoBrmC,GACzB,GAAIgmC,GAAShnC,GAAGuS,UAAU,yCAA2CvR,EAAO,OAO5E,OALAgmC,GAAO1yB,aAAa,KAAMtT,GAE1BgmC,EAAO/hC,MAAMC,QAAU,OACvBiI,SAASm6B,KAAK/yB,YAAYyyB,GAEnBA,EAUX,QAASO,GAA4BP,EAAQp0B,GACzC,GAAIw0B,GAAaJ,EAAO3pB,GACpBsG,EAASwjB,EAAuBC,GAChC5pB,EAAOoI,EAAQjC,EAEnB6jB,GAAgBhqB,GAAQ5K,EAIxBg0B,EAAiBjjB,GAAU3jB,GAAGgnC,GAAQ7hC,OAAO,OAAQ,WAC7C4rB,EAAQtU,SAASkH,KACjBvhB,EAAI,mEAAqEglC,EAAa,KAEtFN,EAA0BM,GAAcvb,WAAW,WAC/C,GAAIqK,GAAe,gEAAkEkR,CACrFhlC,GAAI8zB,EAAc,SAClBtjB,GACIzQ,MAAO+zB,KAEZ,QAMX6Q,EAAoBT,eAAec,EAAY,SAAS/kC,GACpDD,EAAI,2CAA6CC,EAAU,IAC3D,IAGIolC,GAFA/T,GADSyT,EAAuBC,GACrBrW,EAAQ2W,mBAAmBrlC,IACtCmb,EAAOkW,EAASlW,IAGhBA,IAAQgqB,EAAgBhqB,IACxBpb,EAAI,qCAAuCglC,GAC3CvS,aAAaiS,EAA0BM,UAChCN,GAA0BM,GAEjCrW,EAAQ4W,iBAAiBP,GAEzBK,EAAiBD,EAAgBhqB,SAE1BgqB,GAAgBhqB,GACvBupB,EAAoBP,sBAAsBY,GAC1CK,EAAe/T,IAETlW,GACNpb,EAAI,IAAMC,EAAU,2CAxHhC,GAAIrD,GAAUqf,EAAKrf,QACf+xB,EAAU9uB,KACVi+B,EAAQ7hB,EAAK6hB,MACb0H,EAAwB5nC,GAAGuQ,cAC3Bi3B,KACAZ,KACAE,KACAD,EAAS7nC,EAAQ6nC,OACjBna,EAAY1tB,EAAQ0tB,UACpB9G,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,IACZ2kC,EAAsB,GAAI/mC,IAAGomC,sBAAsBhkC,IAAKA,GAkH5DpC,IAAGwG,OAAOvE,KAAM,GAAIjC,IAAGigC,cAAc5hB,IAErCre,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OAII4D,IAAK,SAAS0J,EAAIwS,GACd9f,EAAO4D,IAAI0J,GAAKnQ,MAAO2iB,IAEvBA,EAAUvb,aAAa,OAAQoY,GAG3BmD,EAAU/pB,YACV9F,GAAG6vB,GAAW9pB,UAItBgvB,QAAS,SAAS1X,GACdspB,EAAYtpB,GACZtN,EAAOglB,QAAQ1X,IAGnBoG,QAAS,SAASpG,GACd,MAAOtN,GAAO0T,QAAQpG,IACkB/c,SAApCywB,EAAQwP,cAAcljB,GAAInQ,UAK1ClN,GAAGwG,OAAOvE,MACNwa,SAAU,SAASY,GACf,MAAO0T,GAAQwP,cAAcljB,GAAInQ,OAWrC26B,iBAAkB,SAASb,EAAQp0B,GAE/B,GAAIk1B,EAEAjB,GACAU,EAA4BP,EAAQp0B,GAGpCg0B,EAAiBI,EAAO3pB,IAAMrd,GAAGgnC,GAAQ7hC,OAAO,OAAQ,WAMpD,GALA/C,EAAI,yBAA2B4kC,EAAO3pB,IAKjC2pB,EAAOlhC,WAAZ,CAIA,IAEI,GAAIkhC,EAAOe,iBACPf,EAAOe,gBAAgBT,MACkB,SAAzCN,EAAOe,gBAAgBT,KAAK50B,UAK5B,OAGR,MAAOvQ,GAEHC,EAAI,8EAAgFD,EAAME,QAAU,IAAK,SACzGylC,GAAsBx4B,SAAS,GAGnCsD,EAASk1B,OAWrBE,cAAe,SAAS3qB,GACpB,GAAI+pB,GAAarW,EAAQmW,eAAe7pB,EAExC,OAAOgqB,GAAoBD,IAQ/BO,iBAAkB,SAAStqB,GACM/c,SAAzBsmC,EAAiBvpB,KACjBupB,EAAiBvpB,WACVupB,GAAiBvpB,KAQhC6pB,eAAgB,SAASvjB,GACrB,MAAOA,GAAS,IAAMikB,GAY1BK,mBAAoB,SAAS5pB,GACzB,GAAI+K,GAAS/K,EAAK+K,OACdtI,EAAWzC,EAAKyC,SAChBthB,EAAS6e,EAAK7e,OACdi5B,EAAepa,EAAKoa,aACpByP,EAAa7pB,EAAK6pB,WAClB7zB,EAAOrU,GAAGuS,UAAU,iBAAmB6W,EAAS,2CAChD2T,EAAMjc,CAcV,OAZI2X,GACAz4B,GAAGoU,WAAW5U,EAAQ6U,GAGtB0oB,EAAM/8B,GAAGqT,QAAQ7T,EAAQshB,GAG7BzM,EAAKC,aAAa,SAAUyoB,GAC5B1oB,EAAKC,aAAa,SAAU4zB,GAC5B7zB,EAAKpP,MAAMC,QAAU,OACrBiI,SAASm6B,KAAK/yB,YAAYF,GAEnBA,GAOXqzB,mBAAoB,SAASS,GACzB,GAAIzU,KAEJ,KACIA,EAAW1zB,GAAGwU,UAAU2zB,GAE5B,MAAOhmC,GACHC,EAAI,0DAA4DD,EAAME,QAAU,IAAK,SAGzF,MAAOqxB,OCnSnB1zB,GAAGooC,iBAAmB,SAAS/pB,GAC3B,YAkBA,SAASkkB,GAAMllB,GACXrd,GAAGY,KAAKmwB,EAAQqR,SAAS/kB,GAAK,SAASgrB,EAAO3xB,GAC1C,GAAI4xB,GAAgBvX,EAAQwX,kBAAkBlrB,EAAIgrB,EAElD3xB,GAAI4mB,mBAAqB,KACzB5mB,EAAIlJ,OAAOwuB,WAAa,KACxBtlB,EAAI6rB,QACJ+F,GAAiBA,EAActI,UAAYsI,EAActI,SAAS3iB,KAvB1E,GAAI0T,GAAU9uB,KACVtC,EAAY0e,EAAKrf,QAAQW,UACzBugC,EAAQ7hB,EAAK6hB,MACbznB,EAAW4F,EAAKrf,QAAQyZ,SACxBc,EAAS8E,EAAKrf,QAAQua,OACtBivB,EAAa/vB,GAAY4F,EAAKrf,QAAQyZ,SAASyK,SAAWljB,GAAGiW,kBAAkBwC,SAC/EgwB,EAAgBlvB,GAAU8E,EAAKrf,QAAQua,OAAO2J,SAAWslB,GAAcxoC,GAAGiW,kBAAkBsD,OAC5F4J,EAAU+c,EAAM/c,QAChBkC,EAAU6a,EAAM7a,QAChBO,EAAUsa,EAAMta,QAChBf,EAAcqb,EAAMrb,YACpB8J,EAAgBuR,EAAMvR,cACtBH,EAAgB0R,EAAM1R,cACtBrB,EAAa+S,EAAM/S,WACnB/qB,EAAM89B,EAAM99B,GAahBpC,IAAGwG,OAAOvE,KAAM,GAAIjC,IAAGigC,cAAc5hB,IAErCre,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OAII4D,IAAK,SAAS0J,EAAIqrB,GACd,GAAI1oC,GAAGgM,OAAO08B,IAAgB1oC,GAAG+M,OAAO27B,GACpC34B,EAAO4D,IAAI0J,GAAKgF,KAAMqmB,QAErB,CAAA,KAAIA,YAAuB1oC,IAAG4a,WAI/B,KAAM,IAAIzU,OAAM,2CAHhB4J,GAAO4D,IAAI0J,GAAK6iB,MAAOwI,IAM3B3X,EAAQ4X,eAAetrB,GACvBorB,GAAiB1X,EAAQ6X,uBAAuBvrB,IAGpD0X,QAAS,SAAS1X,GACdklB,EAAMllB,GACN0T,EAAQ0Q,+BAA+BpkB,GACvC0T,EAAQ8T,WAAWxnB,GACnBtN,EAAOglB,QAAQ1X,OAK3Brd,GAAGwG,OAAOvE,MAEN2/B,iBAAkB,SAASvkB,EAAI2jB,SACpBjQ,GAAQwP,cAAcljB,GAAI9J,KAAKs1B,aAAa7H,IAGvDuC,SAAU,SAASlmB,EAAI2jB,GACnB,GAAI8H,GAAY/X,EAAQwP,cAAcljB,GAAI9J,IAEtCu1B,GAAUC,YACHD,GAAUC,KAAK/H,GAEtB8H,EAAUE,sBACHF,GAAUE,eAAehI,IAMxCM,eAAgB,SAASjkB,EAAI4rB,GACzB,GAAIC,GAAenY,EAAQgS,gBAAgB1lB,GAAM,EAC7C3G,EAAMqa,EAAQoY,QAAQ9rB,EAAI6rB,EAE9B,OAAID,IACO,GAAIjpC,IAAGoP,SAAUE,QAAQ25B,EAAevyB,GAAMA,IAGlD,GAAI1W,IAAGoP,SAAUE,WAAYoH,IAGxC2N,QAAS,SAAShH,GACd,MAAO0T,GAAQtN,QAAQpG,IAAO0T,EAAQwP,cAAcljB,GAAIgF,MAG5DyiB,SAAU,SAASznB,GACf,MAAO0T,GAAQtN,QAAQpG,IAAO0T,EAAQwP,cAAcljB,GAAI6iB,OAO5D9a,sBAAuB,WACnB,GAAIgkB,KAmBJ,OAjBArY,GAAQsY,sBAAsB,SAASlpC,EAAK6iB,GACxC+N,EAAQ0R,0BAA0B,KAAMzf,EAAWvK,SAASspB,WAAa/e,EAAWvK,SAASupB,UAE7F,IAAI3hC,IACAW,KAAMgiB,EAAWhiB,KACjBghC,UAAWhf,EAAWvK,SAASupB,UAC/BxjB,KAAMwE,EAAWxE,KACjBhB,KAAMwF,EAAWxF,KAGjBwF,GAAW7iB,MACXE,EAAKF,IAAM6iB,EAAW7iB,KAG1BipC,EAAmBtnC,KAAKzB,KAGrB+oC,GAGXjD,YAAa,SAAS9oB,GAClB,QAAS5E,GAAYsY,EAAQtN,QAAQpG,KAAQ0T,EAAQwP,cAAcljB,GAAIisB,cAG3E7G,0BAA2B,SAASplB,EAAIksB,EAAeC,GACnD,GAAIzH,GAAawH,GAAiBxY,EAAQwP,cAAcljB,GAAI5E,SAASspB,WACjEC,EAAYwH,GAAgBzY,EAAQwP,cAAcljB,GAAI5E,SAASupB,SAE/DD,KACA3/B,EAAIpC,GAAG0L,OAAO,yDAA0DgJ,KAAKopB,UAAUiE,KACvFA,EAAW0H,UACXzpC,GAAGY,KAAKmhC,EAAY,SAASngC,EAAKo/B,GAC9BgB,EAAUC,QAAQjB,KAEtBe,EAAW19B,OAAS,IAI5BgV,MAAO,SAASgE,GACZ,GAAI0T,EAAQtN,QAAQpG,GAIhB,MAHAjb,GAAIpC,GAAG0L,OAAO,4DAA6D2R,EAAI8F,EAAQ9F,KACvF0T,EAAQwP,cAAcljB,GAAIqsB,QAAS,EACnCnH,EAAMllB,IACC,GAIf2lB,mBAAoB,SAAS3lB,GACzB,GAAI5E,GAAYsY,EAAQtN,QAAQpG,GAAK,CACjC,GACIssB,GACA91B,EAFA2G,EAAQuW,EAAQwP,cAAcljB,EAQlC,UAJO7C,GAAM/B,SAEb+B,EAAM/B,YACNkxB,EAAc5Y,EAAQgS,gBAAgB1lB,GAClCssB,EAAc,GAAKlxB,EAASqhB,UAAW,CAKvC,IAJAtf,EAAM/B,SAASyK,SAAU,EACzB1I,EAAM/B,SAASmxB,MAAQD,EACvBnvB,EAAM/B,SAASupB,aAEVnuB,EAAI,EAAGA,EAAI81B,EAAa91B,IACzB2G,EAAM/B,SAASupB,UAAUlgC,KAAK+R,EAGlCkd,GAAQ4X,eAAetrB,OAGvB7C,GAAM/B,SAASyK,SAAU,IAKrCqiB,WAAY,SAASloB,EAAIwsB,GACjB9Y,EAAQtN,QAAQpG,KAChB0T,EAAQwP,cAAcljB,GAAIgF,KAAOwnB,IAIzChF,WAAY,SAASxnB,GACjB,GAAIyrB,GAAY/X,EAAQwP,cAAcljB,GAAI9J,IAE1CvT,IAAGY,KAAKkoC,EAAUE,eAAgB,SAASc,SAChChB,GAAUE,eAAec,KAGpC9pC,GAAGY,KAAKkoC,EAAUC,KAAM,SAASe,SACtBhB,GAAUC,KAAKe,MAW9BC,WAAY,SAAS1sB,EAAI2sB,GACrB,MAAOjZ,GAAQkZ,aAAa5sB,EAAI2sB,EAAahqC,GAAGuN,sBAGpDg7B,kBAAmB,SAASlrB,EAAI2sB,GAC5B,GAAIhJ,GAA0B,MAAfgJ,GAAsB,EAAKA,CAC1C,OAAOjZ,GAAQwP,cAAcljB,GAAI9J,KAAKy1B,eAAehI,IAGzDC,cAAe,SAAS5jB,EAAI6sB,GACxB,GAAIhQ,GAAYzhB,EAAS4hB,SACrB8P,EAAW9kB,EAAQhI,GACnBjP,EAAa2iB,EAAQ1M,QAAQhH,GAC7B+sB,EAAalQ,EAAYgQ,EACzBG,EAAWD,EAAalQ,GAAaiQ,EAAWA,EAAWC,EAAalQ,EACxEyP,EAAc5Y,EAAQgS,gBAAgB1lB,GACtCwrB,EAAe5mC,KAAKs+B,cAAcljB,GAAI9J,KAAKs1B,aAI3C/5B,EAAO+5B,EAAaqB,IAAelqC,GAAGmO,UAAUC,EAAYg8B,EAAYC,EAI5E,OAFAxB,GAAaqB,GAAcp7B,GAGvBw7B,KAAMJ,EACN77B,MAAO+7B,EACP97B,IAAK+7B,EACLE,MAAOZ,EACP76B,KAAMA,EACN0P,KAAM6rB,EAAWD,IAIzBhJ,yBAA0B,SAASnT,GAC/B,OACI+L,UAAW/L,EAAUqc,KACrBE,UAAWvc,EAAU5f,MAAQ,EAC7Bo8B,QAASxc,EAAU3f,IACnB8rB,WAAYnM,EAAUsc,QAQ9BG,mBAAoB,SAASrtB,GACzB,GAAIstB,GAAgB,MAChB3pC,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,GACf6c,EAAYzhB,EAAS4hB,SACrBvZ,EAAW+D,EAAYxH,EAE3B,OAAOrd,IAAG0L,OAAO,2BAA4B/L,EAAWgrC,EAAe3pC,EAAMwd,EAAM0b,EAAWpZ,IAGlG8pB,aAAc,SAASvtB,GACnB,MAAO0T,GAAQ1M,QAAQhH,GAAIja,MAG/BynC,oBAAqB,SAASxtB,GAC1B,MAAO0T,GAAQwP,cAAcljB,GAAI5E,UAOrCsqB,gBAAiB,SAAS1lB,GACtB,GAAI5E,EAAU,CACV,GAAI0xB,GAAW9kB,EAAQhI,GACnB6c,EAAYzhB,EAAS4hB,QAEzB,OAAO/zB,MAAKwkC,KAAKX,EAAWjQ,KAIpCiP,QAAS,SAAS9rB,EAAI2sB,GAClB,GAAIhJ,GAA0B,MAAfgJ,GAAsB,EAAKA,CAC1C,OAAOjZ,GAAQwP,cAAcljB,GAAI9J,KAAKw1B,KAAK/H,IAG/CoB,SAAU,SAAS/kB,GACf,MAAO0T,GAAQwP,cAAcljB,GAAI9J,KAAKw1B,MAK1CM,sBAAuB,SAASz2B,GACxB61B,GACAzoC,GAAGY,KAAKsW,aAAc,SAAS/W,EAAK+K,GAChC,GAAwD,IAApD/K,EAAI0J,QAAQ7J,GAAG0L,OAAO,aAAc/L,IAAmB,CACvD,GAAIqjB,GAAatO,KAAKC,MAAMzJ,EAC5B0H,GAASzS,EAAK6iB,OAM9B2lB,eAAgB,SAAStrB,GACrB0T,EAAQwP,cAAcljB,GAAI9J,MACtBy1B,kBACA7H,iBACA4H,QACAF,kBAIRkC,kBAAmB,SAAS1tB,GACxB0T,EAAQwP,cAAcljB,GAAIisB,cAAe,GAK7C7H,+BAAgC,SAASpkB,GACrC,GAAI2tB,EAEJ,UAAIvC,GAAiB1X,EAAQoV,YAAY9oB,KACrC2tB,EAAiBja,EAAQ2Z,mBAAmBrtB,GAExC2tB,GAAkB9zB,aAAanE,QAAQi4B,OACvC9zB,aAAa+zB,WAAWD,IACjB,IASnBpC,uBAAwB,SAASvrB,GAC7B,GACI2tB,GAAgBE,EADhB1wB,EAAQuW,EAAQwP,cAAcljB,EAK9BorB,IAA+BnoC,SAAdka,EAAMra,MACvB6qC,EAAiBja,EAAQ2Z,mBAAmBrtB,GAC5C6tB,EAAgBh0B,aAAanE,QAAQi4B,GAGjCE,IACAA,EAAgBx2B,KAAKC,MAAMu2B,GAIvBvc,EAAcuc,EAAc1tB,MAC5BuT,EAAQga,kBAAkB1tB,IAG1Bjb,EAAIpC,GAAG0L,OAAO,0DAA2D2R,EAAI8F,EAAQ9F,KAErFmR,EAAcnR,EAAI6tB,EAAc1tB,MAEhChD,EAAMra,IAAM+qC,EAAc/qC,IAC1Bqa,EAAM/B,SAAWyyB,EAAczyB,SAC/B+B,EAAM4S,OAAS8d,EAAc9d,OAC7B5S,EAAM0mB,kBAAmB,EAEzBnQ,EAAQ0R,0BAA0BplB,OAOlDimB,0BAA2B,SAASjmB,GAChC,GACI2tB,GAAgBE,EADhB1wB,EAAQuW,EAAQwP,cAAcljB,EAIlC,IAAIorB,GAAiB1X,EAAQoV,YAAY9oB,GAAK,CAC1C2tB,EAAiBja,EAAQ2Z,mBAAmBrtB,GAE5C6tB,GACIlqC,KAAMmiB,EAAQ9F,GACdmB,KAAM6G,EAAQhI,GACdG,KAAMoI,EAAQvI,GACdld,IAAKqa,EAAMra,IACXsY,SAAU+B,EAAM/B,SAChB2U,OAAQ5S,EAAM4S,OACd+d,YAAarL,KAAK+F,MAGtB,KACI3uB,aAAaC,QAAQ6zB,EAAgBt2B,KAAKopB,UAAUoN,IAExD,MAAO/oC,GACHC,EAAIpC,GAAG0L,OAAO,0DAA2D2R,EAAIlb,EAAMsI,YAAa,WAK5G2gC,yBAA0B,SAAS/tB,EAAI2jB,EAAU9G,GAC7C,GAAIxjB,GAAMqa,EAAQoY,QAAQ9rB,EAAI2jB,GAC1BhgC,EAAOmiB,EAAQ9F,GACfguB,GACI3G,OAAQ,SAAStX,EAAQC,GACrB,GAAI8c,GAAW9kB,EAAQhI,EAEnB+P,KAAWC,EACXF,EAAW9P,EAAIrc,EAAMmpC,EAAUA,GAG/Bhd,EAAW9P,EAAIrc,EAAOosB,GAAU+c,EAAWA,EAAW,EAAI/c,EAAS+c,IAI3EpJ,QAAS,SAAS3T,EAAQC,GACtB,GAAI8T,GAAgBpQ,EAAQwP,cAAcljB,GAAI9J,KAAK4tB,cAC/CmK,EAAiCva,EAAQwP,cAAcljB,GAAI+P,OAC3Dme,EAAmBne,EACnBoe,EAAkBne,EAClB8M,EAAgB9U,EAAQhI,GACxBouB,EAAuBF,GAAoBC,EAAkBtR,GAC7DwR,EAAqBJ,CAEzBnK,GAAcH,GAAYyK,EAE1BzrC,GAAGY,KAAKugC,EAAe,SAASH,EAAU2K,GACtCD,GAAsBC,IAG1Bxe,EAAW9P,EAAIrc,EAAM0qC,EAAoBvR,IAIrDzjB,GAAIlJ,OAAOwuB,WAAa,SAAS3pB,GAC7B,GAAIA,EAAE4rB,iBAAkB,CAEpB,GAAI76B,GAAoB,MAAb82B,EAAoB,SAAW,SAC1CmR,GAAmBjoC,GAAMiP,EAAE+a,OAAQ/a,EAAEgb,UAcjD4c,aAAc,SAAS5sB,EAAI2sB,EAAatzB,EAAKk1B,GACzC,GAAIC,GAAwB,MAAf7B,GAAsB,EAAKA,EACpClB,EAAY/X,EAAQwP,cAAcljB,GAAI9J,IAW1C,OATAu1B,GAAUC,KAAOD,EAAUC,SAC3BD,EAAUE,eAAiBF,EAAUE,mBAErCF,EAAUC,KAAK8C,GAAUn1B,EAErBk1B,IACA9C,EAAUE,eAAe6C,GAAUD,GAGhCl1B,GAIXyuB,8BAA+B,WAC3B,GAAI2G,GAAiBvyB,EAAO+gB,eAE5BvJ,GAAQsY,sBAAsB,SAASlpC,EAAK6iB,GACxC,GAAI+oB,GAAiB,GAAIjM,MAAK9c,EAAWmoB,YAGzCY,GAAeC,QAAQD,EAAeE,UAAYH,GAE9CC,EAAehM,WAAaD,KAAK+F,QACjCzjC,EAAI,2CAA6CjC,GACjD+W,aAAa+zB,WAAW9qC,OAWpC4lC,qBAAsB,SAAS1oB,GAC3B,GAAI7C,GAAQuW,EAAQwP,cAAcljB,EAMlC,OAJK7C,GAAM/B,UACPsY,EAAQiS,mBAAmB3lB,GAGxB7C,EAAM/B,SAASyK,YCxflCljB,GAAGmpB,wBAA0B,SAASlO,GAClC,YAqBA,SAASixB,KACL,MAAqC,SAAjCltC,EAAQoqB,OAAOvpB,eAEXssC,QAAS,aAtBrB,GAAIC,GACAptC,GACIoqB,OAAQ,SACRE,cAAe,SACfK,iBACAN,eAAgB,EAChBI,cAAe,SAASpM,GAAK,UAC7BqM,eACAE,MACIoI,UAAU,EACVyI,iBAAiB,GAErBr4B,IAAK,SAASuJ,EAAKvB,KACnByf,SAAU,SAASxM,KACnB0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,KAGjDjqB,IAAGwG,OAAOxH,EAASic,GAYnBmxB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAe,OAAQ,UACvBvV,OAAQpqB,EAAQoqB,OAChBO,cAAe3qB,EAAQ2qB,cACvBD,YAAa1qB,EAAQ0qB,YACrBmT,eAAgBqP,IAChB7iB,eAAgBrqB,EAAQqqB,eACxBI,cAAe,SAASpM,GACpB,MAAOre,GAAQyqB,cAAc1E,IAAI1H,IAErCjb,IAAKpD,EAAQoD,IACb66B,OAAQj+B,EAAQ6qB,SAChB0D,WAAYvuB,EAAQ+qB,iBACpBH,KAAM5qB,EAAQ4qB,QAGlB5pB,GAAGwG,OAAOvE,MACN2zB,WAAY,SAASvY,EAAIG,EAAMgY,GAC3B,GAAIzI,GAAoByI,KAExBx2B,GAAQoD,IAAI,sCAAwCib,GAE7B,WAAnBre,EAAQoqB,OACRgjB,EAAUnN,cAAc5hB,GACnB+hB,SAAS5hB,GACT8hB,WAAWvS,GACX4Q,QAGL5Q,EAAkB/tB,EAAQsqB,eAAiB9L,EAC3C4uB,EAAUnN,cAAc5hB,GACnBiiB,WAAWvS,GACX4Q,YCpDrB,WAMI,QAAS0O,GAAkBC,GACvB,GAGIC,GAHAC,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTnkC,EAAS2E,SAASC,cAAc,SAGpC,OAAIo/B,GAAKE,EAAK,UACVlkC,EAAOokC,MAAQpkC,EAAOyT,OAAS,EAC/BswB,EAAM/jC,EAAOqkC,WAAW,MACxBN,EAAIO,UAAUR,GAAME,EAAK,EAAG,GAIoB,IAAzCD,EAAIQ,aAAa,EAAG,EAAG,EAAG,GAAG1sC,KAAK,IAUjD,QAAS2sC,GAAqBV,EAAKE,EAAIE,GACnC,GAIIH,GAAKlsC,EAAM4sC,EAAOC,EAJlB1kC,EAAS2E,SAASC,cAAc,UAChC+/B,EAAK,EACLC,EAAKV,EACLW,EAAKX,CAUT,KAPAlkC,EAAOokC,MAAQ,EACfpkC,EAAOyT,OAASywB,EAChBH,EAAM/jC,EAAOqkC,WAAW,MACxBN,EAAIO,UAAUR,EAAK,EAAG,GACtBjsC,EAAOksC,EAAIQ,aAAa,EAAG,EAAG,EAAGL,GAAIrsC,KAG9BgtC,EAAKF,GACRF,EAAQ5sC,EAAgB,GAAVgtC,EAAK,GAAS,GACd,IAAVJ,EACAG,EAAKC,EAELF,EAAKE,EAETA,EAAMD,EAAKD,GAAO,CAItB,OADAD,GAASG,EAAKX,EACI,IAAVQ,EAAe,EAAIA,EAM/B,QAASI,GAAqBhB,EAAKx9B,EAAM9P,EAASuuC,GAC9C,GAAI/kC,GAAS2E,SAASC,cAAc,UAChC3E,EAAOzJ,EAAQyJ,MAAQ,aACvB0G,EAAU,GAAInP,IAAGoP,OASrB,OAPAo+B,GAAoBlB,EAAKx9B,EAAMtG,EAAQxJ,EAASuuC,GAC3CrzB,KAAK,WACF/K,EAAQG,QACJ9G,EAAOI,UAAUH,EAAMzJ,EAAQ0J,SAAW,OAI/CyG,EAGX,QAASs+B,GAAoCpvB,GACzC,GAAIqvB,GAAY,MAEhB,KAAK1tC,GAAG6R,MACJ,KAAM,IAAI7R,IAAGmG,MAAM,kEAGvB,IAAIkY,EAAKsvB,WAAatvB,EAAKuvB,UAAYF,EACnC,OACIG,UAAWvnC,KAAKC,MAAMD,KAAKwnC,KAAKJ,GAAarvB,EAAKsvB,WAAatvB,EAAKuvB,aACpEG,SAAUznC,KAAKC,MAAMD,KAAKwnC,KAAKJ,GAAarvB,EAAKuvB,UAAYvvB,EAAKsvB,eAQ9E,QAASH,GAAoBlB,EAAKx9B,EAAMtG,EAAQxJ,EAASuuC,GACrD,GAMIS,GANAxB,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTC,EAAQ5tC,EAAQ4tC,MAChB3wB,EAASjd,EAAQid,OACjBswB,EAAM/jC,EAAOqkC,WAAW,MACxB19B,EAAU,GAAInP,IAAGoP,OAKrB,OAFAm9B,GAAI0B,OAEAjvC,EAAQkvC,OACDC,GACHr/B,KAAMA,EACNtG,OAAQA,EACRqvB,MAAOyU,EACP8B,YAAa1B,EACb2B,WAAY7B,EACZ8B,YAAatvC,EAAQsvC,YACrBJ,OAAQlvC,EAAQkvC,OAChBK,aAActyB,EACduyB,YAAa5B,KAIhB5sC,GAAGiW,kBAAkByD,2BACtBs0B,EAAqBP,GACjBG,UAAWhB,EACXe,WAAY1xB,IAGZ+xB,IACAhuC,GAAGoC,IAAIpC,GAAG0L,OAAO,iFACbkhC,EAAO3wB,EAAQ+xB,EAAmBD,SAAUC,EAAmBH,WAC/D,QAEJjB,EAAQoB,EAAmBD,SAC3B9xB,EAAS+xB,EAAmBH,YAIpCY,EAAoBjmC,EAAQokC,EAAO3wB,EAAQjd,EAAQsvC,aAI/CtuC,GAAG6R,OACF,WACOw6B,EAAkBC,KAClBE,GAAM,EACNE,GAAM,EAGV,IAOIgC,GAAQC,EAAIC,EAPZC,EAAI,KACJC,EAAY3hC,SAASC,cAAc,UACnC2hC,EAAkBxB,EAAWP,EAAqBV,EAAKE,EAAIE,GAAM,EACjEsC,EAAK1oC,KAAKwkC,KAAK+D,EAAIjC,EAAQJ,GAC3ByC,EAAK3oC,KAAKwkC,KAAK+D,EAAI5yB,EAASywB,EAAKqC,GACjC5B,EAAK,EACL+B,EAAK,CAMT,KAHAJ,EAAUlC,MAAQkC,EAAU7yB,OAAS4yB,EACrCH,EAASI,EAAUjC,WAAW,MAEvBM,EAAKT,GAAI,CAGZ,IAFAiC,EAAK,EACLC,EAAK,EACED,EAAKnC,GACRkC,EAAOS,UAAU,EAAG,EAAGN,EAAGA,GAC1BH,EAAO5B,UAAUR,GAAMqC,GAAKxB,GAC5BZ,EAAIO,UAAUgC,EAAW,EAAG,EAAGD,EAAGA,EAAGD,EAAIM,EAAIF,EAAIC,GACjDN,GAAME,EACND,GAAMI,CAEV7B,IAAM0B,EACNK,GAAMD,EAEV1C,EAAI6C,UACJN,EAAYJ,EAAS,QAIzBnC,EAAIO,UAAUR,EAAK,EAAG,EAAGM,EAAO3wB,GAGpCzT,EAAO6mC,iBAAmB7mC,EAAO6mC,kBACjClgC,EAAQG,UAEDH,GAGX,QAASg/B,GAAqCmB,GAC1C,GAAIxgC,GAAOwgC,EAAWxgC,KAClB+oB,EAAQyX,EAAWzX,MACnBuW,EAAckB,EAAWlB,YACzBC,EAAaiB,EAAWjB,WACxBC,EAAcgB,EAAWhB,YACzBn/B,EAAU,GAAInP,IAAGoP,QACjB8+B,EAASoB,EAAWpB,OACpBqB,EAAepiC,SAASC,cAAc,UACtCoiC,EAAsBD,EAAa1C,WAAW,MAC9C4C,EAAeH,EAAW9mC,OAC1B+lC,EAAee,EAAWf,aAC1BC,EAAcc,EAAWd,WAyB7B,OAvBAC,GAAoBc,EAAclB,EAAYD,EAAaE,GAE3DmB,EAAaxzB,OAASsyB,EACtBkB,EAAa7C,MAAQ4B,EAErBgB,EAAoB1C,UAAUjV,EAAO,EAAG,GAExCqW,GACIp/B,KAAMA,EACNmN,OAAQsyB,EACR1W,MAAOA,EACP0X,aAAcA,EACdE,aAAcA,EACd7C,MAAO4B,IAENt0B,KACG,WACIu1B,EAAaJ,iBAAmBI,EAAaJ,kBAC7ClgC,EAAQG,WAEZH,EAAQK,SAGTL,EAOX,QAASs/B,GAAoBjmC,EAAQokC,EAAO3wB,EAAQqyB,GAChD,OAAQA,GACJ,IAAK,GACL,IAAK,GACL,IAAK,GACL,IAAK,GACD9lC,EAAOokC,MAAQ3wB,EACfzT,EAAOyT,OAAS2wB,CAChB,MACJ,SACIpkC,EAAOokC,MAAQA,EACfpkC,EAAOyT,OAASA,EAExB,GAAIswB,GAAM/jC,EAAOqkC,WAAW,KAC5B,QAAQyB,GACJ,IAAK,GAED/B,EAAImD,UAAU9C,EAAO,GACrBL,EAAInoB,OAAM,EAAI,EACd,MACJ,KAAK,GAEDmoB,EAAImD,UAAU9C,EAAO3wB,GACrBswB,EAAIoD,OAAOrpC,KAAKspC,GAChB,MACJ,KAAK,GAEDrD,EAAImD,UAAU,EAAGzzB,GACjBswB,EAAInoB,MAAM,GAAG,EACb,MACJ,KAAK,GAEDmoB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAInoB,MAAM,GAAG,EACb,MACJ,KAAK,GAEDmoB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAImD,UAAU,GAAIzzB,EAClB,MACJ,KAAK,GAEDswB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAImD,UAAU9C,GAAQ3wB,GACtBswB,EAAInoB,OAAM,EAAI,EACd,MACJ,KAAK,GAEDmoB,EAAIoD,QAAO,GAAOrpC,KAAKspC,IACvBrD,EAAImD,WAAW9C,EAAO,IAUlC,QAASiD,GAAaC,EAAUC,GAC5B,GAAI/rC,GAAO/B,IAEPmH,QAAOO,MAAQmmC,YAAoBnmC,QAClC,WACG,GAAI2iC,GAAM,GAAI0D,OACVC,EAAM7mC,OAAO6mC,KAAO7mC,OAAO6mC,IAAIC,gBAAkB9mC,OAAO6mC,IACpD7mC,OAAO+mC,WAAa/mC,OAAO+mC,UAAUD,gBAAkB9mC,OAAO+mC,UAAY,IAClF,KAAKF,EAAO,KAAM9pC,OAAM,uDACxBmmC,GAAI8D,IAAMH,EAAIC,gBAAgBJ,GAC9B9rC,EAAK8K,KAAOghC,EACZA,EAAWxD,KAGdwD,EAASrD,cAAiBqD,EAASnD,gBACpCmD,EAASzgC,OAAS,WACd,GAAIghC,GAAYrsC,EAAKssC,kBACjBD,KACArsC,EAAKssC,mBAAqB,KAG1BzkB,WAAW,WACP,IAAK,GAAIhY,GAAI,EAAGxD,EAAMggC,EAAUhsC,OAAQwP,EAAIxD,EAAKwD,IAC7Cw8B,EAAUx8B,MAEf,KAGXi8B,EAASvgC,QAAUwgC,EACnB9tC,KAAKquC,uBAETruC,KAAK6tC,SAAWA,EAMpBD,EAAaruC,UAAU+uC,OAAS,SAAS1gC,EAAQ7Q,GAC7CA,EAAUA,KAEV,IASIwxC,GATAxsC,EAAO/B,KACPwuC,EAAWxuC,KAAK6tC,SAASrD,aACzBiE,EAAYzuC,KAAK6tC,SAASnD,cAC1BC,EAAQ5tC,EAAQ4tC,MAChB3wB,EAASjd,EAAQid,OACjB2c,EAAW55B,EAAQ45B,SACnBD,EAAY35B,EAAQ25B,UACpB4U,GAAYtrC,KAAK6M,MAA2B,eAAnB7M,KAAK6M,KAAK1L,KACnC0J,EAAU+C,EAAO/C,QAAQ/M,aAG7B,OAAIkC,MAAKquC,uBACLruC,MAAKquC,mBAAmBxuC,KAAK,WAAakC,EAAKusC,OAAO1gC,EAAQ7Q,MAI9D4tC,IAAU3wB,EACVA,EAAUy0B,EAAY9D,EAAQ6D,GAAa,EACpCx0B,IAAW2wB,EAClBA,EAAS6D,EAAWx0B,EAASy0B,GAAc,GAE3C9D,EAAQ6D,EACRx0B,EAASy0B,GAET9X,GAAYgU,EAAQhU,IACpBgU,EAAQhU,EACR3c,EAAUy0B,EAAY9D,EAAQ6D,GAAa,GAE3C9X,GAAa1c,EAAS0c,IACtB1c,EAAS0c,EACTiU,EAAS6D,EAAWx0B,EAASy0B,GAAc,GAG/CF,GAAQ5D,MAAOA,EAAO3wB,OAAQA,GAC9Bjc,GAAGY,KAAK5B,EAAS,SAAS2xC,EAAYC,GAClCJ,EAAIG,GAAcC,IAGN,QAAZ9jC,GACC,WACG,GAAI+jC,GAAehhC,EAAOugC,GAC1B9C,GAAqBtpC,EAAK8rC,SAAU9rC,EAAK8K,KAAM0hC,EAAKjD,GAC/CrzB,KAAK,SAASrR,GACXgH,EAAOugC,IAAMvnC,EACbgoC,IAAiBhhC,EAAOugC,KAAOvgC,EAAOR,cAG/B,WAAZvC,GACP0gC,EAAoBvrC,KAAK6tC,SAAU7tC,KAAK6M,KAAMe,EAAQ2gC,EAAKjD,QAElC,kBAAlBtrC,MAAK6uC,UACZ7uC,KAAK6uC,SAASjhC,MAItB7P,GAAG6vC,aAAeA,KCtYtB7vC,GAAGm7B,eAAiB,SAAS/4B,GACzB,YAEA,SAAS2uC,GAAM3sC,GACX,MAAoC,QAA7BA,EAAG0I,QAAQ/M,cAGtB,QAASixC,GAAS5sC,GACd,MAAoC,WAA7BA,EAAG0I,QAAQ/M,cAGtB,QAASkxC,KACL,MAAmC3wC,WAA5B,GAAI0vC,QAAQkB,YAGvB,QAASC,KACL,GAAI3oC,GAAS2E,SAASC,cAAc,SAEpC,OAAO5E,GAAOqkC,YAAcrkC,EAAOqkC,WAAW,MAMlD,QAASuE,GAAwBC,GAE7B,GAAIC,GAAeD,EAAaznC,MAAM,KAClC5I,EAAOswC,EAAaA,EAAajtC,OAAS,GAAGuF,MAAM,KAAK,GACxD0nB,EAAYtxB,GAAG6U,aAAa7T,EAIhC,QAFAswB,EAAYA,GAAaA,EAAUvxB,eAG/B,IAAK,OACL,IAAK,MACD,MAAO,YACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,OACL,IAAK,MACD,MAAO,cASnB,QAASwxC,GAAcxU,GACnB,GACIyU,GAAgBC,EAAgBC,EADhCC,EAAexkC,SAASC,cAAc,IAS1C,OANAukC,GAAaC,KAAO7U,EAEpByU,EAAiBG,EAAaE,SAC9BH,EAAaC,EAAaG,KAC1BL,EAAiBE,EAAaI,SAE1BP,EAAezxC,gBAAkBqJ,OAAO4oC,SAASH,SAAS9xC,gBAI1D0xC,EAAe1xC,gBAAkBqJ,OAAO4oC,SAASD,SAAShyC,eAK1D2xC,IAAetoC,OAAO4oC,SAASF,OAAS9xC,GAAG4Q,MAOnD,QAASqhC,GAAyB3F,EAAKn9B,GACnCm9B,EAAIj9B,OAAS,WACTi9B,EAAIj9B,OAAS,KACbi9B,EAAI/8B,QAAU,KACdJ,EAAQG,QAAQg9B,IAGpBA,EAAI/8B,QAAU,WACV+8B,EAAIj9B,OAAS,KACbi9B,EAAI/8B,QAAU,KACdnN,EAAI,6BAA8B,SAClC+M,EAAQK,QAAQ88B,EAAK,+BAI7B,QAAS4F,GAAgC1pC,EAAQ2G,GAO7C3G,EAAO6mC,gBAAkB,WACrBlgC,EAAQG,QAAQ9G,IAQxB,QAAS2pC,GAAkCvuB,EAAazU,GACpD,GAAIijC,GAAarB,EAAMntB,IAAgBotB,EAASptB,EAahD,OAXImtB,GAAMntB,GACNquB,EAAyBruB,EAAazU,GAEjC6hC,EAASptB,GACdsuB,EAAgCtuB,EAAazU,IAG7CA,EAAQK,QAAQoU,GAChBxhB,EAAIpC,GAAG0L,OAAO,iDAAkDkY,EAAY9W,SAAU,UAGnFslC,EAKX,QAASC,GAAKjkC,EAAYkW,EAAWtlB,GACjC,GAAIszC,GAAc,GAAItyC,IAAGoP,QACrBub,EAAa,GAAI3qB,IAAGuyC,SAASnkC,EAAYhM,GACzCyhB,EAAU7kB,EAAQ6kB,QAElBgX,EAA2B,MAAlB77B,EAAQ67B,QAAwB77B,EAAQ67B,OACjD2X,EAAsB,WAClBluB,EAAU/U,QAAU,KACpB+U,EAAUjV,OAAS,KACnBjN,EAAI,mDAAoD,SACxDkwC,EAAY9iC,QAAQ8U,EAAW,gCAiDvC,OA9CAqG,GAAW8nB,gBAAgBv4B,KACvB,SAASzR,GAGL,GAAIiqC,IACI/9B,MAAO,WACH,OAAO,GAAI3U,IAAGoP,SAAUE,YAGhCqjC,EAAO9X,EAAS,GAAI76B,IAAG4yC,KAAKxkC,EAAYhM,GAAOswC,EAC/CG,EAAQ,GAAI7yC,IAAG6vC,aAAazhC,EAAYokC,EAExCL,GAAkC7tB,EAAWguB,IAC7CK,EAAKh+B,QAAQuF,KACT,SAASy4B,GACL,GAAIrE,GAAcqE,GAAQA,EAAKG,WAE/BD,GAAMtC,OAAOjsB,GACTsU,SAAU/U,EACV8U,UAAW9U,EACXyqB,YAAaA,EACb7lC,KAAMA,EACNylC,OAAQlvC,EAAQ+kB,wBAIxB,SAASgvB,GACL3wC,EAAIpC,GAAG0L,OAAO,iEAAkEqnC,IAEhFF,EAAMtC,OAAOjsB,GACTsU,SAAU/U,EACV8U,UAAW9U,EACXpb,KAAMA,EACNylC,OAAQlvC,EAAQ+kB,0BAOpC,WACI3hB,EAAI,mBACJkwC,EAAY9iC,QAAQ8U,EAAW,qBAIhCguB,EAGX,QAASU,GAAyBjW,EAAKkW,EAAaZ,EAAMxuB,EAASE,GAC/D,GAAImvB,GAAU,GAAIlD,OACdmD,EAAgB,GAAInzC,IAAGoP,OAE3B+iC,GAAkCe,EAASC,GAEvC5B,EAAcxU,KACdmW,EAAQhC,YAAc,aAG1BgC,EAAQ9C,IAAMrT,EAEdoW,EAAcj5B,KACV,WACIi4B,EAAkCc,EAAaZ,EAE/C,IAAIQ,GAAQ,GAAI7yC,IAAG6vC,aAAaqD,EAChCL,GAAMtC,OAAO0C,GACTra,SAAU/U,EACV8U,UAAW9U,EACXpb,KAAM2oC,EAAwBrU,GAC9BmR,OAAQnqB,KAIhBsuB,EAAK7iC,SAIb,QAAS4jC,GAA+BrW,EAAKuP,EAAK+F,EAAMxuB,GACpDsuB,EAAkC7F,EAAK+F,GAKvCryC,GAAGssC,GAAKrmC,KACJ2yB,SAAU/U,EAAU,KACpB8U,UAAW9U,EAAU,OAGzByoB,EAAI8D,IAAMrT,EAWd,QAASsW,GAAYtW,EAAKzY,EAAWtlB,GACjC,GAAIqzC,GAAO,GAAIryC,IAAGoP,QACdgV,EAAQplB,EAAQolB,MAChBP,EAAUO,EAAQplB,EAAQ6kB,QAAU,IA8BxC,OA3BIO,IAAS2sB,EAAMzsB,GAGX6sB,IAIII,EAAcxU,KAASkU,IACvBmC,EAA+BrW,EAAKzY,EAAW+tB,EAAMxuB,GAGrDmvB,EAAyBjW,EAAKzY,EAAW+tB,EAAMxuB,GAInDuvB,EAA+BrW,EAAKzY,EAAW+tB,EAAMxuB,GAIpDmtB,EAAS1sB,GACd0uB,EAAyBjW,EAAKzY,EAAW+tB,EAAMxuB,GAG1CsuB,EAAkC7tB,EAAW+tB,KAClD/tB,EAAU8rB,IAAMrT,GAGbsV,EAGXryC,GAAGwG,OAAOvE,MAWNsiB,SAAU,SAAS+uB,EAAehvB,EAAWtlB,GACzC,MAAIgB,IAAGoL,SAASkoC,IACZlxC,EAAI,4DACGixC,EAAYC,EAAehvB,EAAWtlB,SAG7CoD,EAAI,iDACGiwC,EAAKiB,EAAehvB,EAAWtlB,WAMlDiD,KAAKsxC,YACLtxC,KAAKsxC,SAASxC,MAAQA,EACtB9uC,KAAKsxC,SAASvC,SAAWA,EACzB/uC,KAAKsxC,SAAShC,cAAgBA,EAC9BtvC,KAAKsxC,SAASnC,wBAA0BA,GChT5CpxC,GAAG4yC,KAAO,SAASxkC,EAAYhM,GAC3B,YAYA,SAASoxC,GAAkBC,GAIvB,IAHA,GAAIpsC,GAAS,EACTqsC,EAAM,EAEHD,EAAIpvC,OAAS,GAChBgD,GAAUi9B,SAASmP,EAAItyC,UAAU,EAAG,GAAI,IAAMmF,KAAKotC,IAAI,EAAGA,GAC1DD,EAAMA,EAAItyC,UAAU,EAAGsyC,EAAIpvC,QAC3BqvC,GAAO,CAGX,OAAOrsC,GAKX,QAASssC,GAAWC,EAAQzkC,GACxB,GAAI0kC,GAAYD,EACZE,EAAa3kC,CAwBjB,OAvBkB7O,UAAduzC,IACAA,EAAY,EACZC,EAAa,GAAI9zC,IAAGoP,SAGxBpP,GAAG6O,cAAcT,EAAYylC,EAAW,GAAG35B,KAAK,SAASu5B,GACrD,GACIM,GADA1wC,EAAQ,cAAcnC,KAAKuyC,EAG3BpwC,GACiB,MAAbA,EAAM,IACN0wC,EAAgBzP,SAASmP,EAAI3zC,MAAM,EAAG,GAAI,IAC1C6zC,EAAWE,EAAYE,EAAgB,EAAGD,IAG1CA,EAAWxkC,QAAQukC,GAIvBC,EAAWtkC,QAAQ,iCAIpBskC,EAIX,QAASE,KACL,GAAI7kC,GAAU,GAAInP,IAAGoP,OAgBrB,OAdApP,IAAG6O,cAAcT,EAAY,EAAG,GAAG8L,KAAK,SAASu5B,GACjB,IAAxBA,EAAI5pC,QAAQ,QACZsF,EAAQK,QAAQ,qBAGhBmkC,IAAaz5B,KAAK,SAAS05B,GACvBzkC,EAAQG,QAAQskC,IAEpB,SAASzxC,GACLgN,EAAQK,QAAQrN,OAKrBgN,EAIX,QAAS8kC,GAAeC,GACpB,GAAI/kC,GAAU,GAAInP,IAAGoP,OAMrB,OAJApP,IAAG6O,cAAcT,EAAY8lC,EAAY,GAAI,GAAGh6B,KAAK,SAASu5B,GAC1DtkC,EAAQG,QAAgB,SAARmkC,KAGbtkC,EAIX,QAASglC,GAAiBD,EAAWE,GACjC,GAAIjlC,GAAU,GAAInP,IAAGoP,OAWrB,OATApP,IAAG6O,cAAcT,EAAY8lC,EAAY,GAAI,GAAGh6B,KAAK,SAASu5B,GAC1D,MAAIW,GACOjlC,EAAQG,QAAQkkC,EAAkBC,QAGzCtkC,GAAQG,QAAQg1B,SAASmP,EAAK,OAI/BtkC,EAIX,QAASklC,GAAOH,EAAWI,GACvB,GAAIV,GAASM,EAAY,GACrBxlC,EAAqB,GAAb4lC,CAEZ,OAAOt0C,IAAG6O,cAAcT,EAAYwlC,EAAQllC,GAIhD,QAAS6lC,GAAcC,GAInB,IAHA,GAAIp3B,MACAw2B,EAAS,EAENA,EAAS,IAAMY,EAAOnwC,QACzB+Y,EAAQtb,KAAK0yC,EAAO10C,MAAM8zC,EAAQA,EAAS,KAC3CA,GAAU,EAGd,OAAOx2B,GAIX,QAASq3B,GAAaL,EAAcE,GAChC,GAAII,GAAiB,GACjBC,EAAa30C,GAAGwG,UAAWouC,GAC3BC,IAsBJ,OApBA70C,IAAGY,KAAK0zC,EAAY,SAAS1yC,EAAK25B,GAC9B,GAGIuZ,GAAWhoC,EAASioC,EAHpBC,EAAQzZ,EAAMz7B,MAAM,EAAG,GACvBud,EAAK+2B,EAAeZ,EAAkBwB,GAAS1Q,SAAS0Q,EAAO,IAC/DC,EAAgBN,EAAW9qC,QAAQwT,EAYvC,IATI43B,GAAiB,IACjBnoC,EAAUooC,EAAS73B,GAAIrc,KACvB+zC,EAAeG,EAAS73B,GAAI3O,MAC5BomC,EAAYvZ,EAAMz7B,MAAM40C,EAAgBA,EAAiC,EAAfK,GAC1DF,EAAK/nC,GAAWsnC,EAAeZ,EAAkBsB,GAAaxQ,SAASwQ,EAAW,IAElFH,EAAWz1B,OAAO+1B,EAAe,IAGX,IAAtBN,EAAWtwC,OACX,OAAO,IAIRwwC,EApJX,GAAID,IAAW,KACXM,GACIC,KACIn0C,KAAM,cACN0N,MAAO,GAmJnB1O,IAAGwG,OAAOvE,MAON0S,MAAO,WACH,GAAIygC,GAAS,GAAIp1C,IAAGoP,QAChBimC,EAAiB,SAAShzC,GACtBD,EAAIpC,GAAG0L,OAAO,kCAAmCrJ,IACjD+yC,EAAO5lC,QAAQnN,GA0BvB,OAvBA2xC,KAAgB95B,KAAK,SAASo7B,GAC1BlzC,EAAIpC,GAAG0L,OAAO,mDAAwEpL,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,OAEtHizC,EAAeqB,GAAYp7B,KAAK,SAASk6B,GAErChyC,EAAIpC,GAAG0L,OAAO,+BAAgC0oC,EAAe,SAAW,QAExED,EAAiBmB,EAAYlB,GAAcl6B,KAAK,SAASq7B,GAErDnzC,EAAIpC,GAAG0L,OAAO,kCAAmC6pC,IAEjDlB,EAAOiB,EAAYC,GAAer7B,KAAK,SAASs6B,GAC5C,GAAIF,GAAaC,EAAcC,GAC3BgB,EAAYf,EAAaL,EAAcE,EAE3ClyC,GAAI,sCAEJgzC,EAAO9lC,QAAQkmC,IAChBH,IACJA,IACJA,IACJA,GAEID,KAKfnzC,KAAKsxC,YACLtxC,KAAKsxC,SAASC,kBAAoBA,GC7MtCxzC,GAAGuyC,SAAW,SAASnkC,EAAYhM,GAC/B,YAEA,SAASqzC,GAAeC,EAAYC,GAChC,GAAIC,IAAe,EACfC,KAAuBziC,OAAOsiC,EASlC,OAPA11C,IAAGY,KAAKi1C,EAAmB,SAASj0C,EAAKk0C,GACrC,GAAwD,IAApDH,EAAkB9rC,QAAQisC,GAE1B,MADAF,IAAe,GACR,IAIRA,EAGX51C,GAAGwG,OAAOvE,MASNwwC,cAAe,WACX,GAAIzuC,GAAO/B,KACP0oB,EAAa,GAAI3qB,IAAGoP,QACpB2mC,GAAc,EACd/0C,EAA2BV,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,IAsC/D,OApCAoB,GAAIpC,GAAG0L,OAAO,gEAAiE1K,IAE/EoB,EAAI,oDAEAH,KAAK+zC,qBACL5zC,EAAI,sDAEJpC,GAAG6O,cAAcT,EAAY,EAAG,GAAG8L,KAAK,SAASu5B,GAC7CzzC,GAAGY,KAAKoD,EAAKiyC,uBAAwB,SAASxtC,EAAMiG,GAChD,GAAI+mC,EAAe/mC,EAAO+kC,GAQtB,OALa,eAAThrC,GAAyBzI,GAAGiW,kBAAkBwD,gBAC9Cs8B,GAAc,EACdprB,EAAWrb,QAAQ7G,KAGhB,IAIfrG,EAAIpC,GAAG0L,OAAO,iDAAkD1K,EAAM+0C,EAAc,GAAK,QAEpFA,GACDprB,EAAWnb,WAGnB,WACIpN,EAAI,+BAAiCpB,EAAO,gDAC5C2pB,EAAWnb,aAIfmb,EAAWnb,UAGRmb,GAWXqrB,kBAAmB,WACf,GAAIE,GAAW9nC,EAAWhL,KAEtB+yC,EAAoBn2C,GAAG6J,QAAQW,OAAO23B,KAAKlgC,KAAKg0C,wBAAyBC,IAAa,EACtFH,GAAc,EACd/0C,EAA2BV,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,IAa/D,OAXIm1C,KAEIJ,EADa,eAAbG,GACcl2C,GAAGiW,kBAAkBwD,eAO1Cs8B,GAAe3zC,EAAIpB,EAAO,gEAEpB+0C,MAKnB/1C,GAAGuyC,SAAS/wC,UAAUy0C,wBAClBG,aAAc,SACdC,YAAa,SACbC,YAAa,SACbC,YAAa,OACbC,cAAe,WAAY,aCpG/Bx2C,GAAG23B,gBAAkB,SAAS7oB,EAAM1M,GAChC,YAMA,SAASq0C,GAAiBC,GACtB,GAAIC,IAAa,CASjB,OAPA32C,IAAGY,KAAK81C,EAAQ,SAASE,EAAOjsC,GAC5B,GAAIA,EAAQ,EAER,MADAgsC,IAAa,GACN,IAIRA,EAQX,QAASE,KACL,GAAIC,GAAoB,GAAI92C,IAAGoP,OA6B/B,OA3BA,IAAIpP,IAAGuyC,SAASzjC,EAAM1M,GAAKqwC,gBAAgBv4B,KAAK,WAC5C,GAAI2d,GAAQ,GAAImY,OACZjT,EAAM3zB,OAAO6mC,KAAO7mC,OAAO6mC,IAAIC,gBAAkB9mC,OAAO6mC,IAClD7mC,OAAO+mC,WAAa/mC,OAAO+mC,UAAUD,gBAAkB9mC,OAAO+mC,UAC9D,IAENpT,IACAlF,EAAMtoB,QAAU,WACZnN,EAAI,4DAA6D,SACjE00C,EAAkBtnC,WAGtBqoB,EAAMxoB,OAAS,WACXynC,EAAkBxnC,SACds9B,MAAO3qC,KAAK2qC,MACZ3wB,OAAQha,KAAKga,UAIrB4b,EAAMuY,IAAMrT,EAAImT,gBAAgBphC,KAGhC1M,EAAI,+DAAgE,SACpE00C,EAAkBtnC,YAEvBsnC,EAAkBtnC,SAEdsnC,EASX,QAASC,GAAgBL,EAAQM,GAC7B,GAAIC,EA0BJ,OAxBAj3C,IAAGY,KAAK81C,EAAQ,SAASQ,EAAWC,GAChC,GAAIA,EAAa,EAAG,CAChB,GAAIC,GAAe,0BAA0Bl2C,KAAKg2C,GAC9CG,EAAoBD,EAAa,GAAGx3C,OAAO,GAAGG,cAAgBq3C,EAAa,GAAGt3C,MAAM,GACpFw3C,EAAcN,EAAWK,EAG7B,QAAQD,EAAa,IACjB,IAAK,MACD,GAAIE,EAAcH,EAEd,MADAF,GAAeC,GACR,CAEX,MACJ,KAAK,MACD,GAAII,EAAcH,EAEd,MADAF,GAAeC,GACR,MAOpBD,EAWXh1C,KAAK21B,SAAW,SAAS8e,GACrB,GAAIa,GAAmB,GAAIv3C,IAAGoP,OAoB9B,OAlBAhN,GAAI,iCAEAq0C,EAAiBC,GACjBG,IAAiB38B,KAAK,SAAS88B,GAC3B,GAAIC,GAAeF,EAAgBL,EAAQM,EAEvCC,GACAM,EAAiB/nC,QAAQynC,GAGzBM,EAAiBjoC,WAEtBioC,EAAiBjoC,SAGpBioC,EAAiBjoC,UAGdioC,IC7Hfv3C,GAAG42B,QAAU,SAASvY,GAClB,YAaA,SAASm5B,GAAoB9jB,GACzB,QAAI1zB,GAAG8C,QAAQ4wB,QAIf10B,GAAQoD,IAAI,oCAAqC,SAGrD,QAASq1C,GAAgBC,EAAWpoC,EAAS0a,EAAU7a,GACnD,GAAIwoC,IAAmB,CAEvBroC,GAAUA,GAAWkoC,EAAoBE,GAErCpoC,GACAtP,GAAGY,KAAK82C,EAAW,SAAS91C,EAAKw+B,GAE7B,GAAqB,MAAjBA,EAAS5iB,KACTm6B,GAAmB,EACnB34C,EAAQoD,IAAIpC,GAAG0L,OAAO,oEAAqE9J,GAAM,aAEhG,IAAqB,MAAjBw+B,EAASp/B,KACd22C,GAAmB,EACnB34C,EAAQoD,IAAIpC,GAAG0L,OAAO,oEAAqE9J,GAAM,aAGjG,KAEI,MADA5C,GAAQ83B,cAAcsJ,IACf,EAEX,MAAOwX,GACHD,GAAmB,EACnB34C,EAAQoD,IAAIw1C,EAAIv1C,QAAS,SAIjC,OAAO,IAIf8M,EAAQG,IAAYqoC,EAAmB,UAAY,WAAWD,EAAW1tB,GAlD7E,GAAIhrB,IACA8hB,SAAU,KACVthB,UACAiqB,iBACAG,QACAkN,cAAe,SAAStO,KACxBpmB,IAAK,SAASC,EAAS+H,KAG3BpK,IAAGwG,OAAOxH,EAASqf,GAAM,GA8CzBpc,KAAK80B,QAAU,WAEX,GAAI8gB,GAAgB,GAAI73C,IAAGoP,QACvB0oC,EAA0B,SAASpkB,EAAUpkB,EAAS0a,GAClDytB,EAAgB/jB,EAAUpkB,EAAS0a,EAAU6tB,IAEjDE,EAAmB/3C,GAAGwG,UAAWxH,GACjCotC,EAAY,GAAIpsC,IAAGg4C,qBACfh4C,GAAGwG,OAAOuxC,GAAmBxqB,WAAYuqB,IAKjD,OAFA1L,GAAU6L,cAEHJ,ICrEf73C,GAAGg4C,qBAAuB,SAAS35B,GAC/B,YAiBA,SAASkP,GAAWlQ,EAAI2M,EAAUC,GAC9B,GAAIyJ,GAAW,IAGf,IAA6B,MAAzB1J,EAASkuB,aACT,IACIxkB,EAAW1zB,GAAGwU,UAAUwV,EAASkuB,cAErC,MAAON,GACH54C,EAAQoD,IAAI,qCAAuCw1C,EAAIv1C,QAAS,SAChE4nB,GAAU,EAIlBjrB,EAAQuuB,WAAWmG,GAAWzJ,EAASD,GA7B3C,GAAIoiB,GACAptC,GACI8hB,SAAU,KACV2I,iBACAjqB,UACAoqB,MACIoI,UAAU,EACVyI,iBAAiB,GAErBlN,WAAY,SAASmG,EAAUpkB,EAAS0a,KACxC5nB,IAAK,SAASuJ,EAAKvB,KAG3BpK,IAAGwG,OAAOxH,EAASqf,GAmBnB+tB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAe,OACfvV,OAAQ,MACRO,eACI5E,IAAK,WACD,MAAO/lB,GAAQ8hB,WAGvB2I,cAAezqB,EAAQyqB,cACvBrnB,IAAKpD,EAAQoD,IACbmrB,WAAYA,EACZ3D,KAAM5qB,EAAQ4qB,QAGlB5pB,GAAGwG,OAAOvE,MACNg2C,YAAa,WACT,GAAIz4C,GAASQ,GAAGwG,UAAWxH,EAAQQ,OAEnCR,GAAQoD,IAAI,0BAEZgqC,EAAUnN,cAAc,kBACnBK,WAAW9/B,GACXogC,kBACAjC,WCzDjB39B,GAAGgnB,OAAS,SAAS3I,EAAMjc,GACvB,YAEA,IACI2hB,GAAuB1F,EAAKsc,cAC5Bwd,EAAkB95B,EAAKuc,aACvBC,EAASxc,EAAKwc,OACdC,EAAczc,EAAKyc,YACnBC,EAAiB1c,EAAK0c,eAAiB,IACvCqd,EAAoB/5B,EAAK2c,YACzBC,EAAc5c,EAAK4c,YACnBC,EAAQj5B,KAAKo2C,gBAAgBh6B,EAAK6c,MAGtCl7B,IAAGwG,OAAOvE,MAGNihB,QAASljB,GAAGiW,kBAAkBuD,SAAW0hB,EAAM72B,OAAS,EAExDi0C,eAAgB,SAASC,EAAkBC,EAAkBC,GACzD,GAAIz0C,GAAO/B,KACPy2C,KACAC,EAAeF,EAAuB3pC,KAAO2pC,EAAuB3pC,KAAO2pC,EAC3E9tB,EAAa,GAAI3qB,IAAGuyC,SAASoG,EAAcv2C,EAiD/C,OA9CIuoB,GAAWqrB,qBAEXh2C,GAAGY,KAAKs6B,EAAO,SAASt5B,EAAKg3C,GACzB,GAAIC,GAAa70C,EAAK80C,sBAClBhe,YAAaA,EACbie,cAAeH,EAAWx1C,KAC1B41C,QAASL,EAAav1C,MAG1Bs1C,GAAQ52C,MACJ0b,KAAMxd,GAAGuQ,cACTvP,KAAMgD,EAAKi1C,SAAST,GAChBx3C,KAAM43C,EAAW53C,KACjBoC,KAAMy1C,EACNG,QAASL,EAAav1C,OAE1B0L,KAAM,GAAI9O,IAAG4a,UAAU+9B,EACvB34C,GAAGgT,KAAKhP,EAAKk1C,qBAAsBl1C,GAC/B+f,qBAAsBA,EACtBF,QAAS+0B,EAAW/0B,QACpBgX,OAAQA,EACRz3B,KAAMy1C,EACNnwC,QAASqyB,EACToe,WAAYf,EACZnd,YAAaA,EACb74B,IAAKA,SAKjBs2C,EAAQ52C,MACJ0b,KAAM+6B,EACNv3C,KAAMw3C,EACNh6B,KAAMm6B,EAAan6B,KACnB1P,KAAMqpC,EAAkBQ,EAAe,QAI3CD,EAAQ52C,MACJ0b,KAAM+6B,EACNv3C,KAAMw3C,EACNh6B,KAAMm6B,EAAan6B,KACnB1P,KAAM6pC,IAIPD,GAGXrd,cAAe,SAAShZ,EAAMrhB,EAAMwc,EAAMgB,EAAM4S,EAAU3S,EAAS6K,EAAe8vB,GAC9E,GAAIp1C,GAAO/B,KAEPo3C,GADWh3B,EAAKyG,YAAezG,EAAKvT,MAAQuT,EAAKvT,KAAKga,eAEtDwwB,EAAa,KACbpoB,EAAmBkoB,EAAIloB,iBACvBlO,EAAao2B,EAAIp2B,WACjB0G,EAAc0vB,EAAI1vB,YAClBhL,EAAe1e,GAAGuQ,aAEtBvQ,IAAGY,KAAKoD,EAAKs0C,eAAe96B,EAAMxc,EAAMqhB,GAAO,SAASzgB,EAAK23C,GACzD,GACIl8B,GADAm8B,EAAWD,EAAO/6B,IAGlB+6B,GAAOzqC,eAAgB9O,IAAG4a,YAC1B4+B,GAAW,GAGfn8B,EAAK2F,EAAW5E,SACZZ,KAAM+7B,EAAO/7B,KACbxc,KAAMu4C,EAAOv4C,KACbwd,KAAMg7B,EACN/6B,QAASA,EACTC,aAAcA,IAGd66B,EAAOzqC,eAAgB9O,IAAG4a,UAC1By+B,EAAUv3C,KAAKub,GAGfi8B,EAAaj8B,EAGbk8B,EAAOzqC,MACPoiB,EAAiB7T,EAAIk8B,EAAOzqC,MAC5BsiB,EAAStvB,MAAMub,GAAIA,EAAIgF,KAAMk3B,EAAOzqC,QAGpCkU,EAAWlE,UAAUzB,EAAIrd,GAAG2d,OAAOqC,YAOxB,OAAfs5B,IACAt5C,GAAGY,KAAKy4C,EAAW,SAASz3C,EAAK63C,GAC7B,GAAIj6C,IACAk6C,aAAc12B,EAAWpE,UAAUvB,GAAIi8B,IAAa97B,KACpDm8B,aAAc32B,EAAWpE,UAAUvB,GAAIi8B,IAAa96B,KAKxDhf,GAAO8pB,GAAiBtG,EAAWpE,UAAUvB,GAAIo8B,IAAWj8B,KAE5DwF,EAAWtD,YAAY+5B,EAAUH,GACjC5vB,EAAY+B,YAAYguB,EAAUj6C,KAKlC65C,EAAUh1C,SACT,WACG,GAAIu1C,KACJA,GAAMtwB,GAAiBtG,EAAWpE,UAAUvB,GAAIi8B,IAAa97B,KAC7DkM,EAAY+B,YAAY6tB,EAAYM,WAQ5D55C,GAAGwG,OAAOxG,GAAGgnB,OAAOxlB,WAChBslB,WAAY,SAASzJ,EAAI0J,EAAOqyB,GAC5B,YAEA,KAAKp5C,GAAGiW,kBAAkBuD,QACtB,KAAM,IAAIxZ,IAAGmG,MAAM,4CAGvB,IAAI0zC,GAAgB,GAAI75C,IAAGoP,QACvBhN,EAAMg3C,EAAIh3C,IACVigB,EAAO+2B,EAAI/0B,QAAQhH,GACnB2F,EAAao2B,EAAIp2B,WAAWpE,UAAUvB,GAAIA,IAC1Crc,EAAOgiB,GAAcA,EAAWhiB,KAChCwc,EAAOwF,GAAcA,EAAWxF,KAChCs8B,GACInf,cAAe5T,EAAM4T,cACrBC,cAAc,EACdC,OAAQ9T,EAAM8T,OACdC,YAAa/T,EAAM3jB,MAAQ,KAC3B23B,eAAgBhU,EAAMre,QACtB0vC,kBAAmB,kBACnBld,QAASl6B,KAAM,GAAI6iB,QAASkD,EAAMlD,WAEtCk2B,EAAS,GAAI/5C,IAAGgnB,OAAO8yB,EAAgB13C,EAuB3C,OArBKpC,IAAGgnB,QAAWhnB,GAAGiW,kBAAkBiD,eAAkBmJ,EAOrDriB,GAAGgT,KAAK,WAEL,GAAIumC,GAASQ,EAAOzB,eAAe96B,EAAMxc,EAAMqhB,GAAM,EAEjDk3B,IAAUA,EAAOzqC,eAAgB9O,IAAG4a,UACpC2+B,EAAOzqC,KAAKiM,SAASb,KAAK2/B,EAAcvqC,QAASuqC,EAAcrqC,UAG/DpN,EAAIib,EAAK,4BAA6B,SACtCw8B,EAAcrqC,YAEnBvN,SAjBH43C,EAAcrqC,UAEdpN,EAAI,iDAAmDib,EAAK,uFAC6B,UAiBtFw8B,GAKXf,qBAAsB,SAASz6B,GAC3B,YAEA,IAAI06B,GAAgB16B,EAAK06B,cACrBje,EAAczc,EAAKyc,YACnBkf,EAAgB37B,EAAK26B,OAIzB,OAAKle,IAAgBie,EAQhBA,GAKD/4C,GAAG6J,QAAQW,OAAO23B,KAAKniC,GAAGuyC,SAAS/wC,UAAUy0C,wBAAyB8C,IAAkB,EAClE,eAAlBA,EACO/4C,GAAGiW,kBAAkBwD,aAAes/B,EAAgBje,EAGxDie,EATAje,EARe,eAAlBkf,EACO,YAEJA,GAqBff,SAAU,SAAS16B,EAAc07B,GAC7B,YAEA,IAAIC,GAAa37B,EAAavJ,YAAY,KACtCmlC,EAAcF,EAAwB72C,MAAQ,YAC9C42C,EAAgBC,EAAwBjB,QACxCoB,EAAa,GACbC,EAAYr6C,GAAG6U,aAAa0J,GAC5B+7B,EAAgB,EAmBpB,OAjBIL,GAAwBj5C,MAAQi5C,EAAwBj5C,KAAKyK,OAAOpH,SACpEi2C,EAAgB,KAAOL,EAAwBj5C,KAAO,KAGtDk5C,GAAc,GACdE,EAAa77B,EAAatJ,OAAO,EAAGilC,GAEhCF,IAAkBG,IAClBE,EAAYF,EAAYvwC,MAAM,KAAK,IAGvCwwC,GAAcE,EAAgB,IAAMD,GAGpCD,EAAa77B,EAAe+7B,EAGzBF,GAIX/B,gBAAiB,SAASnd,GACtB,YAIA,OAFAA,GAAQl7B,GAAGwG,UAAW00B,GAEfA,EAAMqf,KAAK,SAASC,EAAGC,GAC1B,MAAID,GAAE32B,QAAU42B,EAAE52B,QACP,EAEP22B,EAAE32B,QAAU42B,EAAE52B,SACP,EAEJ,KAIfq1B,qBAAsB,SAAS76B,EAAMq8B,GACjC,YAEA,IAAI12C,GAAO/B,KACP8hB,EAAuB1F,EAAK0F,qBAC5B3hB,EAAMic,EAAKjc,IACXyhB,EAAUxF,EAAKwF,QACfgX,EAASxc,EAAKwc,OACdz3B,EAAOib,EAAKjb,KACZsF,EAAU2V,EAAK3V,QACfywC,EAAa96B,EAAK86B,WAClBle,EAAc5c,EAAK4c,aAAmC,eAApByf,EAAWt3C,MAAkC,eAATA,EACtEy2C,EAAgB,GAAI75C,IAAGoP,QACvBurC,EAAiB,GAAI36C,IAAGm7B,eAAe/4B,GACvCoG,EAAS2E,SAASC,cAAc,SA8BpC,OA5BAhL,GAAI,6CAA+Cs4C,EAAW15C,MAE9D25C,EAAep2B,SAASm2B,EAAYlyC,GAASqb,QAASA,EAASgX,OAAQA,EAAQ9W,qBAAsBA,IAAuB7J,KAAK,WAC7H,GAAI0gC,GAAqBpyC,EAAOI,UAAUxF,EAAMsF,GAC5CmyC,EAAgB,WACZz4C,EAAI,yCAA2Cs4C,EAAW15C,KAC1D,IAAI8N,GAAO9O,GAAG2I,cAAciyC,EAC5Bf,GAAcvqC,QAAQR,GAG1BmsB,GACAj3B,EAAK82C,kBAAkBJ,EAAYE,EAAoBx4C,GAAK8X,KAAK,SAAS6gC,GACtEH,EAAqBG,EACrBF,KAEJ,WACIz4C,EAAI,wFAAyF,SAC7Fy4C,MAIJA,KAEL,WACCz4C,EAAI,iDAAmDs4C,EAAW15C,KAAM,SACxE64C,EAAcrqC,QAAQ2pC,KAGnBU,GAIXiB,kBAAmB,SAASE,EAAeJ,EAAoBx4C,GAC3D,YAEA,IAAI64C,GAAS,GAAI/rC,YACbgsC,EAAkB,GAAIl7C,IAAGoP,QACzB+rC,EAAuB,EAc3B,OAZAF,GAAO5rC,OAAS,WACZ8rC,EAAuBF,EAAO5zC,OAC9B6zC,EAAgB5rC,QAAQtP,GAAGo7C,aAAahM,QAAQ+L,EAAsBP,KAG1EK,EAAO1rC,QAAU,WACbnN,EAAI,mBAAqB44C,EAAch6C,KAAO,2DAA4D,SAC1Gk6C,EAAgB1rC,WAGpByrC,EAAOI,cAAcL,GAEdE,GAGXI,eAAgB,SAASzyC,GACrB,YAEA,IAAIE,GAAYE,EAAYH,EAAaE,CAsBzC,OAlBID,GADAF,EAAQe,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKjB,EAAQe,MAAM,KAAK,IAGxBG,UAAUlB,EAAQe,MAAM,KAAK,IAI9CX,EAAaJ,EAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBd,EAAc,GAAIkB,aAAYjB,EAAW1E,QACzC2E,EAAW,GAAIiB,YAAWnB,GAC1B9I,GAAGY,KAAKmI,EAAY,SAASnH,EAAKsI,GAC9BlB,EAASpH,GAAOsI,EAAUC,WAAW,KAGlClI,KAAKs5C,YAAYzyC,EAAaG,IAGzCsyC,YAAa,SAASl7C,EAAMoI,GACxB,YAEA,IAAIU,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOpJ,GACZmJ,EAAYE,QAAQjB,IAGpB,GAAIkB,OAAMtJ,IAAQ+C,KAAMqF,OChZ3CzI,GAAGo7C,aAAe,WAGjB,GAAIA,KA+KD,OA7KAA,GAAaI,QAAU;AAMvBJ,EAAaK,SAAW,SAASvuC,GAE7B,GACIwuC,GAAMC,EACNC,EAAMC,EAAMC,EAFZC,EAAS,GACGC,EAAO,GACDC,EAAO,GACzBpoC,EAAI,CAER,GACI6nC,GAAOxuC,EAAM2G,KACb8nC,EAAOzuC,EAAM2G,KACbmoC,EAAO9uC,EAAM2G,KAEb+nC,EAAOF,GAAQ,EACfG,GAAgB,EAAPH,IAAa,EAAMC,GAAQ,EACpCG,GAAgB,GAAPH,IAAc,EAAMK,GAAQ,EACrCC,EAAc,GAAPD,EAEHE,MAAMP,GACPG,EAAOG,EAAO,GACNC,MAAMF,KACdC,EAAO,IAGVF,EAASA,EACN95C,KAAKu5C,QAAQ57C,OAAOg8C,GACpB35C,KAAKu5C,QAAQ57C,OAAOi8C,GACpB55C,KAAKu5C,QAAQ57C,OAAOk8C,GACpB75C,KAAKu5C,QAAQ57C,OAAOq8C,GACvBP,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SACvBpoC,EAAI3G,EAAM7I,OAEnB,OAAO03C,IAGXX,EAAahM,QAAU,SAAS+M,EAAgBC,GAE5C,GAAIC,GAAuB,yBAE3B,KAAKF,EAAe94C,MAAMg5C,GAEzB,MAAOD,EAGR,IAAIE,GAAWr6C,KAAKs6C,SAASJ,EAAel1C,QAAQo1C,EAAsB,KACtEG,EAAWv6C,KAAKw6C,eAAeH,GAE/BzkB,EAAQ51B,KAAKy6C,iBAAiBN,EAAmBI,EAErD,OAAOH,GAAuBp6C,KAAKw5C,SAAS5jB,IAKhDujB,EAAasB,iBAAmB,SAASN,EAAmBI,GAEpD,GAAIG,GAAY16C,KAAK26C,aAAaJ,GAC9BK,EAAgB56C,KAAK66C,WAAWV,EAAmBO,GACnDI,EAAU,GAAI9yC,YAAW4yC,EAE7B,OAAOE,IAIf3B,EAAawB,aAAe,SAASJ,GAG7B,IAAK,GADDQ,GACKC,EAAI,EAAGA,EAAIT,EAASn4C,OAAQ44C,IAGjC,GADAD,EAAMR,EAASS,GACD,KAAVD,EAAI,GAAsB,KAAVA,EAAI,GAEpB,MAAOA,EAGf,WAIR5B,EAAa0B,WAAa,SAASV,EAAmBO,GAE9C,GAAIO,GAAYd,EAAkBn1C,QAAQ,0BAA2B,IACjEk2C,EAAMl7C,KAAKs6C,SAASW,GACpBE,EAAgBD,EAAItzC,QAAQ,IAAI,GAChCwzC,EAAMF,EAAIr9C,MAAM,EAAGs9C,GACnBE,EAAMH,EAAIr9C,MAAMs9C,GAChBG,EAAQF,CAIb,OAFCE,GAAQA,EAAMnqC,OAAOupC,GACrBY,EAAQA,EAAMnqC,OAAOkqC,IAM7BlC,EAAaqB,eAAiB,SAASe,GAKnC,IAHA,GAAIC,GAAO,EACPjB,OAGJ,CACI,GAA2B,KAAvBgB,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAAW,KACjE,IAA2B,KAAvBD,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAElDA,GAAQ,MAGZ,CACI,GAAIp5C,GAAmC,IAA1Bm5C,EAAcC,EAAO,GAAWD,EAAcC,EAAO,GAC9DC,EAAWD,EAAOp5C,EAAS,EAC3B24C,EAAMQ,EAAc19C,MAAM29C,EAAMC,EACpClB,GAAS16C,KAAKk7C,GACdS,EAAOC,EAEX,GAAID,EAAOD,EAAcn5C,OAAQ,MAGrC,MAAOm4C,IAKXpB,EAAamB,SAAW,SAASrvC,GAE7B,GACIwuC,GAAMC,EACNC,EAAMC,EAAMC,EADAE,EAAO,GACDC,EAAO,GACzBpoC,EAAI,EACJspC,KAGAQ,EAAa,qBACjB,IAAIA,EAAWz8C,KAAKgM,GAChB,KAAM,IAAI/G,OAAM,uHAGpB+G,GAAQA,EAAMjG,QAAQ,sBAAuB,GAE7C,GACI20C,GAAO35C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCgoC,EAAO55C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCioC,EAAO75C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCooC,EAAOh6C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MAEzC6nC,EAAQE,GAAQ,EAAMC,GAAQ,EAC9BF,GAAgB,GAAPE,IAAc,EAAMC,GAAQ,EACrCE,GAAgB,EAAPF,IAAa,EAAKG,EAE3BkB,EAAIr7C,KAAK45C,GAEG,IAARI,GACDqB,EAAIr7C,KAAK65C,GAEA,IAARM,GACDkB,EAAIr7C,KAAKk6C,GAGZN,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SAEvBpoC,EAAI3G,EAAM7I,OAEnB,OAAO84C,IAIJ/B,KC7KXp7C,GAAGs7B,cAAgB,SAAS1oB,EAAUyS,GAClC,YAEA,IAAIu4B,MACAC,EAAc,EACdC,EAAY,EAEZC,GAAiB,EACjBC,GAAgB,EAChBC,EAAgB,SAAS7wB,EAAQC,GACzBD,IAAW2wB,GAAkB1wB,IAAU2wB,GACvCprC,EAASwa,EAAQC,GAGrB0wB,EAAiB3wB,EACjB4wB,EAAgB3wB,GAQpB6wB,EAAmB,SAAS7pB,EAAQ8pB,GAChC,GAAIC,IAAO,CASX,OAPAp+C,IAAGY,KAAKyzB,EAAQ,SAASzyB,EAAKy8C,GAC1B,GAAIr+C,GAAG6J,QAAQs0C,EAAWE,IAAa,EAEnC,MADAD,IAAO,GACA,IAIRA,GAGX3wB,EAAW,SAASpQ,GAChBihC,EAAoBjhC,GAAI,GAAI,SACrBugC,GAAgBvgC,IAG3BiX,EAAgB,SAASF,EAAYC,EAAQ8pB,IACnB,IAAlB9pB,EAAOhwB,QAAgB65C,EAAiB7pB,EAAQ8pB,MAChDF,EAAcH,EAAWA,GACzB77C,KAAK8a,UAIbwhC,EAAQ,SAASlhC,GACb,GAAImB,GAAO6G,EAAQhI,EAGfmB,GAAO,IACP8/B,EAAoBjhC,EAAI,EAAGmB,GAC3Bo/B,EAAgBvgC,IAAO+P,OAAQ,EAAGC,MAAO7O,KAYjD8/B,EAAsB,SAASjhC,EAAImhC,EAAWC,GAC1C,GAAIC,GAAYd,EAAgBvgC,GAAMugC,EAAgBvgC,GAAI+P,OAAS,EAC/DuxB,EAAWf,EAAgBvgC,GAAMugC,EAAgBvgC,GAAIgQ,MAAQ,CAE7DmxB,MAAc,GAAMC,KAAa,GACjCZ,GAAea,EACfZ,GAAaa,IAGTH,IACAX,GAAeW,EAAYE,GAE3BD,IACAX,GAAaW,EAAWE,IAIhCV,EAAcJ,EAAaC,GAGnC99C,IAAGwG,OAAOvE,MAENqyB,cAAeA,EAGf3V,eAAgB,SAAStB,EAAI2B,EAAWD,GAChCA,IAAc/e,GAAG2d,OAAOuC,UAAYnB,IAAc/e,GAAG2d,OAAOqC,SAC5DyN,EAASpQ,GAEJ0B,IAAc/e,GAAG2d,OAAOW,YAC7BigC,EAAMlhC,IAKd4X,qBAAsB,SAAS5X,EAAI+P,EAAQC,GACvCixB,EAAoBjhC,EAAI+P,EAAQC,GAChCuwB,EAAgBvgC,IAAO+P,OAAQA,EAAQC,MAAOA,IAIlD6J,UAAW,SAAS7Z,GAChBkhC,EAAMlhC,IAGVN,MAAO,WACH6gC,KACAC,EAAc,EACdC,EAAY,MCzHxB99C,GAAGoqB,aAAe,SAASnP,GACvB,YAYA,SAAS2jC,GAAQ1zC,GACb,MAAOA,GAAK9H,MACwB,IAAhC8H,EAAK9H,KAAKyG,QAAQ,UAG1B,QAASg1C,KACLC,EAAqB9+C,GAAGhB,EAAQqrB,eAAellB,OAAO,QAAS,SAASuxB,GACpE,GAAIqoB,GAAgBroB,EAAMqoB,aAEtBA,IACA/+C,GAAGY,KAAKm+C,EAAclxC,MAAO,SAASjM,EAAKsJ,GACvC,GAAI0zC,EAAQ1zC,GAAO,CACf,GAAI4D,GAAO5D,EAAK8zC,WAChBhgD,GAAQ2B,UAAU4pB,cAAczb,QAOpD,QAASmwC,KACDH,GACAA,IAhCR,GAAI9/C,GAAS8/C,CAEb9/C,IACIqrB,cAAe,KACf1pB,WACIyB,IAAK,SAASC,EAAS+H,KACvBmgB,cAAe,SAASzb,OA8BhC9O,GAAGwG,OAAOxH,EAASic,GACnB4jC,IAEA7+C,GAAGwG,OAAOvE,MACN8a,MAAO,WACHkiC,QCpCZj/C,GAAGyxB,YAAc,SAASzyB,EAASkgD,EAAa98C,GAC5C,YAgCA,SAAS+8C,GAAqBC,GACtBA,EAAO92C,aAAa,YACpBtE,EAAK8tB,YAAcstB,EAAO92C,aAAa,WAM/C,QAAS+2C,GAAaD,EAAQE,GAC1B,QAAIF,EAAOG,gBAAkBH,EAAOG,mBAChCn9C,EAAI,yDAA0D,aAC9Dk9C,MAQR,QAASE,GAAoBJ,GACzB,GAAIE,GAAeF,EAAOK,MAG1Bz/C,IAAGo/C,GAAQj6C,OAAO,SAAU,SAASuxB,GACjCA,EAAQA,GAASttB,OAAOstB,MAEpBA,EAAMtkB,eACNskB,EAAMtkB,iBAGNskB,EAAMpkB,aAAc,EAGxB+sC,EAAaD,EAAQE,IAAiBJ,MAK1CE,EAAOK,OAAS,WACZJ,EAAaD,EAAQE,IAAiBJ,KAM9C,QAASQ,GAAgBN,GAarB,MAZIA,KACIp/C,GAAGoL,SAASg0C,KACZA,EAASjyC,SAAS85B,eAAemY,IAGjCA,IACAh9C,EAAI,8BACJ+8C,EAAqBC,GACrB1kB,GAAmB8kB,EAAoBJ,KAIxCA,EAzFX,GAAIp7C,GAAQ/B,KACRy4B,EAAkB17B,EAAQ07B,gBAC1B0kB,EAASpgD,EAAQ0D,QACjBkvB,EAAa5yB,EAAQ4yB,UAGzB5xB,IAAGwG,OAAOvE,MAIN6vB,YAAa,KAIbD,cAAeD,EAGfF,gBAAgB,EAGhBC,sBAAuB,WAEnB,MAAc,OAAVytB,EACO,KAGJp7C,EAAK27C,UAAUP,MAkE9BA,EAASM,EAAgBN,GACzBn9C,KAAKyvB,iBAAmB0tB,GAG5Bp/C,GAAGwG,OAAOxG,GAAGyxB,YAAYjwB,WAGrBm+C,UAAW,SAAStrC,GAChB,YACA,IAAIf,MACAssC,EAAoB,SAASx8C,GACzB,GAAIy8C,IACA,SACA,QACA,QACA,SAGJ,OAAO7/C,IAAG6J,QAAQg2C,EAAiBz8C,EAAKrD,eAAiB,GAE7D+/C,EAAkB,SAAS18C,GACvB,MAAOpD,IAAG6J,SAAS,WAAY,SAAUzG,EAAKrD,gBAAkB,GAEpEggD,EAAc,SAAS37C,GACnB,SAAI07C,EAAgB17C,EAAGhB,OAAUgB,EAAG47C,UAI7B57C,EAAGiS,UAAsC,WAA1BjS,EAAGhB,KAAKrD,eAElCkgD,EAAc,SAASC,GACnB,GAAIv1C,GAAQ,IASZ,OAPA3K,IAAGY,KAAKZ,GAAGkgD,GAAQx4C,WAAY,SAAS9F,EAAK+F,GACzC,GAAoC,WAAhCA,EAAMmF,QAAQ/M,eAA8B4H,EAAMw4C,SAElD,MADAx1C,GAAQhD,EAAMgD,OACP,IAIRA,EAmBf,OAhBA3K,IAAGY,KAAKyT,EAAK+rC,SAAU,SAASx+C,EAAKwC,GACjC,IAAKpE,GAAGwM,QAAQpI,GAAI,IAAsC,aAA7BA,EAAG0I,QAAQ/M,gBACpC6/C,EAAkBx7C,EAAGhB,OACpB28C,EAAY37C,IAIZ,GAAiC,WAA7BA,EAAG0I,QAAQ/M,gBAA+BggD,EAAY37C,GAAK,CAChE,GAAIuG,GAAQs1C,EAAY77C,EAEV,QAAVuG,IACA2I,EAAIlP,EAAGpD,MAAQ2J,QANnB2I,GAAIlP,EAAGpD,MAAQoD,EAAGuG,QAWnB2I,KCzJftT,GAAGilC,YAAcjlC,GAAGilC,gBACpBjlC,GAAGilC,YAAYyB,kBAAoB,SAAS1nC,EAASkhC,GACjD,YAUA,SAASmgB,GAAqBhjC,EAAI2pB,GAG9B,GAAItT,GAAU4sB,EAAKC,CAGnB,KAEID,EAAMtZ,EAAOe,iBAAmBf,EAAOwZ,cAAcrzC,SACrDozC,EAAYD,EAAIhZ,KAAK50B,UAErBtQ,EAAI,yCACJA,EAAI,eAAiBm+C,GAEjBA,GAAaA,EAAUl9C,MAAM,YAC7Bk9C,EAAYD,EAAIhZ,KAAK1/B,WAAWA,WAAW64C,WAG/C/sB,EAAW3C,EAAQ2W,mBAAmB6Y,GAE1C,MAAOp+C,GACHC,EAAI,wDAA0DD,EAAME,QAAU,IAAK,SACnFqxB,GAAYpkB,SAAS,GAGzB,MAAOokB,GAMX,QAASgtB,GAAWrjC,EAAI2pB,GACpB,GAAIxnC,GAASR,EAAQ0qB,YAAY3E,IAAI1H,GACjC+L,EAA0C,QAAjCpqB,EAAQoqB,OAAOrpB,cAA0B,MAAQ,OAC1D+gB,EAAW9hB,EAAQ2qB,cAAc5E,IAAI1H,GACrCrc,EAAOmiB,EAAQ9F,EAKnB,OAHA7d,GAAOR,EAAQwqB,UAAY5D,EAAQvI,GACnC7d,EAAOR,EAAQu5B,eAAiBv3B,EAEzB+vB,EAAQkX,oBACX7e,OAAQA,EACRtI,SAAUA,EACVthB,OAAQA,EACRi5B,aAAcz5B,EAAQy5B,aACtByP,WAAYlB,EAAOhmC,OArD3B,GAAI+vB,GAAU9uB,KACVkhB,EAAU+c,EAAM/c,QAChByC,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,GAsDhBH,MAAK0iC,WAAa,SAAStnB,GACvB,GAGIhJ,GAHAnH,EAAQ6jB,EAAQtU,SAASY,GACzB2pB,EAASjW,EAAQiX,cAAc3qB,GAC/BlO,EAAU,GAAInP,IAAGoP,OA8BrB,OA3BAiF,GAAOqsC,EAAWrjC,EAAI2pB,GACtB3yB,EAAKE,YAAYrH,GAEjB6jB,EAAQ8W,iBAAiBb,EAAQ,SAAS2Z,GACtCv+C,EAAI,gBAEJ,IAAIsxB,GAAWitB,EAAsBA,EAAsBN,EAAqBhjC,EAAI2pB,EAEpFjW,GAAQ4W,iBAAiBtqB,GAGpBre,EAAQ4qB,KAAKoI,UACdhyB,GAAGgnC,GAAQjhC,SAGX2tB,EAASpkB,QACTH,EAAQG,QAAQokB,GAGhBvkB,EAAQK,QAAQkkB,KAIxBtxB,EAAI,8BAAgCib,GACpChJ,EAAKorC,SACLz/C,GAAGqU,GAAMtO,SAEFoJ,GAGXnP,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAG0mC,mBACnB1nC,SACI6nC,OAAQ7nC,EAAQ4qB,KAAKoI,SACrBtF,UAAW1tB,EAAQ0tB,WAGvBwT,OACIzS,SAAUzuB,EAAQyuB,SAClBtK,QAASA,EACTyC,QAASA,EACTxjB,IAAKA,OC5GjBpC,GAAGilC,YAAcjlC,GAAGilC,gBACpBjlC,GAAGilC,YAAYmD,iBAAmB,SAAS/pB,EAAM6hB,GAC7C,YAEA,IAAInP,GAAU9uB,KACVkhB,EAAU+c,EAAM/c,QAChBkC,EAAU6a,EAAM7a,QAChBO,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,IACZw+C,EAAYviC,EAAKma,gBAAkBna,EAAKoa,aAExCooB,EAA4B,SAASxjC,EAAI7d,EAAQyuB,GAC7C,GAAIzP,GAAO6G,EAAQhI,GACfrc,EAAOmiB,EAAQ9F,EAEnB7d,GAAO6e,EAAK5F,SAASshB,WAAWC,WAAa/L,EAAUqc,KACvD9qC,EAAO6e,EAAK5F,SAASshB,WAAWE,gBAAkBhM,EAAU5f,MAC5D7O,EAAO6e,EAAK5F,SAASshB,WAAWG,WAAajM,EAAUzP,KACvDhf,EAAO6e,EAAK5F,SAASshB,WAAWK,YAAcnM,EAAUsc,MACxD/qC,EAAO6e,EAAKqa,mBAAqBla,EAM7BoiC,IACAphD,EAAO6e,EAAKka,eAAiBv3B,IAIrC8/C,EAAyB,GAAI9gD,IAAGilC,YAAY8b,4BACxCn3B,KAAMvL,EAAKuL,KACX9I,SAAUzC,EAAK5F,SAASnJ,QAAQwR,SAChC1e,IAAKA,IAGT4+C,EAAiC,SAAS3jC,EAAI3G,GAC1C,GAAIvH,GAAU,GAAInP,IAAGoP,OAerB,OAbAsH,GAAI4mB,mBAAqB,WACrB,GAAuB,IAAnB5mB,EAAIsnB,WAAkB,CACtB,GAAI32B,GAAS45C,EAAwB5jC,EAAI3G,EAErCrP,GAAOiI,QACPH,EAAQG,QAAQjI,EAAOqsB,SAAUhd,GAGjCvH,EAAQK,QAAQnI,EAAOqsB,SAAUhd,KAKtCvH,GAGX+xC,EAA0B,SAAS7jC,GAC/B,GAAI7d,GAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9Brc,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,EAOnB,OALA7d,GAAO6e,EAAKmL,UAAY5D,EAAQvI,GAChC7d,EAAO6e,EAAKka,eAAiBv3B,EAC7BxB,EAAO6e,EAAKqa,mBAAqBla,EACjChf,EAAO6e,EAAK5F,SAASshB,WAAWK,YAAcrJ,EAAQgS,gBAAgB1lB,GAE/D7d,GAGX2hD,EAAwB,SAASzqC,EAAKgd,GAClC,MAAO1zB,IAAG6J,SAAS,IAAK,IAAK,IAAK,IAAK,KAAM6M,EAAIiH,QAAU,IACtD+V,EAASpkB,SACVokB,EAAS3W,OAGjBkkC,EAA0B,SAAS5jC,EAAI3G,GACnC,GAAIgd,EAOJ,OALAtxB,GAAI,sCAAwCib,GAC5Cjb,EAAI,kBAAoBsU,EAAIwhC,cAE5BxkB,EAAW0tB,GAAc,EAAM1qC,IAG3BpH,SAAU6xC,EAAsBzqC,EAAKgd,GACrCA,SAAUA,IAKlB0tB,EAAgB,SAAS5zC,EAAQkJ,GAC7B,GAAIgd,KAEJ,KACItxB,EAAIpC,GAAG0L,OAAO,4CAA6CgL,EAAIiH,OAAQjH,EAAIwhC,eAC3ExkB,EAAW1zB,GAAGwU,UAAUkC,EAAIwhC,cAEhC,MAAO/1C,GACHqL,GAAUpL,EAAI,qDAAuDD,EAAME,QAAU,IAAK,SAG9F,MAAOqxB,IAGX2tB,EAA4B,SAAShkC,GACjC,GAAIlO,GAAU,GAAInP,IAAGoP,OAcrB,OAZA0xC,GAAuBQ,SACfjkC,EACA0T,EAAQgZ,WAAW1sB,GACnB6jC,EAAwB7jC,GACxBgB,EAAKoL,cAAc1E,IAAI1H,IAE1BnD,KAAK,SAASxD,GACXvH,EAAQG,QAAQ8xC,GAAc,EAAO1qC,GAAMA,IAC5C,SAASA,GACRvH,EAAQK,QAAQ4xC,GAAc,EAAO1qC,GAAMA,KAG5CvH,GAGXoyC,EAA8B,SAAS/hD,EAAQkX,EAAKtI,EAAYiP,GAC5D,GAAInJ,GAAW,GAAI5G,UACf8b,EAAS/K,EAAK+K,OACdtI,EAAWzC,EAAKsL,cAAc5E,IAAI1H,GAClCrc,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,EAuBnB,OArBA7d,GAAO6e,EAAKmL,UAAY5D,EAAQvI,GAChC7d,EAAO6e,EAAKka,eAAiBv3B,EAEzB4/C,IACAphD,EAAO6e,EAAKqa,mBAAqBla,GAIhCH,EAAKoa,eACDmoB,IACDphD,EAAO6e,EAAKqO,WAAa1rB,GAE7B8f,EAAW9gB,GAAGqT,QAAQ7T,EAAQshB,IAGlCpK,EAAI+mB,KAAKrU,EAAQtI,GAAU,GAEvBzC,EAAKuL,KAAKoI,UAAY3T,EAAKuL,KAAK6Q,kBAChC/jB,EAAIC,iBAAkB,GAGtBiqC,GACIviC,EAAKoa,cACLz4B,GAAGiU,aAAazU,EAAQ0U,GAG5BA,EAASzK,OAAO4U,EAAKqO,UAAWte,GACzB8F,GAGJ9F,GAGXozC,EAAmB,SAASnkC,EAAI3G,GAC5B,GAAI+qC,GAAepjC,EAAKoL,cAAc1E,IAAI1H,GACtCjP,EAAa2iB,EAAQ1M,QAAQhH,EAEjC3G,GAAI4nB,iBAAiB,SAAU,oBAC/B5nB,EAAI4nB,iBAAiB,mBAAoB,kBACzC5nB,EAAI4nB,iBAAiB,gBAAiB,YAEjCsiB,IACDlqC,EAAI4nB,iBAAiB,eAAgB,4BAErC5nB,EAAI4nB,iBAAiB,cAAelwB,EAAWhL,OAGnDpD,GAAGY,KAAK6gD,EAAc,SAASzgD,EAAMZ,GACjCsW,EAAI4nB,iBAAiBt9B,EAAMZ,KAIvCJ,IAAGwG,OAAOvE,MACNmhC,YAAa,SAAS/lB,EAAI2jB,EAAUzG,GAChC,GAGIprB,GAASuyC,EAAQliD,EAHjByuB,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCtqB,EAAMqa,EAAQgZ,WAAW1sB,EAAI2jB,EACtB3b,GAAQhI,EAgBnB,OAbAlO,GAAU6xC,EAA+B3jC,EAAI3G,GAC7Cqa,EAAQqa,yBAAyB/tB,EAAI2jB,EAAU/S,EAAUzP,MACzDhf,EAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9BwjC,EAA0BxjC,EAAI7d,EAAQyuB,GAElCsM,IACA/6B,EAAO6e,EAAK9E,OAAOwgB,WAAWQ,WAAY,GAG9CmnB,EAASH,EAA4B/hD,EAAQkX,EAAKuX,EAAUnf,KAAMuO,GAClEmkC,EAAiBnkC,EAAI3G,GACrBA,EAAIinB,KAAK+jB,GAEFvyC,GAGXw1B,WAAY,SAAStnB,GACjB,GACIlO,GAASuH,EAAKlX,EAAQkiD,EADtBtzC,EAAa2iB,EAAQ1M,QAAQhH,EAWjC,OARA3G,GAAMqa,EAAQgZ,WAAW1sB,GACzB0T,EAAQqa,yBAAyB/tB,GACjClO,EAAU6xC,EAA+B3jC,EAAI3G,GAC7ClX,EAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9BqkC,EAASH,EAA4B/hD,EAAQkX,EAAKtI,EAAYiP,GAC9DmkC,EAAiBnkC,EAAI3G,GACrBA,EAAIinB,KAAK+jB,GAEFvyC,KAIfnP,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGooC,kBACnBppC,QAASgB,GAAGwG,QAAQ7G,UAAW,eAAgB0e,GAC/C6hB,MAAOlgC,GAAGwG,QAAQqe,YAAaxG,EAAKsL,cAAc5E,KAAMmb,MAG5DlgC,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OACIuxB,eAAgB,SAASjkB,GACrB,MAAIgB,GAAK5F,SAASnJ,QAAQwR,SACfugC,EAA0BhkC,GAG1BtN,EAAOuxB,eAAejkB,EAAIrd,GAAGgT,KAAKouC,EAAen/C,MAAM,SCvOlFjC,GAAGilC,YAAY8b,2BAA6B,SAAS9lC,GACjD,YAEA,IAAImxB,GACAhjB,EAAS,OACTpqB,GACI4qB,MACIqI,UAAU,EACVD,UAAU,EACVyI,iBAAiB,GAErB3Z,SAAU,KACV1e,IAAK,SAASuJ,EAAKvB,MAEvBu3C,KACAC,GACI78B,IAAK,SAAS1H,GACV,MAAOre,GAAQ8hB,UAI3B9gB,IAAGwG,OAAOxH,EAASic,GAEnBmxB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAevV,GACfA,OAAQA,EACRO,cAAei4B,EACfrjB,oCAAoC,EACpC3U,KAAM5qB,EAAQ4qB,KACdxnB,IAAKpD,EAAQoD,IACbmrB,WAAY,SAASlQ,EAAI3G,EAAKuT,GAC1B,GAAI9a,GAAUwyC,EAAStkC,SAEhBskC,GAAStkC,GAEZ4M,EACA9a,EAAQK,QAAQkH,GAGhBvH,EAAQG,QAAQoH,OAK5B1W,GAAGwG,OAAOvE,MACNq/C,SAAU,SAASjkC,EAAI3G,EAAKlX,EAAQ0nB,GAChC,GAAI/X,GAAU,GAAInP,IAAGoP,OAWrB,OATApQ,GAAQoD,IAAI,0CAA4Cib,GAExDskC,EAAStkC,GAAMlO,EAEfi9B,EAAUnN,cAAc5hB,GACnBiiB,WAAW9/B,GACXigC,YAAYvY,GACZyW,KAAKjnB,GAEHvH,MCjEnBnP,GAAGyE,YAAc,SAASwW,GACtB,YAoBA,SAAS4mC,GAAmBz/B,EAAO0/B,GAE/B,GAAIC,GAAexgD,MAAMC,UAAU1B,MAAM2B,KAAK2gB,EAE9CpjB,GAAQ2B,UAAUqhD,QAAQ,WAAa5/B,EAAM/d,OAAS,mBACtDy9C,EAAeG,cAAa,GAC5BjjD,EAAQ2B,UAAUuhD,+BAA+BH,EAAcD,EAAeK,cAGlF,QAASC,GAAiB7mB,GACtB,GAAI8mB,GAAoB,GAAIriD,IAAGoP,OAoD/B,OAlDImsB,GAAMvvB,OACNuvB,EAAMlZ,KAAK,SAASA,GAChB,GAAIrhB,GAAOu6B,EAAMv6B,KACbshD,EAAW/mB,EAAM+mB,SACjBC,EAAwBD,EAASz4C,QAAQ7I,EAG7CshD,GAAWA,EAASrtC,OAAO,EAAGstC,GAGH,MAAvBD,EAAS1iD,OAAO,KAChB0iD,EAAWA,EAASrtC,OAAO,IAG/BoN,EAAKmgC,OAASF,EACdG,EAAa3gD,KAAKugB,GAClBggC,EAAkB/yC,WAEtB,SAASozC,GACL1jD,EAAQ2B,UAAUqhD,QAAQ,oBAAsBzmB,EAAM+mB,SAAW,sBAAwBI,EAAUpwB,KAAO,IAAK,SAC/G+vB,EAAkB7yC,YAGjB+rB,EAAMonB,aACXC,EAAoBrnB,GAAOrhB,KACvB,SAAwBkD,GACpB,GAAIylC,GAAczlC,EAAQ/Y,MAE1BrE,IAAGY,KAAKwc,EAAS,SAASxb,EAAK25B,GAC3B6mB,EAAiB7mB,GAAO5gB,KAAK,WACzBkoC,GAAe,EAEK,IAAhBA,GACAR,EAAkB/yC,cAKzB8N,EAAQ/Y,QACTg+C,EAAkB/yC,WAI1B,SAAqBozC,GACjB1jD,EAAQ2B,UAAUqhD,QAAQ,oBAAsBzmB,EAAM+mB,SAAW,sBAAwBI,EAAUpwB,KAAO,IAAK,SAC/G+vB,EAAkB7yC,YAKvB6yC,EAIX,QAASO,GAAoBrnB,EAAO0f,EAAQ6H,EAAcC,GACtD,GAAI5zC,GAAU4zC,GAAmB,GAAI/iD,IAAGoP,QACpC4zC,EAAY/H,GAAU1f,EAAM0nB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqB9lC,GACjB,GAAI+lC,GAAaL,EAAeA,EAAa1vC,OAAOgK,GAAWA,CAE3DA,GAAQ/Y,OACRwnB,WAAW,WACP+2B,EAAoBrnB,EAAOynB,EAAWG,EAAYh0C,IACnD,GAGHA,EAAQG,QAAQ6zC,IAIxBh0C,EAAQK,SAGLL,EAGX,QAASi0C,GAAmBx1C,EAAck0C,GACtC,GAAIuB,MACAC,EAA4B,GAAItjD,IAAGoP,OA4CvC,OA1CApQ,GAAQ2B,UAAU4iD,yBAClBzB,EAAeG,cAAa,GAExBr0C,EAAawU,MAAM/d,OAAS,IAAMrF,EAAQwkD,oBAC1CxkD,EAAQ2B,UAAUuhD,mCAClBljD,EAAQ2B,UAAU8iD,UAAU,oBAAqB,IACjD3B,EAAeG,cAAa,GAC5BqB,EAA0B9zC,YAG1BizC,KAEIziD,GAAG2N,sBAAsBC,GACzB5N,GAAGY,KAAKgN,EAAaC,MAAO,SAASjM,EAAKsJ,GACtC,GAAIqwB,GAAQrwB,EAAK4C,kBAEbytB,KAEIA,EAAMvvB,OACNy2C,EAAa3gD,KAAKoJ,EAAK8zC,aAIvBqE,EAAsBvhD,KAAKsgD,EAAiB7mB,GAAO5gB,KAAK,WACpD0oC,EAAsB7e,MACe,IAAjC6e,EAAsBh/C,QACtBi/C,EAA0Bh0C,gBAQ9CmzC,EAAe70C,EAAawU,MAGK,IAAjCihC,EAAsBh/C,QACtBi/C,EAA0Bh0C,WAI3Bg0C,EAGX,QAASI,GAAcC,GACnB,GAAIC,GAAW,GAAI5jD,IAAG6jD,gBAClBC,sBAAuBA,EACvBphD,QAASihD,EACTI,QAAS,SAAS1xC,GACdrS,GAAG2jD,GAAU58C,SAAS/H,EAAQstB,QAAQ03B,YACtC3xC,EAAE4xC,mBAENC,sBAAuB,SAAS7xC,GAC5BrS,GAAG2jD,GAAU38C,YAAYhI,EAAQstB,QAAQ03B,aAE7CG,OAAQ,SAAS9xC,GACb+wC,EAAmB/wC,EAAEzE,aAAcg2C,GAAU1pC,KACzC,WACI2nC,EAAmBY,EAAcmB,IAErC,WACI5kD,EAAQ2B,UAAUqhD,QAAQ,sEAAuE,aAcjH,OARA9lC,GAAexG,YAAY,WACvBkuC,EAASruC,YAGbvV,GAAG2jD,GAAUx7C,aAAai8C,IAA2BpkD,GAAG2jD,GAAU3+C,OAElEq/C,EAAgBviD,KAAK8hD,GAEdA,EAGX,QAASU,GAAWC,GAChB,GAAIC,EASJ,OAPAxkD,IAAGY,KAAK2jD,EAAU32C,aAAa62C,MAAO,SAAStkD,EAAKC,GAChD,GAAY,UAARA,EAEA,MADAokD,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBryC,GACxB,MAAIrS,IAAGwR,WACKa,EAAEsyC,cAGV3kD,GAAGoR,SACIiB,EAAE4qC,EAAI,GAAK5qC,EAAEuyC,EAAI,EAGb,IAARvyC,EAAE4qC,GAAmB,IAAR5qC,EAAEuyC,EAG1B,QAASC,KACL,GAAIC,GAAY9lD,EAAQuF,iBAEpBwgD,EAAqB,WACjBl5B,WAAW,WACP7rB,GAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAC7B5jD,GAAG4jD,GAAUz7C,aAAai8C,IAA2BpkD,GAAG4jD,GAAU5+C,OAClEhF,GAAG4jD,GAAU58C,YAAYhI,EAAQstB,QAAQ03B,eAE9C,IAGXhkD,IAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAC7B,GAAI9B,GAAiB4B,EAAcE,EAG/BkB,GAAUzgD,QAAUrE,GAAGiW,kBAAkB8C,UACzCmD,EAAe/W,OAAOgI,SAAU,YAAa,SAASkF,IAC7CyvC,EAAeG,gBAAkBqC,EAAWjyC,IAC7CrS,GAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAGzBA,YAAoBoB,cACpBhlD,GAAG4jD,GAAUz7C,aAAai8C,IAE1BpkD,GAAG4jD,GAAU39C,KAAKf,QAAS,gBAQnDgX,EAAe/W,OAAOgI,SAAU,YAAa,SAASkF,GAC9CqyC,EAAmBryC,IACnB0yC,MAOR7oC,EAAe/W,OAAOnF,GAAGmN,UAAUzF,WAAW,GAAI,aAAc,SAAS2K,GACrE0yC,MAGJ7oC,EAAe/W,OAAOgI,SAAU,OAAQ,SAASkF,GAC7CA,EAAED,iBACF2yC,MAGJ7oC,EAAe/W,OAAOgI,SAAU22C,EAAuBiB,GAnR3D,GAAI/lD,GACA8kD,EAAwB,eACxBM,EAAyB,mBACzBC,KACA5B,KACAvmC,EAAiB,GAAIlc,IAAGqV,cAE5BrW,IACIuF,oBACAi/C,oBAAoB,EACpBl3B,SACI03B,WAAY,MAEhBrjD,UAAW,GAAIX,IAAGyE,YAAY9D,WAGlCX,GAAGwG,OAAOxH,EAASic,GAAG,GAsQtB4pC,IAEA7kD,GAAGwG,OAAOvE,MACNgjD,mBAAoB,SAASviD,GACzB1D,EAAQuF,iBAAiBzC,KAAKY,GAC9BghD,EAAchhD,IAGlBwiD,eAAgB,SAASxiD,GACrB,GAAImR,GACAsxC,EAAMnmD,EAAQuF,gBAElB,KAAKsP,IAAKsxC,GACN,GAAIA,EAAItxC,KAAOnR,EACX,MAAOyiD,GAAIjmC,OAAOrL,EAAG,IAKjC0B,QAAS,WACL2G,EAAe3G,UACfvV,GAAGY,KAAKyjD,EAAiB,SAASziD,EAAKgiD,GACnCA,EAASruC,gBAMzBvV,GAAGyE,YAAY9D,UAAY,WACvB,YAEA,QACI4iD,uBAAwB,aACxBrB,+BAAgC,SAAS9/B,EAAOgjC,KAChD3B,UAAW,SAASnxB,EAAM+yB,GACtBrlD,GAAGoC,IAAI,2BAA6BkwB,EAAO,2BAA6B+yB,EAAiB,IAAK,UAElGrD,QAAS,SAAS3/C,EAAS+H,GACvBpK,GAAGoC,IAAIC,EAAS+H,MAK5BpK,GAAG6jD,eAAiB,SAAS5oC,GACzB,YAiBA,SAASqqC,KACL,MAAOtlD,IAAGoR,UAAapR,GAAGwR,WAAaxR,GAAGyR,UAG9C,QAAS8zC,GAAmBlzC,GAEnBmzC,IAGGF,EACAppC,EAAe/W,OAAOgI,SAAU,WAAY,SAASkF,GACjDA,EAAED,mBAGN8J,EAAe/W,OAAOgI,SAAU,WAAY,SAASkF,GAC7CA,EAAEzE,eACFyE,EAAEzE,aAAa63C,WAAa,OAC5BpzC,EAAED,oBAKdozC,GAAsB,GAI9B,QAASE,GAAgBrzC,GAGrB,IAAKrS,GAAGiW,kBAAkB8C,SACtB,OAAO,CAGX,IAAI4sC,GAAYC,EAAKvzC,EAAEzE,aAEvBi4C,EAAW7lD,GAAGoR,QAQd,OADAu0C,MAAa3lD,GAAG4Q,OAAQ5Q,GAAGiW,kBAAkB8C,WAAuC,SAArB6sC,EAAGE,cAC3DF,GAAMD,IAAeC,EAAGxjC,QAAWyjC,GAAYD,EAAGnB,MAAMh/C,UAAYmgD,EAAGnB,MAAMh/C,SAAS,UAGjG,QAASsgD,GAAoBC,GAIzB,MAHmB1lD,UAAf0lD,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiBj5C,SAASk5C,YAAY,SACtCD,EAAeE,UAAUtnD,EAAQ8kD,uBAAuB,GAAM,GAJlE,GAAIsC,EAOJ,IAAIh9C,OAAOm9C,YACP,IACIH,EAAiB,GAAIG,aAAYvnD,EAAQ8kD,uBAE7C,MAAOlM,GACHuO,QAIJA,IAGJh5C,UAASq5C,cAAcJ,GAG3B,QAASK,KACLvqC,EAAe/W,OAAOzC,EAAS,WAAY,SAAS2P,GAChD,GAAKqzC,EAAgBrzC,GAArB,CAMA,GAAIq0C,GAAS1mD,GAAG4Q,MAAQ5Q,GAAGiW,kBAAkB8C,SAAW,KAAO1G,EAAEzE,aAAak4C,aAC/D,UAAXY,GAAgC,aAAXA,EACrBr0C,EAAEzE,aAAa63C,WAAa,OAE5BpzC,EAAEzE,aAAa63C,WAAa,OAGhCpzC,EAAE4xC,kBACF5xC,EAAED,oBAGN8J,EAAe/W,OAAOzC,EAAS,YAAa,SAAS2P,GACjD,IAAK0zC,IAAuB,CACxB,IAAKL,EAAgBrzC,GACjB,MAEJrT,GAAQ+kD,QAAQ1xC,MAIxB6J,EAAe/W,OAAOzC,EAAS,YAAa,SAAS2P,GACjD,GAAKqzC,EAAgBrzC,GAArB,CAIArT,EAAQ23B,QAAQtkB,EAEhB,IAAIsyC,GAAgBx3C,SAASw5C,iBAAiBt0C,EAAEu0C,QAASv0C,EAAEw0C,QAEvD7mD,IAAGiC,MAAMwD,SAASk/C,IAItB3lD,EAAQklD,sBAAsB7xC,MAGlC6J,EAAe/W,OAAOzC,EAAS,OAAQ,SAAS2P,GAC5C,IAAK0zC,IAAuB,CACxB,IAAKL,EAAgBrzC,GACjB,MAGJA,GAAED,iBACFC,EAAE4xC,kBACFjlD,EAAQmlD,OAAO9xC,GAEf6zC,OAjJZ,GACIlnD,GAAS0D,EAASujD,EAAaT,EAD/BtpC,EAAiB,GAAIlc,IAAGqV,cAG5BrW,IACI0D,QAAS,KACTqhD,QAAS,SAAS1xC,KAClBskB,QAAS,SAAStkB,KAElB6xC,sBAAuB,SAAS7xC,KAChC8xC,OAAQ,SAAS9xC,MAGrBrS,GAAGwG,OAAOxH,EAASic,GACnBvY,EAAU1D,EAAQ0D,QAyIlB6iD,IACAkB,IAEAzmD,GAAGwG,OAAOvE,MACNggD,aAAc,SAAS+D,GACnB,MAAOD,GAAoBC,IAG/BzwC,QAAS,WACL2G,EAAe3G,WAGnB4sC,WAAY,WACR,MAAOz/C,OCvelB,WACG,YAEA1C,IAAG8mD,aACC9lC,gBAAiB,SAASC,GACtBhf,KAAK8kD,QAAQvlD,UAAUwf,gBAAgBhf,MAAMC,KAAMP,WACnDO,KAAK+kD,YAAYC,iBAGrBnkC,iBAAkB,WACd7gB,KAAK8kD,QAAQvlD,UAAUshB,iBAAiB9gB,MAAMC,KAAMP,WACpDO,KAAK+kD,YAAYE,cAGrBC,iBAAkB,SAASzkD,GACvBT,KAAKmlD,MAAQnlD,KAAKmlD,KAAKnC,mBAAmBviD,IAG9C2kD,oBAAqB,SAAS3kD,GAC1B,GAAIT,KAAKmlD,KACL,MAAOnlD,MAAKmlD,KAAKlC,eAAexiD,IAIxC4kD,gBAAiB,SAASjqC,GACtB,IAAKpb,KAAK+kD,YAAYO,gBAAgBlqC,GAClC,MAAOpb,MAAK+kD,YAAYQ,iBAAiBnqC,IAIjDN,MAAO,WACH9a,KAAK8kD,QAAQvlD,UAAUub,MAAM/a,MAAMC,KAAMP,WACzCO,KAAK+kD,YAAYjqC,SAEZ9a,KAAKpB,SAASslB,QAAUlkB,KAAK+kD,YAAYtiC,cAC1CziB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAK+kD,YAAYtiC,YAC1BrJ,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGHza,KAAKmlD,OACLnlD,KAAKmlD,KAAK7xC,UACVtT,KAAKmlD,KAAOnlD,KAAKwlD,qBAGrBxlD,KAAKylD,mBAAqB,EAC1BzlD,KAAK0lD,uBAAyB,EAE9B1lD,KAAK2lD,mCAGT3/B,QAAS,SAAS5K,EAAIkC,GAClB,GAAIsoC,GAAoB5lD,KAAKpB,SAASkyB,eAAexT,EAErDtd,MAAK8kD,QAAQvlD,UAAUymB,QAAQjmB,MAAMC,KAAMP,WAC3CO,KAAK+kD,YAAYc,eAAezqC,EAAIwqC,IAGxC/hC,YAAa,SAASzI,GAClB,GAAIqsB,GAASznC,KAAK8kD,QAAQvlD,UAAUskB,YAAY9jB,MAAMC,KAAMP,UAG5D,OADAgoC,IAAUznC,KAAK+kD,YAAYe,aAAa1qC,GACjCqsB,GAGX3mB,eAAgB,SAAS1F,GACrB,GAAI2qC,GAAY/lD,KAAK8kD,QAAQvlD,UAAUuhB,eAAe/gB,MAAMC,KAAMP,UAGlE,OADAsmD,IAAa/lD,KAAK+kD,YAAYiB,gBAAgB5qC,GACvC2qC,GAGXE,MAAO,SAASC,GACZ,MAAOlmD,MAAK+kD,YAAYoB,UAAUD,IAGtCE,cAAe,SAAS1kC,GACpB,GAAItB,GAAOpgB,KAAKoiB,QAAQV,EAExB,OAAOtB,GAAKimC,eAOpBtoD,GAAGuoD,cACC5jC,WAAY,SAASvJ,GACjB,GAAI+K,GAASlkB,KAAK8kD,QAAQvlD,UAAUmjB,WAAW3iB,MAAMC,KAAMP,UAQ3D,OANKykB,IACG/K,IAAanZ,KAAKytB,mBAClBvJ,EAASlkB,KAAK+kD,YAAYtiC,aAI3ByB,GAGXqiC,gBAAiB,SAAS7kC,GACtB1hB,KAAK+kD,YAAYyB,WAAW9kC,IAGhCikC,gCAAiC,WAC7B3lD,KAAKymD,yBAA2B1oD,GAAG2oD,yBAA2B1mD,KAAK2mD,6BAInE3mD,KAAK4mD,wBAA0B7oD,GAAGwR,UAE9BvP,KAAK6mD,2BAEL7mD,KAAK8mD,sBAAwB9mD,KAAK+mD,0BAClC/mD,KAAKgnD,6BAA+BhnD,KAAKinD,iCACzCjnD,KAAKknD,2BAA6BlnD,KAAKmnD,iCAI/C3B,kBAAmB,WACf,GAAIzjD,GAAO/B,KACPsC,EAAmBtC,KAAKpB,SAASwoD,YAAYC,eAC7CC,EAAatnD,KAAK+kD,YAClBwC,EAAkBD,EAAWE,aAIjC,OAFAD,IAAmBjlD,EAAiBzC,KAAK0nD,GAElC,GAAIxpD,IAAGyE,aACVF,iBAAkBA,EAClBi/C,mBAAoBvhD,KAAKpB,SAASwM,SAClCif,SACI03B,WAAY/hD,KAAKpB,SAASyrB,QAAQ03B,YAEtCrjD,WACI4iD,uBAAwB,WACpBgG,EAAWG,sBAEfxH,+BAAgC,SAAS9/B,EAAOgjC,GAC5CmE,EAAWI,qBAEX3pD,GAAGY,KAAKwhB,EAAO,SAASxgB,EAAKygB,GACzBA,EAAKimC,aAAelD,IAGpBhjC,EAAM/d,QACNL,EAAK+c,SAASqB,EAAO,KAAM,OAGnCqhC,UAAW,SAASnxB,EAAMs3B,GACtB5lD,EAAKqkB,WAAWiK,EAAMs3B,IAE1B5H,QAAS,SAAS3/C,EAAS+H,GACvBpG,EAAK5B,IAAIC,EAAS+H,QAMlCw+C,2BAA4B,WACxB,GAAI5kD,GAAO/B,IAEX,OAAO,IAAIjC,IAAG2oD,yBACVY,WAAYtnD,KAAK+kD,YAEjB5kD,IAAK,SAASC,EAASwnD,GACnB7lD,EAAK5B,IAAIC,EAASwnD,IAGtBC,aAAc,SAASnmC,GACnB3f,EAAKqf,WAAWM,IAGpB8J,SAAU,SAAS9J,GACf3f,EAAKye,OAAOkB,IAGhBomC,QAAS,SAASpmC,GACd3f,EAAK4iB,MAAMjD,IAGfqmC,QAAS,SAASrmC,GACd3f,EAAK8hB,YAAYnC,IAGrBsmC,WAAY,SAAStmC,GACjB3f,EAAK+e,eAAeY,IAGxBumC,UAAW,SAASvmC,GAChB,MAAO3f,GAAKmf,QAAQQ,OAKhCmlC,uBAAwB,WAEpB,MAAO7mD,MAAK+kD,YAAYmD,2BAChBloD,KAAKpB,SAAS+wB,YACf5xB,GAAGoqD,sBACHpqD,GAAGqqD,2BACHrqD,GAAGqqD,2BAGdC,qBAAsB,WAClB,GAAItmD,GAAO/B,KACPsnD,EAAatnD,KAAK+kD,WAEtB,QACIuC,WAAYA,EACZnnD,IAAK,SAASC,EAASwnD,GACnB7lD,EAAK5B,IAAIC,EAASwnD,IAEtBU,kBAAmB,SAAS5mC,GACxB,MAAO3f,GAAKmhB,YAAY9H,GAAIsG,IAAShG,QAEzCusC,UAAW,SAASvmC,GAChB,MAAO3f,GAAKmf,QAAQQ,IAExB6mC,UAAW,SAASntC,EAAIkC,GACpBvb,EAAKikB,QAAQ5K,EAAIkC,IAErBkrC,sBAAuB,SAASptC,EAAIqtC,GAChC,GAAIC,GAAU3qD,GAAGupD,EAAWqB,aAAavtC,IACrCwtC,EAAkB7qD,GAAGupD,EAAW/B,iBAAiBnqC,GAEjDqtC,IACAC,EAAQ5jD,SAAS,cACjBwiD,EAAWuB,aAAaztC,GACxBksC,EAAWwB,aAAa1tC,KAGxBstC,EAAQ3jD,YAAY,cACpBuiD,EAAWyB,aAAa3tC,GACxBksC,EAAW0B,aAAa5tC,IAI5BwtC,EAAgB9jD,SAAS,WAAWC,YAAY,cAK5D2kB,sBAAuB,SAAStO,EAAI2B,EAAWD,GAC3C9c,KAAK8kD,QAAQvlD,UAAUmqB,sBAAsB3pB,MAAMC,KAAMP,WAErDO,KAAK6mD,0BAED7mD,KAAK+kD,YAAYQ,iBAAiBnqC,IAAO0B,IAAc/e,GAAG2d,OAAOoC,YACjE9d,KAAK+kD,YAAYkE,qBAAqB7tC,GACtCpb,KAAK+kD,YAAY+D,aAAa1tC,IAIlC2B,IAAchf,GAAG2d,OAAO0C,iBAAmBtB,IAAc/e,GAAG2d,OAAOyC,WACnEne,KAAK+kD,YAAYmE,UAAU9tC,GAC3Bpb,KAAK+kD,YAAYoE,cAAc/tC,GAC/Brd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKrW,YAAY/E,KAAKopD,SAASC,WAE/DvsC,IAAc/e,GAAG2d,OAAO4C,eAC7Bte,KAAK+kD,YAAYuE,UAAUluC,IAInC6rC,+BAAgC,WAC5B,GAAI7qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGwrD,4BAA4BntC,IAG9C+qC,6BAA8B,WAC1B,GAAI/qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGqqD,0BAA0BhsC,IAG5C2qC,wBAAyB,WACrB,GAAI3qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGoqD,qBAAqB/rC,IAGvCiX,eAAgB,SAASjY,GACrBpb,KAAK8kD,QAAQvlD,UAAU8zB,eAAetzB,MAAMC,KAAMP,WAClDO,KAAK+kD,YAAYyE,YAAYpuC,IAGjCgW,eAAgB,SAASe,EAAYC,GACjCpyB,KAAK8kD,QAAQvlD,UAAU6xB,eAAerxB,MAAMC,KAAMP,WAClDO,KAAK+kD,YAAY0E,sBAGrBx2B,UAAW,SAAS7X,EAAIrc,GACpB,GAAIqhB,GAAOpgB,KAAKoiB,QAAQhH,EAEpBgF,IAAQA,EAAKmgC,QAAUvgD,KAAKpB,SAASwoD,YAAYsC,sBACjD1pD,KAAKmkB,aAAaqF,YAAYpO,GAC1BuuC,OAAQvpC,EAAKmgC,SAIrBvgD,KAAK8kD,QAAQvlD,UAAU0zB,UAAUlzB,MAAMC,KAAMP,WAC7CO,KAAK4pD,WAAWxuC,EAAIrc,IAIxBo0B,aAAc,SAAS/X,GAEfpb,KAAK6mD,2BACL7mD,KAAK+kD,YAAYkE,qBAAqB7tC,GACtCpb,KAAK+kD,YAAYiE,aAAa5tC,GAGzBpb,KAAK4mD,wBACN5mD,KAAKknD,2BAA2B2C,WAAW7pD,KAAK+kD,YAAY4D,aAAavtC,MAMrFiQ,YAAa,SAASjQ,EAAIrc,EAAMosB,EAAQC,GACpCprB,KAAK8kD,QAAQvlD,UAAU8rB,YAAYtrB,MAAMC,KAAMP,WAE/CO,KAAK+kD,YAAY+E,eAAe1uC,EAAI+P,EAAQC,GAE9B,IAAVA,GAAoD,MAArC/mB,KAAKC,MAAM6mB,EAASC,EAAQ,MAC3CprB,KAAK+kD,YAAYgF,WAAW3uC,GAC5Bpb,KAAK+kD,YAAYuE,UAAUluC,GAC3Bpb,KAAK+kD,YAAYiF,aAAa5uC,GAC9Bpb,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASkH,KAAKmkD,oBAGtDjqD,KAAKkqD,iBAAiB9uC,IAItBpb,KAAKkqD,iBAAiB9uC,EAAI+P,EAAQC,IAI1CwI,iBAAkB,SAASzI,EAAQC,GAC/BprB,KAAK8kD,QAAQvlD,UAAUq0B,iBAAiB7zB,MAAMC,KAAMP,WACpDO,KAAK+kD,YAAY1I,oBAAoBlxB,EAAQC,IAGjDG,YAAa,SAASnQ,EAAIrc,EAAMqG,EAAQqP,GAMpC,QAAS01C,GAAe/kD,GAGfkb,IAILgnC,EAAW6B,cAAc/tC,GAEzBrd,GAAGuiB,GAAevb,YAAYhD,EAAKqnD,SAASC,UAC5C/B,EAAW0C,aAAa5uC,GAEpBrZ,EAAKmhB,YAAY9H,GAAIA,IAAKM,SAAW3d,GAAG2d,OAAO4C,eAC/CgpC,EAAWyC,WAAW3uC,GAE1BksC,EAAWkC,YAAYpuC,GAEnBhW,EAAOiI,QACPtL,EAAKqoD,sBAAsBhvC,IAG3Brd,GAAGuiB,GAAexb,SAAS/C,EAAKqnD,SAASiB,MACzC/C,EAAWgD,WAAWlvC,GAElBksC,EAAWiD,oBAAsBxoD,EAAKiiB,gBAAgB5I,KACtDrd,GAAGuiB,GAAexb,SAAS/C,EAAKqnD,SAASlN,WACzCoL,EAAWkD,UAAUpvC,IAEzBrZ,EAAK0oD,2BAA2BrvC,EAAIhW,KAjC5C,GAAIslD,GAAe1qD,KAAK8kD,QAAQvlD,UAAUgsB,YAAYxrB,MAAMC,KAAMP,WAC9D6nD,EAAatnD,KAAK+kD,YAClBzkC,EAAgBgnC,EAAW/B,iBAAiBnqC,GAC5CrZ,EAAO/B,IA6CX,OAVI0qD,aAAwB3sD,IAAGoP,QAC3Bu9C,EAAahyC,KAAK,SAASiyC,GACvBR,EAAeQ,KAKnBR,EAAe/kD,GAGZslD,GAGXN,sBAAuB,SAAShvC,GAC5B,GAAIksC,GAAatnD,KAAK+kD,WAElB/kD,MAAK8vB,qBACLw3B,EAAWsD,iBAAiBxvC,GAGhCrd,GAAGupD,EAAW/B,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAAS/7C,SAE3DrN,KAAK6qD,sBAAsBzvC,IAG/BwQ,cAAe,SAASxQ,GACpBpb,KAAK8kD,QAAQvlD,UAAUqsB,cAAc7rB,MAAMC,KAAMP,WACjDO,KAAK+kD,YAAY+F,YAAY1vC,IAGjC0Q,UAAW,SAAS1Q,EAAIrc,GACpB,GAAI2rD,GAAe1qD,KAAK8kD,QAAQvlD,UAAUusB,UAAU/rB,MAAMC,KAAMP,UAIhE,OAFAO,MAAK+kD,YAAY+F,YAAY1vC,GAEtBsvC,GAGXz+B,eAAgB,SAAS7Q,EAAI4Q,GACzBhsB,KAAK8kD,QAAQvlD,UAAU0sB,eAAelsB,MAAMC,KAAMP,WAI9CusB,EAAU+L,UAAY,GAAK/3B,KAAKygB,SAASyjB,YAAY9oB,IACrDpb,KAAK+kD,YAAYgG,WAAW3vC,IAIpCsQ,UAAW,SAAStQ,EAAIrc,GACpBiB,KAAK8kD,QAAQvlD,UAAUmsB,UAAU3rB,MAAMC,KAAMP,WAC7CO,KAAKumD,gBAAgBnrC,GAEU,IAA3Bpb,KAAK8tB,mBACL9tB,KAAK+kD,YAAY0E,sBAIzBh3B,mBAAoB,SAASrX,GACzB,GAAI4vC,GAAoBC,EAASC,CAEjClrD,MAAK8kD,QAAQvlD,UAAUkzB,mBAAmB1yB,MAAMC,KAAMP,WAEtDO,KAAKmrD,gBAAgB/vC,GAEjBpb,KAAKpB,SAAS+lB,MAAMymC,oBACpBJ,EAAqBhrD,KAAK8jB,aAAa1I,GACvC6vC,EAAUjrD,KAAKpB,SAAS+lB,MAAMwQ,gBAE9B+1B,EAAYlrD,KAAKpB,SAAS+lB,MAAM0mC,cAAcrmD,QAAQ,gBAAiBgmD,GACvEE,EAAYA,EAAUlmD,QAAQ,eAAgBimD,GAE9CjrD,KAAK+kD,YAAYoE,cAAc/tC,EAAI8vC,GACnCntD,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAASC,YAKzEn4B,qBAAsB,SAAS9V,GAC3B,MAAIpb,MAAK8kD,QAAQvlD,UAAU2xB,qBAAqBnxB,MAAMC,KAAMP,YACxDO,KAAK+kD,YAAYuG,cAAclwC,GAC/Brd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKrW,YAAY/E,KAAKopD,SAASiB,MACpErqD,KAAK+kD,YAAYoE,cAAc/tC,GAC/Bpb,KAAK+kD,YAAY+F,YAAY1vC,GAC7Bpb,KAAKmrD,gBAAgB/vC,IACd,IAGPrd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAASlN,WACjEl8C,KAAK+kD,YAAYyF,UAAUpvC,IACpB,IAIfiG,gBAAiB,SAASjG,GACtB,GAAIkY,GAAoBv1B,GAAGgT,KAAK/Q,KAAKurD,uBAAwBvrD,KAE7DA,MAAK8kD,QAAQvlD,UAAU8hB,gBAAgB7hB,KAAKQ,KAAMob,EAAIkY,IAG1Di4B,uBAAwB,SAASnwC,EAAIG,EAAMgY,GACnCvzB,KAAKpB,SAASwiB,WAAWoqC,aACzBxrD,KAAKyrD,mBAAmB1rD,MAAMC,KAAMP,WAGpCO,KAAK0rD,mBAAmB3rD,MAAMC,KAAMP,YAI5CwoB,kBAAmB,SAAS7M,EAAI3G,EAAKuT,GACjChoB,KAAK8kD,QAAQvlD,UAAU0oB,kBAAkBloB,MAAMC,KAAMP,WAErDO,KAAK+kD,YAAYyE,YAAYpuC,GAEzB4M,GACAhoB,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASwiB,WAAWuqC,oBAC5D3rD,KAAK+kD,YAAY6F,iBAAiBxvC,IAGlCpb,KAAKumD,gBAAgBnrC,IAI7BswC,mBAAoB,SAAStwC,EAAIG,EAAMgY,GACnCvzB,KAAK+kD,YAAY6G,iBAAiBxwC,GAClCpb,KAAK+kD,YAAY+F,YAAY1vC,GAC7Bpb,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASwiB,WAAWyqC,oBAC5D7rD,KAAK0zB,eAAeC,WAAW5zB,MAAMC,KAAMP,YAG/CgsD,mBAAoB,SAASrwC,EAAIG,EAAMqf,GAEnC,GAKIt5B,GALA6R,EAAWnT,KAAKkhB,QAAQ9F,GACxB0wC,EAAiB9rD,KAAKpB,SAASwiB,WAAW0qC,eAAe9mD,QAAQ,gBAAiBmO,GAElF44C,GADO/rD,KAAK2jB,QAAQvI,GACA3b,WACpBsC,EAAO/B,IAGXsB,GAAStB,KAAKpB,SAASotD,YAAYF,GAE/B/tD,GAAGga,iBAAiBzW,GACpBA,EAAO2W,KAAK,WACRlW,EAAK2pD,mBAAmB3rD,MAAMgC,EAAMgqD,KAGnCzqD,KAAW,GAChBS,EAAK2pD,mBAAmB3rD,MAAMgC,EAAMgqD,IAI5CnC,WAAY,SAASxuC,EAAIrc,EAAMktD,GAC3B,GAAIC,GAGA5U,EAFA6U,EAAe,EACfC,EAAcpsD,KAAKygB,SAASwjB,UAAU7oB,IAAOpb,KAAKpB,SAAS2Y,QAAQ80C,UAGnErsD,MAAKpB,SAASqE,QAAQqpD,eAClBtsD,KAAKylD,mBAAqB,GAAKzlD,KAAK0lD,uBAAyB,IAC7DyG,EAAensD,KAAK0lD,uBAAyB,GAGjDwG,GACIhqD,MAAOiqD,IAIVF,IACGjsD,KAAKpB,SAASy3B,8BAAgCt4B,GAAGiW,kBAAkBqC,eACnErW,KAAK+kD,YAAYwH,gBAMhBvsD,KAAKpB,SAASwM,WACfksC,EAASt3C,KAAKkjB,YAAY9H,GAAIA,IAE9Bpb,KAAKwsD,mBAAqBxsD,KAAKwsD,oBAAsBlV,EAAO76B,aAExD66B,EAAO76B,eAAiBzc,KAAKwsD,oBAAuBlV,EAAO76B,eAC3Dzc,KAAKygB,SAASC,YACd1gB,KAAKysD,aACLzsD,KAAKwsD,mBAAqB,QAKlCP,GACAjsD,KAAK+kD,YAAY2H,eAAetxC,EAAIpb,KAAKpB,SAASkyB,eAAe/xB,GAAOmtD,EAAaE,GACrFpsD,KAAK+kD,YAAY4H,gBAAgBvxC,EAAIpb,KAAKkiB,eAAe9G,IAAK,EAAMpb,KAAKpB,SAASguD,WAAWl0B,iBAG7F14B,KAAK+kD,YAAY5oC,QAAQf,EAAIpb,KAAKpB,SAASkyB,eAAe/xB,GAAOmtD,EAAaE,GAC9EpsD,KAAK+kD,YAAY8H,gBAAgBzxC,EAAIpb,KAAKoiB,QAAQhH,GAAKpb,KAAKpB,SAASguD,WAAWl0B,gBAGpF14B,KAAK0lD,wBAA0B,GAE3BuG,GACCjsD,KAAKpB,SAASqE,QAAQ6pD,kBAAoB/uD,GAAGiW,kBAAkBqC,gBAEhErW,KAAKkqD,iBAAiB9uC,IAI9BqxC,WAAY,WACRzsD,KAAK+kD,YAAYE,aACjBjlD,KAAK6gB,oBAGTqpC,iBAAkB,SAAS9uC,EAAI2xC,EAAYlR,GACvC,GAAIt/B,GAAOvc,KAAKojB,QAAQhI,GACpB4xC,EAAiBhtD,KAAK8sB,YAAYvQ,EAElCA,IAAQ,IACWle,SAAf0uD,GAA0C1uD,SAAdw9C,IAC5BmR,EAAiBhtD,KAAKitD,gBAAgBF,EAAYlR,IAGtD77C,KAAK+kD,YAAYxnC,WAAWnC,EAAI4xC,KAIxCC,gBAAiB,SAASC,EAAcrR,GAEpC,QAASrtC,GAAEzP,EAAMwxB,GAAenwB,EAAUA,EAAQ4E,QAAQjG,EAAMwxB,GADhE,GAAInwB,GAAUJ,KAAKpB,SAASkH,KAAKqnD,cAKjC,OAFA3+C,GAAE,YAAanK,KAAKC,MAAM4oD,EAAerR,EAAY,MACrDrtC,EAAE,eAAgBxO,KAAK8sB,YAAY+uB,IAC5Bz7C,GAGXqqD,2BAA4B,SAASrvC,EAAIqW,GACrC,GAAI27B,GAAMC,EAAkBC,CAE5BF,GAAOptD,KAAKpB,SAAS2uD,wBAAwBH,KAC7CC,EAAmBrtD,KAAKpB,SAAS2uD,wBAAwBF,iBAE5C,WAATD,GACAE,EAAgB77B,EAAS47B,GACpBC,IACDA,EAAgBttD,KAAKpB,SAASkH,KAAK0nD,YAGvCxtD,KAAK+kD,YAAYoE,cAAc/tC,EAAIkyC,GAE/BttD,KAAKpB,SAAS2uD,wBAAwBE,eACtCztD,KAAK0tD,aAAatyC,EAAIkyC,IAGZ,YAATF,EACLptD,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASkH,KAAK0nD,YAExC,SAATJ,GACLptD,KAAKG,IAAI,0CAA4CitD,EAAO,iBAAkB,SAItFM,aAAc,SAAStyC,EAAItV,GACvB9F,KAAK+kD,YAAYQ,iBAAiBnqC,GAAIhC,MAAQtT,GAGlDqlD,gBAAiB,SAAS/vC,GACjBpb,KAAKpB,SAASy3B,8BAA+Bt4B,GAAGiW,kBAAkBqC,eACnErW,KAAK+kD,YAAYuF,WAAWlvC,IAIpCgL,WAAY,SAASiK,EAAMtxB,EAAMkK,GAC7B,GAAI7I,GAAUJ,KAAK8kD,QAAQvlD,UAAU6mB,WAAWrmB,MAAMC,KAAMP,UAC5DO,MAAKpB,SAAS+uD,YAAYvtD,IAG9B2mB,YAAa,SAAS3mB,GAClBJ,KAAK8kD,QAAQvlD,UAAUwnB,YAAYhnB,MAAMC,KAAMP,WAC/CO,KAAKpB,SAAS+uD,YAAYvtD,IAG9BwtD,kBAAmB,WACf,GAAI7rD,GAAO/B,IAEXA,MAAKpB,SAASF,UAAU8pB,gBAAkB,WACtC,GAAIpoB,GAAU2B,EAAKnD,SAASypB,MAAMwlC,kBAC9BC,EAAa/rD,EAAKnD,SAASypB,MAAM5I,WAErC,OAAO1d,GAAKnD,SAASmvD,WAAW3tD,EAAS0tD,KAIjDjhC,oBAAqB,SAASzR,EAAIrc,GAC9BiB,KAAKylD,oBAAsB,EAC3BzlD,KAAK8kD,QAAQvlD,UAAUstB,oBAAoB9sB,MAAMC,KAAMP,YAG3D8gB,uBAAwB,SAAS3U,EAAOrO,EAAQshB,GAC5C7e,KAAKylD,mBAAqB75C,EAAMxJ,OAChCpC,KAAK0lD,uBAAyB,EAC9B1lD,KAAK8kD,QAAQvlD,UAAUghB,uBAAuBxgB,MAAMC,KAAMP,YAG9DorD,sBAAuB,SAASnpC,GAC5B,GAAIgF,GAAe1mB,KAAKkiB,eAAeR,GACnCssC,EAAahuD,KAAKkjB,YAAY9H,GAAIsG,IAAShG,MAE3CsyC,KAAejwD,GAAG2d,OAAO+C,UACxBiI,IACD1mB,KAAKpB,SAASguD,WAAWqB,aAAaC,mBACrCnwD,GAAGiW,kBAAkBiD,eAItBjX,KAAK+kD,YAAY4H,gBAAgBjrC,EAAQgF,EAAc1mB,KAAKpB,SAASguD,WAAWl0B,gBAIxFxZ,eAAgB,SAASqH,GACrB,GAAInL,GAAKpb,KAAK8kD,QAAQvlD,UAAU2f,eAAenf,MAAMC,KAAMP,UAO3D,OALAO,MAAK4pD,WAAWxuC,EAAIpb,KAAKkhB,QAAQ9F,IAAK,GACtCpb,KAAK+kD,YAAYyE,YAAYpuC,GAC7Bpb,KAAK+kD,YAAYgF,WAAW3uC,GAC5Bpb,KAAKoqD,sBAAsBhvC,GAEpBA,GAGXqR,SAAU,SAASrR,EAAIoC,GACnBxd,KAAK8kD,QAAQvlD,UAAUktB,SAAS1sB,MAAMC,KAAMP,WAE5CO,KAAK+kD,YAAYxnC,WAAWnC,EAAIpb,KAAK8sB,YAAYtP,KAGrDuX,wBAAyB,WACrB/0B,KAAK+kD,YAAYC,gBACjBhlD,KAAK8kD,QAAQvlD,UAAUw1B,wBAAwBh1B,MAAMC,KAAMP,gBC7sBvE1B,GAAGC,aAAe,SAASgb,EAAGtb,GAC1B,YAEA,IAAIqE,GAAO/B,IAKXA,MAAK8kD,QAAUpnD,EAAYK,GAAGL,GAAW04B,kBAAoBr4B,GAAGq4B,kBAChEp2B,KAAK8kD,QAAQ/kD,MAAMC,KAAMP,WAGzB1B,GAAGwG,OAAOvE,KAAKpB,UACX6B,QAAS,KAETyjB,OAAQ,KAERiqC,YAAa,KAEb/G,aACIC,kBACAqC,sBAAsB,GAG1B5jD,MACIqnD,eAAgB,6BAChBK,WAAY,gBACZvD,mBAAoB,gBACpBxiB,OAAQ,UAGZ2mB,SAAU,cAEV/jC,SACIg/B,SAAU,qBACVnN,UAAW,sBACX7uC,QAAS,oBACTg9C,KAAM,iBACNgE,SAAU,cACVtrD,KAAM,UACNg/C,WAAY,8BAGhBwL,yBACIH,KAAM,UACNC,iBAAkB,QAClBI,eAAe,GAGnB/8B,UACI49B,kBAAmB,6BACnBC,mBAAoB,kFAGxB5pC,OACIymC,mBAAmB,EACnBC,cAAe,oCAGnBjqC,YACIoqC,cAAc,EACdM,eAAgB,8CAChBD,mBAAoB,cACpBF,mBAAoB,iBAIxB1oD,SACI6pD,kBAAkB,EAClBR,cAAc,GAGlBjkC,OACImmC,eAAe,EACfX,kBAAmB,0BAGvBjB,YACIl0B,cAAe,KACf+1B,SAAU,EACVR,cACIC,mBAAmB,EACnBQ,iBAAkB,KAClBC,YAAa,MAEjBC,kBAAmB,KAGvBr3C,SACI80C,YAAY,GAGhBsB,YAAa,SAASvtD,GAClB,MAAI2B,GAAKgjD,YAAY8J,UAAU,SACpB9sD,EAAKgjD,YAAY+J,WAAW,QAAS1uD,OAG5CwpB,YAAW,WACPziB,OAAOmqB,MAAMlxB,IACd,IAIX4rD,YAAa,SAAS5rD,GAClB,MAAI2B,GAAKgjD,YAAY8J,UAAU,WACpB9sD,EAAKgjD,YAAY+J,WAAW,UAAW1uD,GAGvC+G,OAAO4nD,QAAQ3uD,IAI9B2tD,WAAY,SAAS3tD,EAAS4uD,GAC1B,MAAIjtD,GAAKgjD,YAAY8J,UAAU,UACpB9sD,EAAKgjD,YAAY+J,WAAW,SAAU1uD,EAAS4uD,GAG/C7nD,OAAO8nD,OAAO7uD,EAAS4uD,MAGvC,GAGHjxD,GAAGwG,OAAOvE,KAAKpB,SAAUoa,GAAG,GAE5BhZ,KAAK+kD,YAAc,GAAIhnD,IAAGmxD,YACtB/uD,IAAKpC,GAAGgT,KAAK/Q,KAAKG,IAAKH,MACvBmvD,eAAgBnvD,KAAKpB,SAASwvD,SAC9BgB,YAAapvD,KAAKpB,SAAS6B,QAC3B4uD,gBAAiBrvD,KAAKpB,SAASuvD,YAC/BjqC,OAAQlkB,KAAKpB,SAASslB,OACtBw0B,eAAgB14C,KAAKiiB,gBACrBoI,SACItnB,KAAM/C,KAAKpB,SAASyrB,QAAQtnB,KAC5BsrD,SAAUruD,KAAKpB,SAASyrB,QAAQgkC,UAEpC5Z,QACI6a,UAAWtvD,KAAKpB,SAASguD,WAAW6B,SACpCG,kBAAmB5uD,KAAKpB,SAASguD,WAAWgC,mBAEhDX,cACIsB,gBAAiBvvD,KAAKpB,SAASguD,WAAWqB,aAAaC,kBACvDsB,sBAAuBxvD,KAAKpB,SAASguD,WAAWqB,aAAaS,iBAC7De,oBAAqBzvD,KAAKpB,SAASguD,WAAWqB,aAAaU,aAE/D7oD,KAAM9F,KAAKpB,SAASkH,OAGpB9F,KAAKpB,SAASmrB,YAAYsH,mBAAqBtzB,GAAGgS,UAAYhS,GAAGkS,YACjEjQ,KAAK+kD,YAAY2K,cAAc1vD,KAAKpB,SAAS8xB,SAASa,+BAEhDxzB,GAAGiW,kBAAkB0D,WAAc1X,KAAKpB,SAAS+oB,KAAKoI,WAAahyB,GAAGiW,kBAAkB2D,WAC9F3X,KAAK+kD,YAAY2K,cAAc1vD,KAAKpB,SAAS8xB,SAAS69B,qBAGtDvuD,KAAK81B,iBAEL91B,KAAK+kD,YAAYzW,SAEjBtuC,KAAKopD,SAAWppD,KAAKpB,SAASyrB,SAEzBrqB,KAAKpB,SAASslB,QAAUlkB,KAAK+kD,YAAYtiC,cAC1CziB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAK+kD,YAAYtiC,YAC1BrJ,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGPza,KAAK2lD,kCAED5nD,GAAGyE,aAAezE,GAAGiW,kBAAkB8C,WACvC9W,KAAKmlD,KAAOnlD,KAAKwlD,qBAGjBxlD,KAAKpB,SAASypB,MAAMD,eAAiBpoB,KAAKpB,SAASypB,MAAMmmC,gBACrDzwD,GAAGoqB,aACHnoB,KAAK4tD,oBAGL5tD,KAAKG,IAAI,kCAAmC,UAIpDH,KAAKylD,mBAAqB,EAC1BzlD,KAAK0lD,uBAAyB,IAKtC3nD,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAG2gB,eACxC3gB,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAGuoB,gBAGxCvoB,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAG8mD,aACxC9mD,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAGuoD,cC5LxCvoD,GAAGmxD,WAAa,SAAS9yC,GACrB,YAEA,IA4EIjc,GACAwvD,EACAC,EACAC,EACAxtC,EACA8M,EACA2gC,EACAC,EAnFAC,EAAe,aACfC,EAAoB,cACpBC,EAA0B,cAC1BC,EAA8B,kBAE9BC,EAAqB,mBACrBC,EAAsB,oBACtBC,EAAoB,iBACpBC,EAAuB,oBACvBC,GACIC,QAASvlD,SAASwlD,yBAClBC,QAEJC,GAAmB,EACnBC,EAAsB,EACtBC,GAA+B,EAC/BC,KACAC,GAAmB,EACnBj0D,GACIoD,IAAK,KACLs0C,QACI6a,UAAW,EACXV,kBAAmB,KAEvBO,eAAgB,cAChBC,YAAa,KACbC,gBAAiB,KACjBnrC,OAAQ,KACRw0B,eAAgB;AAChBruB,SACItnB,KAAM,UACNsrD,SAAU,eAEdJ,cACIsB,iBAAiB,EACjBC,sBAAuB,KACvBC,oBAAqB,MAEzB3pD,MACI2hC,OAAQ,WAGhBwpB,GACI/sC,OAAQ,4BACRgtC,YAAa,2BACbC,mBAAoB,4BACpBC,cAAe,6BACfC,cAAe,6BACfC,eAAgB,wBAChBC,aAAc,4BACdn0D,SAAU,uBACVo0D,KAAM,+BACNC,KAAM,0BACNC,qBAAsB,qCACtBr6C,YAAa,2BACbs6C,0BAA2B,2CAC3BC,iBAAkB,iCAClBxxC,KAAM,0BACNyxC,QAAS,6BACTt1C,KAAM,0BACNiE,OAAQ,4BACRpJ,MAAO,2BACP06C,eAAgB,8BAChBC,aAAc,4BACdptC,MAAO,2BACPqtC,WAAY,iCACZC,kBAAmB,4BACnBC,aAAc,iCACdC,SAAU,oCACVC,eAAgB,8BAChBC,sBAAuB,sCACvBC,UAAW,yBAEfC,KACAC,EAAiC,GAAIz0D,IAAGoP,QACxCslD,EAA+B,GAAI10D,IAAGoP,QAatCulD,EAA6B,WACzB,GAAIC,GAAmB51D,EAAQkxD,aAAauB,sBACxCoD,EAAa71D,EAAQkxD,aAAawB,oBAClCrzC,GACIwF,QAASovC,EACT7uC,MAAO4tC,EAGXD,KACI6C,EACA51D,EAAQ27C,eAAep2B,SAASqwC,EAAiB,GAAI5kB,OAAS3xB,GAAMnE,KAChE,SAAS46C,GACLL,EAA+BnlD,QAAQwlD,IAE3C,WACIL,EAA+BjlD,UAC/BpN,EAAI,wDAA0DwyD,EAAiB,WAKvFH,EAA+BjlD,UAG/BqlD,EACA71D,EAAQ27C,eAAep2B,SAASswC,EAAY,GAAI7kB,OAAS3xB,GAAMnE,KAC3D,SAAS46C,GACLJ,EAA6BplD,QAAQwlD,IAEzC,WACIJ,EAA6BllD,UAC7BpN,EAAI,gEAAkEyyD,EAAY,WAK1FH,EAA6BllD,YAOzCulD,EAAoB,SAASR,GACzB,GAAIS,GAAsB,GAAIh1D,IAAGoP,OAwBjC,OAtBAslD,GAA6Bx6C,KAAK,SAASoyB,GACvC2oB,EAA4B3oB,EAAKioB,GAE5BA,EAAUnkB,IASX4kB,EAAoB1lD,WARpBilD,EAAUnkB,IAAM9D,EAAI8D,IACpBmkB,EAAUllD,OAAS,WACfklD,EAAUllD,OAAS,KACnB6lD,GAAKX,GACLS,EAAoB1lD,aAM7B,WAICtK,EAAKuvD,GACLS,EAAoB1lD,YAGjB0lD,GAGXG,EAAqB,SAAS93C,EAAIvO,EAAMuP,GACpC,GAAIk2C,GAAYa,EAAa/3C,EAK7B,OAHAjb,GAAI,gCAAkCib,GACtCvO,EAAKumD,cAAgBh4C,EAEdre,EAAQ27C,eAAep2B,SAASzV,EAAMylD,EAAWl2C,GAAMnE,KAC1D,WACI44C,IACAoC,GAAKX,GACLC,EAAkBn3C,GAAI/N,WAE1B,WACIklD,EAAkBn3C,GAAI7N,UAIjBxQ,EAAQkxD,aAAasB,iBACtB8D,EAA+Bj4C,EAAIk3C,MAKnDgB,EAA4B,WACxB,GAAIvC,EAAqB3uD,OAAQ,CAC7B0uD,GAA+B,CAE/B,IAAIyC,GAAqBxC,EAAqBv9C,OAE1C+/C,GAAmBC,OACnBC,EAAkCF,GAGlCG,EAA+BH,OAInCzC,IAA+B,GAIvC6C,EAAY,SAASv4C,GACjB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBzwC,SAGtDqzC,EAAc,SAASz4C,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBa,iBAGtDgC,EAAY,SAAS3yD,GACjB,MAAOyyD,GAAcvxC,EAAW4uC,EAAgB9vD,EAAO,YAG3D4yD,EAAY,SAAS34C,GACjB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBc,eAGtDiC,EAAoB,WAChB,MAAOJ,GAAcvxC,EAAW4uC,EAAgBmB,iBAGpD6B,EAAc,SAAS74C,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBiB,eAGtD9vC,EAAU,SAAShH,GACf,MAAOo1C,GAAUG,IAAIv1C,IAAOrd,GAAGoxB,GAAU3pB,gBAAgByqD,EAAoB70C,IAGjFnI,EAAc,SAASmI,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB7wC,OAGtD8zC,EAAW,SAAS94C,GAChB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB75C,QAGtD+8C,EAAc,SAAS/4C,GAGnB,MAAU,OAANA,EACOw4C,EAAcvxC,EAAW4uC,EAAgBU,4BAC5CiC,EAAcvxC,EAAW4uC,EAAgBW,kBAI1CgC,EAAcxxC,EAAQhH,GAAK61C,EAAgBS,uBAC9CkC,EAAcxxC,EAAQhH,GAAK61C,EAAgB55C,cAGnD+8C,EAAW,SAASh5C,GAChB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBtsC,QAGtDvB,EAAU,SAAShI,GACf,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB10C,OAGtD83C,EAAa,SAASj5C,GAClB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBY,UAGtD+B,EAAgB,SAAS3iD,EAASqjD,GAC9B,MAAOrjD,IAAWlT,GAAGkT,GAASzL,gBAAgB8uD,IAGlDnB,EAAe,SAAS/3C,GACpB,MAAO00C,IAAkB8D,EAAcxxC,EAAQhH,GAAK61C,EAAgBqB,YAGxEvvD,EAAO,SAASZ,GACZA,GAAMpE,GAAGoE,GAAI2C,SAAS/H,EAAQstB,QAAQtnB,OAM1CiwD,EAA8B,SAAS/hC,EAAaqhC,GAChD,GAAI37B,GAAW1F,EAAYjuB,MAAM2zB,SAC7BD,EAAYzF,EAAYjuB,MAAM0zB,SAE9BA,IAAaC,IAAa27B,EAAUtvD,MAAM2zB,WAAa27B,EAAUtvD,MAAM0zB,WACvE34B,GAAGu0D,GAAWtuD,KACV2yB,SAAUA,EACVD,UAAWA,KAQvB28B,EAAiC,SAASj4C,EAAIk3C,GAC1C,GAAIiC,GAAahC,EAAkBn3C,KAAO,GAAIrd,IAAGoP,SAAUI,UACvDinD,EAA2B,GAAIz2D,IAAGoP,OAqBtC,OAnBAqlD,GAA+Bv6C,KAAK,SAASoyB,GACzCkqB,EAAWt8C,KACP,WACIu8C,EAAyBnnD,WAE7B,WACI2lD,EAA4B3oB,EAAKioB,GAEjCA,EAAUllD,OAAS,WACfklD,EAAUllD,OAAS,KACnBonD,EAAyBnnD,WAG7BilD,EAAUnkB,IAAM9D,EAAI8D,IACpB8kB,GAAKX,OAKVkC,GAWXC,EAAsB,WAClB,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACArT,EACA4Q,EACAF,EACA4C,EACAC,CAKJ,IAHA90D,EAAI,oBAG0B,MAA1BpD,EAAQoyD,eACR,KAAM,IAAIjrD,OAAM,oDAIpB,IAAInG,GAAGoL,SAASpM,EAAQoyD,gBAAiB,CAGrC,GAFAuF,EAAWxpD,SAAS85B,eAAejoC,EAAQoyD,gBAE1B,OAAbuF,EACA,KAAM,IAAIxwD,OAAMnG,GAAG0L,OAAO,0CAA2C1M,EAAQoyD,gBAGjFwF,GAAaD,EAASjkD,cAErB,CACD,GAAyCpS,SAArCtB,EAAQoyD,eAAe1+C,UACvB,KAAM,IAAIvM,OAAM,gGAIpBywD,GAAa53D,EAAQoyD,eAAe1+C,UA4ExC,GAzEAkkD,EAAa52D,GAAGsL,QAAQsrD,GACxBE,EAAiB3pD,SAASC,cAAc,OACxC0pD,EAAeviD,YAAYvU,GAAGuS,UAAUqkD,IACxCM,EAAal3D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgB7zD,UAI5DL,EAAQmnB,SACR6wC,EAAgBh3D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgB/sC,QAC/D6wC,GACAh3D,GAAGg3D,GAAejxD,UASrB/F,GAAGyE,aAAgBzE,GAAGiW,kBAAkB8C,WACzCs7C,EAAiBr0D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBmB,gBAChEA,GACAr0D,GAAGq0D,GAAgBtuD,UAI3B49C,EAAW3jD,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBO,MAI1D9P,IAAa3jD,GAAGyE,cAChBrC,EAAI,0BAA2B,QAC/BpC,GAAG2jD,GAAU59C,UAGZ/F,GAAGiW,kBAAkB8C,SAajB/Y,GAAGk3D,GAAY/uD,aAAamqD,IAAwB3O,IACzDsT,EAAaj3D,GAAG2jD,GAAUl8C,gBAAgByrD,EAAgBkB,UAC1D6C,GAAcj3D,GAAGi3D,GAAYlxD,WAb7BmxD,EAAWr6C,gBAAgBy1C,GAEvB3O,GAAY3jD,GAAG2jD,GAAUx7C,aAAakqD,IAItCryD,GAAG2jD,GAAU19C,KACTf,QAAS,UAWrBqvD,EAAYv0D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBqB,WAC1DxC,EAGIwC,IACLtB,EAAmB3uB,SAASiwB,EAAUjsD,aAAa6pD,IAEnDc,EAAmBA,EAAmB,EAAIA,EAAmB,KAE7DjB,EAAchyD,GAAGu0D,GAAWpsD,aAAaiqD,IAPzCmC,GAAav0D,GAAGu0D,GAAWxuD,SAS/BgsD,EAAiBA,GAAkBwC,EAEnC3C,EAAsB5xD,GAAG82D,GAAgB5vD,WAAWgsD,EAAgBgB,mBAAmB7vD,OAAS,EAChGwtD,EAAsB7xD,GAAG82D,GAAgB5vD,WAAWgsD,EAAgBtsC,OAAOviB,OAAS,EAEpFwyD,EAAe72D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBQ,MAE9C,MAAhBmD,EACA,KAAM,IAAI1wD,OAAM,0DAapB,OAVA4wD,GAAeF,EAAankD,UAC5BmkD,EAAankD,UAAY,GAGrBokD,EAAetvD,qBAAqB,UAAUnD,QAC9C8I,SAASC,cAAc,UAG3BhL,EAAI,8BAGAiuD,SAAUrwD,GAAGsL,QAAQwrD,EAAepkD,WACpCykD,aAAcn3D,GAAGsL,QAAQyrD,KAIjCK,EAAc,SAAShzD,EAAID,EAAOitB,GAC9B,GAAIimC,GAAWjmC,EACXkmC,EAAWD,EAASzvD,UAEpBzD,GAAQ,IACRmzD,EAAWt3D,GAAGq3D,GAAU3vD,WAAWvD,GAAO0D,aAI9CwvD,EAASzxD,aAAaxB,EAAIkzD,IAG9B3B,EAAiC,SAASH,GACtC,GAAIn4C,GAAKm4C,EAAmBn4C,GACxBk6C,EAAgB/B,EAAmB+B,cACnCC,EAAqBD,GAAiBA,EAAclC,cACpDd,EAAYa,EAAa/3C,GACzBgB,GACI0F,qBAAsByxC,EAAmBzxC,qBACzCF,QAASovC,EACTp4B,QAAQ,EACRzW,OAAO,EAGXpkB,IAAGiW,kBAAkBiD,cACjBq7C,EACIv1D,EAAQ03C,OAAO6a,WAAavyD,EAAQ03C,OAAO6a,WAAauB,GACxDwC,EAA+Bj4C,EAAIk3C,GACnCgB,KAGAR,EAAkBR,GAAW55C,KAAK,WAC9B65C,EAAkBn3C,GAAM,GAAIrd,IAAGoP,QAE/BolD,EAAkBn3C,GAAI1C,KAAK,WACvBkR,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,qBAM/B,MAAtB2G,EACAC,GAAiBp6C,EAAIm6C,GAGrBrC,EAAmB93C,EAAIk6C,EAAel5C,KAOlDk3C,IAGChB,IACLQ,EAAkBR,GAClBgB,MAIRG,EAAoC,SAASF,GACzC,GAAIn4C,GAAKm4C,EAAmBn4C,GACxBsL,EAAe6sC,EAAmB7sC,aAClC+uC,EAAiBlC,EAAmBkC,eACpCnD,EAAYa,EAAa/3C,GACzBgB,GACI0F,qBAAsByxC,EAAmBzxC,qBACzCK,MAAO4tC,EACPnuC,QAASovC,EAGjB,IAAIsB,EACA,GAAI5rC,EAAc,CACd,KAAI3pB,EAAQ03C,OAAO6a,WAAavyD,EAAQ03C,OAAO6a,WAAauB,GASxD,MAJI4E,IACA3C,EAAkBR,GAGfv1D,EAAQ27C,eAAep2B,SAASoE,EAAc4rC,EAAWl2C,GAAMnE,KAClE,WACIg7C,GAAKX,GACLzB,IACAjnC,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,oBAGzD,WACIyE,EAA+Bj4C,EAAIk3C,GACnC1oC,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,oBAjB7DyE,GAA+Bj4C,EAAIk3C,GACnCgB,QAsBJD,GAA+Bj4C,EAAIk3C,GACnCgB,KAKZoC,GAAsB,SAASt6C,EAAIu6C,GAC/B,GAAIC,GAAMzB,EAAY/4C,GAElBy6C,EAA4B,MAANz6C,EAAa61C,EAAgBW,iBAAmBX,EAAgB55C,WAEtFu+C,KAAQ73D,GAAG63D,GAAKpxD,SAASqxD,KACzBD,EAAM73D,GAAG63D,GAAKpwD,gBAAgBqwD,IAG9BD,IACA73D,GAAG63D,GAAK5xD,KAAK2mC,MAAOgrB,EAAU,MAC9BC,EAAIvjD,aAAa,gBAAiBsjD,KAI1C1C,GAAO,SAAS9wD,GACZA,GAAMpE,GAAGoE,GAAI4C,YAAYhI,EAAQstB,QAAQtnB,OAG7CyyD,GAAmB,SAASM,EAAmBC,GAC3C,GAAIC,GAAkB7C,EAAa2C,GAC/BG,EAAkB9C,EAAa4C,EAEnC51D,GAAIpC,GAAG0L,OAAO,qFAAsFqsD,EAAmBC,EAAmBA,IAG1IxD,EAAkBwD,GAAmB99C,KAAK,WACtC44C,IACA0B,EAAkBuD,GAAmBzoD,UACrClN,EAAIpC,GAAG0L,OAAO,uEAAwEssD,EAAmBD,IACzGE,EAAgB7nB,IAAM8nB,EAAgB9nB,IACtC8kB,GAAK+C,IAET,WACIzD,EAAkBuD,GAAmBvoD,UAChCxQ,EAAQkxD,aAAasB,iBACtB8D,EAA+ByC,EAAmBE,KAKlEj4D,IAAGwG,OAAOxH,EAASqf,GACnBjc,EAAMpD,EAAQoD,IAITpC,GAAGiW,kBAAkBiD,gBACtBla,EAAQ03C,OAAOma,kBAAoB,EACnC7xD,EAAQ03C,OAAO6a,UAAY,GAG/BjtC,EAAYtlB,EAAQqyD,YACpBU,EAA4CzxD,SAA3BtB,EAAQ27C,eACzBmX,EAAe4E,IAEf/B,IAEA30D,GAAGwG,OAAOvE,MACNsuC,OAAQ,WACJnuC,EAAI,8BAEJ0wD,EAAsB,EAEtBxuC,EAAU5R,UAAYo/C,EAAazB,SACnCrrD,EAAKixD,KACLh0D,KAAKk2D,oBACL/mC,EAAWpyB,EAAQsyD,iBAAmBuE,EAAcvxC,EAAW4uC,EAAgBQ,MAE/EtxD,EAAI,gCAGRuvD,cAAe,SAAStvD,GACpB,GAAI+1D,GAAep4D,GAAGuS,UAAUlQ,EAChCiiB,GAAU5R,UAAY,GACtB4R,EAAU/P,YAAY6jD,IAG1Br7C,MAAO,WACH9a,KAAKsuC,UAGT2W,WAAY,WACR91B,EAAS1e,UAAY,IAGzB87C,cAAe,WACXqE,GAAmB,GAGvBz0C,QAAS,SAASf,EAAIrc,EAAMq3D,EAAaC,EAAaC,GAClD,GAIIC,GAJAC,EAASz4D,GAAGuS,UAAUu/C,EAAaqF,cACnCuB,EAAa7C,EAAc4C,EAAQvF,EAAgB7wC,MACnD60C,EAAarB,EAAcvxC,EAAW4uC,EAAgB7zD,UACtDkjB,EAAgBg2C,EAAQ9F,EAAUC,QAAUthC,CAG5CmnC,KACA9F,EAAUG,IAAIv1C,GAAMo7C,GAGxBz4D,GAAGy4D,GAAQ1xD,SAASmrD,EAAoB70C,GACxC65C,EAAWr6C,gBAAgBy1C,GAEvBoG,IACA14D,GAAG04D,GAAY5wD,QAAQ9G,GACvB03D,EAAWpkD,aAAa,QAAStT,IAGrCy3D,EAAOnkD,aAAa29C,EAAc50C,GAE9Bg7C,EACAjB,EAAYqB,EAAQJ,EAAYl0D,MAAOoe,GAGvCA,EAAchO,YAAYkkD,GAG1BH,GACAG,EAAOxzD,MAAMC,QAAU,OACvBlF,GAAGy4D,GAAQ1xD,SAASyrD,KAGpBxtD,EAAKoxD,EAAY/4C,IACjBrY,EAAKqgB,EAAQhI,IACbrY,EAAKgxD,EAAU34C,IACfrY,EAAKqxD,EAASh5C,IACdrY,EAAKmxD,EAAS94C,IACdrY,EAAK8wD,EAAYz4C,IAEbw1C,GACA5wD,KAAK+pD,WAAW3uC,GAGpBm7C,EAAQpD,EAAa/3C,GACjBm7C,IAAUA,EAAMpoB,KAChBskB,EAA6Bx6C,KAAK,SAASy+C,GACvCH,EAAMpoB,IAAMuoB,EAAWvoB,IACnBuoB,EAAW1zD,MAAM0zB,WAAaggC,EAAW1zD,MAAM2zB,UAC/C54B,GAAGw4D,GAAOvyD,KACN0yB,UAAWggC,EAAW1zD,MAAM0zB,UAC5BC,SAAU+/B,EAAW1zD,MAAM2zB,WAInCs8B,GAAKsD,OAMrB7J,eAAgB,SAAStxC,EAAIrc,EAAMq3D,EAAaC,GAC5Cr2D,KAAKmc,QAAQf,EAAIrc,EAAMq3D,EAAaC,GAAa,IAGrDrR,cAAe,WACX71B,EAAS7c,YAAYk+C,EAAUC,SAC/BD,EAAUC,QAAUvlD,SAASwlD,yBAC7BF,EAAUG,QAGdnK,WAAY,SAASprC,GACjBrd,GAAGqkB,EAAQhH,IAAKtX,UAGpBqiD,UAAW,SAAShkD,GAChB,GAAIw0D,GAAcx0D,CAElB,IAAIw0D,EAAa,CAEb,KAAiD,MAA1CA,EAAYtwD,aAAa2pD,IAC5B2G,EAAcA,EAAY9yD,UAG9B,OAAOw+B,UAASs0B,EAAYtwD,aAAa2pD,MAIjD4G,YAAa,WACT,MAAOznC,IAGX85B,qBAAsB,SAAS7tC,GAC3B,GAAIvI,GAAWI,EAAYmI,EAE3BvI,IAAY9U,GAAG8U,GAAU/N,SAAS/H,EAAQstB,QAAQgkC,WAGtDxI,eAAgB,SAASzqC,EAAIrc,GACzB,GAAI83D,GAAa5jD,EAAYmI,EAEzBy7C,KACA94D,GAAG84D,GAAYhxD,QAAQ9G,GACvB83D,EAAWxkD,aAAa,QAAStT,KAIzC8pD,aAAc,SAASztC,GACnBrY,EAAKkQ,EAAYmI,KAGrB2tC,aAAc,SAAS3tC,GACnB63C,GAAKhgD,EAAYmI,KAGrB07C,WAAY,SAAS30D,GACjB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgB7wC,OAG3CqC,UAAW,WACP,MAAO1lB,GAAQmnB,QAAU0vC,EAAcvxC,EAAW4uC,EAAgB/sC,SAGtEwjC,mBAAoB,WAChB3kD,EAAKixD,MAGTvM,mBAAoB,WAChBwL,GAAKe,MAGTxM,YAAa,WACT,MAAOoM,GAAcvxC,EAAW4uC,EAAgBO,OAGpDtJ,uBAAwB,WACpB,MAAOyH,IAGXzG,UAAW,SAAS9tC,GAChBrY,EAAKqxD,EAASh5C,KAGlBmvC,gBAAiB,WACb,MAAOqF,IAGXpF,UAAW,SAASpvC,GAChB63C,GAAKmB,EAASh5C,KAGlBmqC,iBAAkB,SAASnqC,GACvB,MAAOgH,GAAQhH,IAGnB4tC,aAAc,SAAS5tC,GACnB,GAAI27C,GAAO9C,EAAY74C,EAEvB27C,IAAQh5D,GAAGg5D,GAAMjyD,SAAS/H,EAAQstB,QAAQgkC,WAG9C/I,gBAAiB,SAASlqC,GACtB,MAAOrd,IAAGqkB,EAAQhH,IAAK5W,SAAS+rD,IAGpCzH,aAAc,SAAS1tC,GACnB,GAAI27C,GAAO9C,EAAY74C,EAEvB27C,IAAQh5D,GAAGg5D,GAAMhyD,YAAYhI,EAAQstB,QAAQgkC,WAGjD2I,WAAY,SAAS70D,GACjB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBiB,cAAc,IAGzDvJ,aAAc,SAASvtC,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBgB,oBAGtDgF,YAAa,SAAS90D,GAClB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBgB,mBAAmB,IAG9DnI,eAAgB,SAAS1uC,EAAI+P,EAAQC,GACjC,GACIuqC,GADAC,EAAMzB,EAAY/4C,EAGlBw6C,IAAOxqC,EAAQ,IACfuqC,EAAUtxD,KAAKC,MAAM6mB,EAASC,EAAQ,KAEtB,MAAZuqC,EACA5yD,EAAK6yD,GAGL3C,GAAK2C,GAGTF,GAAoBt6C,EAAIu6C,KAIhCtZ,oBAAqB,SAASlxB,EAAQC,GAClCprB,KAAK8pD,eAAe,KAAM3+B,EAAQC,IAGtC4+B,aAAc,SAAS5uC,GACnB,GAAIw6C,GAAMzB,EAAY/4C,EAEtBw6C,IAAO7yD,EAAK6yD,IAGhBM,kBAAmB,WACfl2D,KAAKgqD,gBAGTsB,cAAe,SAASlwC,GACpBs6C,GAAoBt6C,EAAI,GACxBpb,KAAKk2D,kBAAkB96C,IAG3BquC,mBAAoB,WAChBzpD,KAAKsrD,iBAGThB,WAAY,SAASlvC,GACjB,IAAKw1C,EAAkB,CACnB,GAAIpwC,GAASmzC,EAAUv4C,EAEvBoF,IAAUziB,GAAGyiB,GAAQzb,YAAYhI,EAAQstB,QAAQtnB,QAIzDgnD,WAAY,SAAS3uC,GACjBrY,EAAK4wD,EAAUv4C,KAGnB87C,SAAU,SAAS/0D,GACf,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBzwC,QAAQ,IAGnDuqC,WAAY,SAAS3vC,GACjB63C,GAAKiB,EAAS94C,IACdrY,EAAK8wD,EAAYz4C,KAGrB0qC,aAAc,SAAS1qC,GACnBpb,KAAKmpD,cAAc/tC,EAAIre,EAAQ+I,KAAK2hC,QACpCznC,KAAKm3D,oBAAoB/7C,GACzBrY,EAAKsxD,EAAWj5C,KAGpBkuC,UAAW,SAASluC,GAChBrY,EAAKmxD,EAAS94C,KAGlBg8C,QAAS,SAASj1D,GACd,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgB75C,OAAO,IAGlDigD,iBAAkB,SAASl1D,GACvB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBa,gBAAgB,IAG3DqF,oBAAqB,SAAS/7C,GAC1B63C,GAAKY,EAAYz4C,IACjBrY,EAAKmxD,EAAS94C,KAGlB4qC,gBAAiB,SAAS5qC,GACtBpb,KAAKmpD,cAAc/tC,EAAI,IACvBpb,KAAK+qD,WAAW3vC,GAChB63C,GAAKoB,EAAWj5C,KAGpBwvC,iBAAkB,SAASxvC,GACvB63C,GAAKc,EAAU34C,KAGnBwwC,iBAAkB,SAASxwC,GACvBrY,EAAKgxD,EAAU34C,KAGnBk8C,eAAgB,SAASn1D,GACrB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBc,cAAc,IAGzDwF,QAAS,SAASp1D,GACd,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBtsC,OAAO,IAGlDpH,WAAY,SAASnC,EAAItV,GACrB,GAAIyW,GAAO6G,EAAQhI,EAEfmB,KACA02C,GAAK12C,GACLxe,GAAGwe,GAAM1W,QAAQC,KAIzBqjD,cAAe,SAAS/tC,EAAItV,GACxB,GAAI0xD,GAAS5D,EAAcxxC,EAAQhH,GAAK61C,EAAgBe,WAEpDwF,KAEY,MAAR1xD,EACA/H,GAAGy5D,GAAQvxD,YAGXlI,GAAGy5D,GAAQ3xD,QAAQC,KAK/B0jD,YAAa,SAASpuC,GAClBrd,GAAGqkB,EAAQhH,IAAKrW,YAAYurD,GAC5BvtD,EAAKsxD,EAAWj5C,KAGpB0vC,YAAa,SAAS1vC,GAClBrd,GAAGqkB,EAAQhH,IAAKtW,SAASwrD,GACzB2C,GAAKoB,EAAWj5C,KAGpByxC,gBAAiB,SAASzxC,EAAIk6C,EAAexzC,GACpC9hB,KAAKslD,gBAAgBlqC,KACtB21C,EAAqBlxD,MAAMub,GAAIA,EAAI0G,qBAAsBA,EAAsBwzC,cAAeA,KAC7FxE,GAAgCwC,MAIzC3G,gBAAiB,SAASvxC,EAAIsL,EAAc+uC,EAAgB3zC,GACnD9hB,KAAKslD,gBAAgBlqC,KACtB21C,EAAqBlxD,MAAMiiB,qBAAsBA,EAAsB0xC,QAAQ,EAAMp4C,GAAIA,EAAIsL,aAAcA,EAAc+uC,eAAgBA,KACxI3E,GAAgCwC,MAIzCzE,UAAW,SAAS1tD,GAChB,MAAOpD,IAAGiW,kBAAkB4C,iBAAmBk9C,EAAU3yD,IAG7D2tD,WAAY,SAAS3tD,EAAMf,EAAS4uD,GAChC,GAAIyI,GAAS3D,EAAU3yD,GACnBu2D,EAAY9D,EAAc6D,EAAQxG,EAAgBI,eAClDsG,EAAUF,EAAOlyD,qBAAqB,SAAS,GAC/CqyD,EAAYhE,EAAc6D,EAAQxG,EAAgBE,oBAClD0G,EAAQjE,EAAc6D,EAAQxG,EAAgBK,gBAC9CpkD,EAAU,GAAInP,IAAGoP,QAEjB2qD,EAAe,WACXF,EAAUt0D,oBAAoB,QAASy0D,GACvCF,GAASA,EAAMv0D,oBAAoB,QAAS00D,GAC5C9qD,EAAQK,WAGZwqD,EAAqB,WACjBH,EAAUt0D,oBAAoB,QAASy0D,GACvCN,EAAOQ,SAGXD,EAAiB,WACbP,EAAOn0D,oBAAoB,QAASw0D,GACpCD,EAAMv0D,oBAAoB,QAAS00D,GACnCP,EAAOQ,QAEP/qD,EAAQG,QAAQsqD,GAAWA,EAAQjvD,OAc3C,OAXA+uD,GAAOt0D,iBAAiB,QAAS20D,GACjCF,EAAUz0D,iBAAiB,QAAS40D,GACpCF,GAASA,EAAM10D,iBAAiB,QAAS60D,GAErCL,IACAA,EAAQjvD,MAAQsmD,GAEpB0I,EAAU1xD,YAAc5F,EAExBq3D,EAAOS,YAEAhrD,MC/gCnBnP,GAAGo6D,eAAiB,SAASC,EAAGC,GAC5B,YAqBA,SAASxO,GAAWppD,GAChB8S,EAASrQ,OAAOzC,EAAS2b,EAAKk8C,UAAW,SAAS7jC,GAE9CA,EAAQA,GAASttB,OAAOstB,KAGxB,IAAI7mB,GAAS6mB,EAAM7mB,QAAU6mB,EAAM8jC,UAEnCn8C,GAAKo8C,UAAU5qD,EAAQ6mB,KA3B/B,GAAIlhB,GAAW,GAAIxV,IAAGqV,eAClBgJ,GACIk8C,UAAW,QACXG,SAAU,KACVD,UAAW,SAAS5qD,EAAQ6mB,KAKpC12B,IAAGwG,OAAOvE,MACN6pD,WAAY,SAASppD,GACjBopD,EAAWppD,IAGf6S,QAAS,WACLC,EAASD,aAiBjBvV,GAAGwG,OAAO8zD,GACNK,kBAAmB,SAASzvD,GACxB,MAAOA,GAAK0vD,UAGhBC,kBAAmB,WACf,MAAOrlD,MAIfxV,GAAGwG,OAAO6X,EAAMg8C,GAEZh8C,EAAKq8C,UACL5O,EAAWztC,EAAKq8C,WClDxB16D,GAAG2oD,wBAA0B,SAAS0R,GAClC,YAqBA,SAASS,GAAajrD,EAAQ6mB,GAC1B12B,GAAGY,KAAKm6D,EAAgB,SAASC,EAAYjqC,GACzC,GACIpN,GADAs3C,EAA2BD,EAAWp7D,OAAO,GAAGC,cAAgBm7D,EAAWl7D,MAAM,EAGrF,IAAIue,EAAKkrC,WAAW,KAAO0R,GAA0BprD,GAKjD,MAJA8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC7P,GAAGoS,eAAeskB,GAClBrY,EAAKjc,IAAIpC,GAAG0L,OAAO,+DAAgE2S,EAAK6rC,UAAUvmC,GAASA,IAC3GoN,EAAQpN,IACD,IA7BnB,GAAIu3C,MACA78C,GACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBC,aAAc,SAASnmC,KACvB8J,SAAU,SAAS9J,KACnBomC,QAAS,SAASpmC,KAClBqmC,QAAS,SAASrmC,KAClBsmC,WAAY,SAAStmC,KACrBumC,UAAW,SAASvmC,MAExBo3C,GACIt4C,OAAQ,SAASpF,GAAMgB,EAAKoP,SAASpQ,IACrCuJ,MAAQ,SAASvJ,GAAMgB,EAAK0rC,QAAQ1sC,IACpC22C,aAAc,SAAS32C,GAAMgB,EAAKyrC,aAAazsC,IAC/ChE,MAAO,SAASgE,GAAMgB,EAAK2rC,QAAQ3sC,IACnC02C,eAAgB,SAAS12C,GAAMgB,EAAK4rC,WAAW5sC,IAkBvDrd,IAAGwG,OAAO6X,EAAMg8C,GAEhBh8C,EAAKk8C,UAAY,QACjBl8C,EAAKo8C,UAAYK,EACjBz8C,EAAKq8C,SAAWr8C,EAAKkrC,WAAWsP,cAEhC74D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo6D,eAAe/7C,EAAM68C,KC1ChDl7D,GAAGoqD,qBAAuB,SAASiQ,GAC/B,YAiBA,SAASS,GAAajrD,EAAQ6mB,GAC1B,GAAIrY,EAAKkrC,WAAWwP,WAAWlpD,IAAWwO,EAAKkrC,WAAW0P,WAAWppD,GAAS,CAC1E,GAAI8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC8N,EAASU,EAAKksC,kBAAkB5mC,EAGhChG,KAAW3d,GAAG2d,OAAOoC,YACrB1B,EAAKjc,IAAIpC,GAAG0L,OAAO,4DAA6D2S,EAAK6rC,UAAUvmC,GAASA,IACxG3jB,GAAGoS,eAAeskB,GAElBwkC,EAAqBC,mBAAmBx3C,EAAQ9T,GAAQ,KAzBpE,GAAIqrD,MACA78C,GACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBv9B,SACIjK,KAAM,iBACN8xC,aAAc,yBAElB5J,kBAAmB,SAAS5mC,KAC5BumC,UAAW,SAASvmC,KAG5B3jB,IAAGwG,OAAO6X,EAAMg8C,GAkBhBh8C,EAAKk8C,UAAY,QACjBl8C,EAAKo8C,UAAYK,EAEjB96D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo7D,oBAAoB/8C,EAAM68C,KCpCrDl7D,GAAGwrD,4BAA8B,SAAS6O,EAAGa,GACzC,YAaA,SAASG,GAAiBxrD,EAAQ6mB,GAC9B,GAAIrY,EAAKkrC,WAAW2P,YAAYrpD,GAAS,CACrC,GAAI8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC8N,EAASU,EAAKksC,kBAAkB5mC,EAEhChG,KAAW3d,GAAG2d,OAAOoC,YACrB1B,EAAKjc,IAAIpC,GAAG0L,OAAO,kEAAmE2S,EAAK6rC,UAAUvmC,GAASA,IAC9Gu3C,EAAqBC,mBAAmBx3C,EAAQ9T,KAlB5D,GAAIwO,IACIkrC,WAAY,KACZgB,kBAAmB,SAAS5mC,KAC5BvhB,IAAK,SAASC,EAASwnD,KAG1BqR,KACDA,MAgBJ78C,EAAKk8C,UAAY,UACjBl8C,EAAKo8C,UAAYY,EAEjBr7D,GAAGwG,OAAO6X,EAAMg8C,GAChBr6D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo7D,oBAAoB/8C,EAAM68C,KCzBrDl7D,GAAGqqD,0BAA4B,SAAShsC,GACpC,YAEAA,GAAKk8C,UAAY,QACjBl8C,EAAKq8C,SAAW,KAEhB16D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGwrD,4BAA4BntC,QCVvDre,GAAGo7D,oBAAsB,SAASf,EAAGa,GACjC,YAWA,SAASI,GAAyB33C,GAC9B,GAAI43C,GAAkBl9C,EAAK6rC,UAAUvmC,GACjC5O,EAASwmD,EAAgBvmD,YAAY,IAMzC,OAJID,GAAS,IACTwmD,EAAkBA,EAAgBtmD,OAAO,EAAGF,IAGzCwmD,EAGX,QAASC,GAAqB73C,GAC1B,GAAI83C,GAAWp9C,EAAK6rC,UAAUvmC,EAC9B,OAAO3jB,IAAG6U,aAAa4mD,GAI3B,QAASC,GAAiBC,EAAoBh4C,GAC1C,GACIi4C,GADAr8C,EAAUo8C,EAAmBhxD,KAGjBrK,UAAZif,GAAyBvf,GAAGsL,QAAQiU,GAASlb,OAAS,IACtDu3D,EAAgBJ,EAAqB73C,GAEfrjB,SAAlBs7D,IACAr8C,EAAUA,EAAU,IAAMq8C,GAG9Bv9C,EAAKmsC,UAAU7mC,EAAQpE,IAG3BlB,EAAKosC,sBAAsB9mC,GAAQ,GAIvC,QAASk4C,GAAyBjC,EAASj2C,GACvCu3C,EAAqBL,oBAAoB11D,OAAOy0D,EAAS,OAAQ,WAC7D8B,EAAiB9B,EAASj2C,KAKlC,QAASm4C,GAA6BlC,EAASj2C,GAC3Cu3C,EAAqBL,oBAAoB11D,OAAOy0D,EAAS,QAAS,SAASljC,GAEvE,GAAIpE,GAAOoE,EAAMqlC,SAAWrlC,EAAMslC,KAErB,MAAT1pC,GACAopC,EAAiB9B,EAASj2C,KAzDtC,GAAItF,IACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBU,kBAAmB,SAAS5mC,KAC5BumC,UAAW,SAASvmC,KACpB6mC,UAAW,SAAS7mC,EAAQpE,KAC5BkrC,sBAAuB,SAAS9mC,EAAQ+mC,KAwDhD1qD,IAAGwG,OAAO6X,EAAMg8C,GAEhBh8C,EAAKq8C,SAAWr8C,EAAKkrC,WAAWsP,cAEhC74D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo6D,eAAe/7C,EAAM68C,IAE5Cl7D,GAAGwG,OAAO00D,GACNC,mBAAoB,SAAS99C,EAAIxN,EAAQosD,GACrC,GAAIN,GAAqBt9C,EAAKkrC,WAAWqB,aAAavtC,EAEtDgB,GAAKosC,sBAAsBptC,GAAI,GAE/Bs+C,EAAmBhxD,MAAQ2wD,EAAyBj+C,GAEhD4+C,GACAN,EAAmBO,QAGvBL,EAAyBF,EAAoBt+C,GAC7Cy+C,EAA6BH,EAAoBt+C,Q7CvF9BjU","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function u(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var l,c,d,p,f,q,h,m,g,_,b,v,S,w,y;return l=e(),p=l&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&u(),f=d&&t(),q=p&&qq.isFileChunkingSupported(),h=p&&q&&s(),m=p&&n(),g=l&&(void 0!==window.postMessage||p),b=i(),_=o(),v=r(),S=a(),w=p&&void 0!==window.FileReader,y=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:v,deleteFileCorsXdr:_,deleteFileCorsXhr:b,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:f,folderSelection:S,imagePreviews:w,imageValidation:w,itemSizeValidation:p,pause:q,progressBar:y,resume:h,scaling:w&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:l,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return u[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function f(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function h(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=v.push(e);if(s<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,f=p.normalizeResponse(n,!1);f.reset?l.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,f,r)||p.cleanup(t,f,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,f=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&u.onResume(e,n,a)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===f.length?l.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),u.onUploadChunk(e,n,o._getChunkDataForCallback(a)),f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](u,{getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t),a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);l[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(h("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;h(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){h("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(h("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||h("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,f=r.inputName,q=s.getUuid,h=s.log,m=new qq.WindowReceiveMessage({log:h});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",f),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(h("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){h("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){h("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,u=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,l=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,h=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),u&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,l(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,u);return d[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=l(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){u&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(u&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);u&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,l(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(u&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:l(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=l(e),a={simple:function(t,n){var i=c(e);t===n?h(e,r,i,i):h(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,d=a,p=c(e),f=l-(d-i),q=u;s[t]=f,qq.each(s,function(e,t){q+=t}),h(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,f=u.width,q=u.height,h=s.getContext("2d"),m=new qq.Promise;return h.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:f}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:f,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",f,q,c.newWidth,c.newHeight),"warn"),f=c.newWidth,q=c.newHeight)),a(s,f,q,u.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*f/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===f?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===f&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function f(e,r,s){var u=new qq.Promise,c=s.scale,f=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,f):d(e,r,u,f):p(e,r,u,f):n(r)?d(e,r,u,f):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),f(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,u,l,c=a.slice(0,4),p=e?n(c):parseInt(c,16),f=o.indexOf(p);if(f>=0&&(u=d[p].name,l=d[p].bytes,s=a.slice(i,i+2*l),r[u]=e?n(s):parseInt(s,16),o.splice(f,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,f=[],q=d.blob?d.blob:d,h=new qq.Identify(q,t);return h.isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});f.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),f.push({uuid:e,name:c,size:q.size,blob:i?q:null})):f.push({uuid:e,name:c,size:q.size,blob:q}),f},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,f=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),f.addReadOnly(t,n)}),l.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,f.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,f,p,h,q,m,g,_,b,v,S,w;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),f=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),p=d&&qq.isFileChunkingSupported(),h=d&&p&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),b=o(),v=r(),S=d&&void 0!==window.FileReader,w=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:p,deleteFileCors:b,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:f,folderSelection:v,imagePreviews:S,imageValidation:S,itemSizeValidation:d,pause:p,progressBar:w,resume:h,scaling:S&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e]&&S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function f(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function p(e){return function(){s(e)}}function h(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){if(S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},v.push(e)<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=f.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),f.cleanup(e,s,a)},function(t,o){var r=f.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||f.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,p=f.normalizeResponse(n,!1);if(p.reset)l.reset(t);else{var h=o._getFileState(t).chunking.inProgress;d=h?qq.indexOf(h,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,p,r)||f.cleanup(t,p,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),p=d.attemptingResume,h=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),p&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),p=!1),null==r&&0===h.length)l.finalize(e);else{h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:p};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=f.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],f.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),f.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=f.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),f.maybeNewUuid(e,r),f.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=f.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||f.cleanup(e,r,o)})}},f={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),f.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),f.maybeSendDeferredFiles(e),c.free(e)}),!1):f.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(f.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,f.now(i);else if(f.isDeferredEligibleForUpload(i))return!1})):(n=!0,f.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=f.normalizeResponse(n.responseJSON,!1);f.cleanup(e,o)}})},start:function(e){var t=f.getProxyOrBlob(e);return t?f.maybeDefer(e,t):(f.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&f.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?f.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){f.cancel(e)}):t!==!1&&f.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),f.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],f&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[h(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},f=r.isCors,p=r.inputName,h=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",p),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;f?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,f=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,f=c[t]||qq.sliceBlob(r,s,u);return c[t]=f,{part:t,start:s,end:u,count:l,blob:f,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=p(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:f(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,f=d(e),p=l-(c-i),h=u;s[t]=p,qq.each(s,function(e,t){h+=t}),m(e,r,h,f)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,f=n.naturalHeight,p=u.width,h=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:f,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:h,targetWidth:p}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:p,origHeight:h}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",p,h,c.newWidth,c.newHeight),"warn"),p=c.newWidth,h=c.newHeight)),a(s,p,h,u.orientation),qq.ios()?function(){e(n)&&(d/=2,f/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,f):1,c=Math.ceil(a*p/d),m=Math.ceil(a*h/f/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===p?function(){var t=e.src;n(r.srcImage,r.blob,i,f).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===p&&o(this.srcImage,this.blob,e,i,f),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,f=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;f.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),f.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function f(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function p(e,r,s){var u=new qq.Promise,c=s.scale,p=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?f(e,r,u,p):d(e,r,u,p):f(e,r,u,p):n(r)?d(e,r,u,p):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),p(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),f=i.indexOf(c);if(f>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(f,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var f=this,p=[],h=d.blob?d.blob:d;return new qq.Identify(h,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=f._determineOutputType({defaultType:r,requestedType:i.type,refType:h.type});p.push({uuid:qq.getUniqueId(),name:f._getName(c,{name:i.name,type:l,refType:h.type}),blob:new qq.BlobProxy(h,qq.bind(f._generateScaledImage,f,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),p.push({uuid:e,name:c,size:h.size,blob:i?h:null})):p.push({uuid:e,name:c,size:h.size,blob:h}),p},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,f=s.uploadData,p=s.paramsStore,h=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=f.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:h}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):f.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:f.retrieve({id:c}).uuid,qqparentsize:f.retrieve({id:c}).size};n[a]=f.retrieve({id:t}).uuid,f.setParentId(t,c),p.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=f.retrieve({id:c}).uuid,p.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){f(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(f(e,0,i),n[e]={loaded:0,total:i})},f=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){f(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5533,12 +5793,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5566,6 +5821,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5653,9 +5916,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5695,8 +5955,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5721,6 +5983,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -5773,7 +6037,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -5856,6 +6120,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6584,7 +6850,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6716,7 +6982,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -6780,15 +7046,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -6894,13 +7160,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -6912,6 +7178,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -6921,7 +7188,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } @@ -7411,4 +7678,4 @@ }); }; })(window); -//# sourceMappingURL=fine-uploader.js.map +//# sourceMappingURL=fine-uploader.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.js.map b/styles/bootstrap/fine-uploader/fine-uploader.js.map index f04b96e4a..a87518cba 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
c&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===f?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===f&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function f(e,r,s){var u=new qq.Promise,c=s.scale,f=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,f):d(e,r,u,f):p(e,r,u,f):n(r)?d(e,r,u,f):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),f(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,u,l,c=a.slice(0,4),p=e?n(c):parseInt(c,16),f=o.indexOf(p);if(f>=0&&(u=d[p].name,l=d[p].bytes,s=a.slice(i,i+2*l),r[u]=e?n(s):parseInt(s,16),o.splice(f,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,f=[],q=d.blob?d.blob:d,h=new qq.Identify(q,t);return h.isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});f.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),f.push({uuid:e,name:c,size:q.size,blob:i?q:null})):f.push({uuid:e,name:c,size:q.size,blob:q}),f},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,f=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),f.addReadOnly(t,n)}),l.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,f.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,f,p,h,q,m,g,_,b,v,S,w;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),f=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),p=d&&qq.isFileChunkingSupported(),h=d&&p&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),b=o(),v=r(),S=d&&void 0!==window.FileReader,w=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:p,deleteFileCors:b,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:f,folderSelection:v,imagePreviews:S,imageValidation:S,itemSizeValidation:d,pause:p,progressBar:w,resume:h,scaling:S&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e]&&S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function f(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function p(e){return function(){s(e)}}function h(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){if(S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},v.push(e)<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=f.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),f.cleanup(e,s,a)},function(t,o){var r=f.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||f.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,p=f.normalizeResponse(n,!1);if(p.reset)l.reset(t);else{var h=o._getFileState(t).chunking.inProgress;d=h?qq.indexOf(h,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,p,r)||f.cleanup(t,p,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),p=d.attemptingResume,h=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),p&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),p=!1),null==r&&0===h.length)l.finalize(e);else{h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:p};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=f.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],f.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),f.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=f.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),f.maybeNewUuid(e,r),f.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=f.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||f.cleanup(e,r,o)})}},f={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),f.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),f.maybeSendDeferredFiles(e),c.free(e)}),!1):f.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(f.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,f.now(i);else if(f.isDeferredEligibleForUpload(i))return!1})):(n=!0,f.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=f.normalizeResponse(n.responseJSON,!1);f.cleanup(e,o)}})},start:function(e){var t=f.getProxyOrBlob(e);return t?f.maybeDefer(e,t):(f.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&f.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?f.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){f.cancel(e)}):t!==!1&&f.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),f.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],f&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[h(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},f=r.isCors,p=r.inputName,h=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",p),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;f?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,f=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,f=c[t]||qq.sliceBlob(r,s,u);return c[t]=f,{part:t,start:s,end:u,count:l,blob:f,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=p(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:f(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,f=d(e),p=l-(c-i),h=u;s[t]=p,qq.each(s,function(e,t){h+=t}),m(e,r,h,f)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,f=n.naturalHeight,p=u.width,h=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:f,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:h,targetWidth:p}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:p,origHeight:h}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",p,h,c.newWidth,c.newHeight),"warn"),p=c.newWidth,h=c.newHeight)),a(s,p,h,u.orientation),qq.ios()?function(){e(n)&&(d/=2,f/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,f):1,c=Math.ceil(a*p/d),m=Math.ceil(a*h/f/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===p?function(){var t=e.src;n(r.srcImage,r.blob,i,f).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===p&&o(this.srcImage,this.blob,e,i,f),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,f=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;f.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),f.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function f(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function p(e,r,s){var u=new qq.Promise,c=s.scale,p=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?f(e,r,u,p):d(e,r,u,p):f(e,r,u,p):n(r)?d(e,r,u,p):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),p(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),f=i.indexOf(c);if(f>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(f,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var f=this,p=[],h=d.blob?d.blob:d;return new qq.Identify(h,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=f._determineOutputType({defaultType:r,requestedType:i.type,refType:h.type});p.push({uuid:qq.getUniqueId(),name:f._getName(c,{name:i.name,type:l,refType:h.type}),blob:new qq.BlobProxy(h,qq.bind(f._generateScaledImage,f,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),p.push({uuid:e,name:c,size:h.size,blob:i?h:null})):p.push({uuid:e,name:c,size:h.size,blob:h}),p},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,f=s.uploadData,p=s.paramsStore,h=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=f.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:h}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):f.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:f.retrieve({id:c}).uuid,qqparentsize:f.retrieve({id:c}).size};n[a]=f.retrieve({id:t}).uuid,f.setParentId(t,c),p.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=f.retrieve({id:c}).uuid,p.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){f(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(f(e,0,i),n[e]={loaded:0,total:i})},f=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){f(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5533,12 +5793,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5566,6 +5821,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5653,9 +5916,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5695,8 +5955,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5721,6 +5983,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -5773,7 +6037,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -5856,6 +6120,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6584,7 +6850,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6716,7 +6982,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -6780,15 +7046,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -6894,13 +7160,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -6912,6 +7178,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -6921,7 +7188,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } @@ -7411,4 +7678,4 @@ }); }; })(window); -//# sourceMappingURL=fine-uploader.js.map +//# sourceMappingURL=fine-uploader.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.js.map b/styles/bootstrap/fine-uploader/fine-uploader.js.map index f04b96e4a..a87518cba 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,f,p,h,q,m,g,_,b,v,S,w;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),f=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),p=d&&qq.isFileChunkingSupported(),h=d&&p&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),b=o(),v=r(),S=d&&void 0!==window.FileReader,w=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:p,deleteFileCors:b,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:f,folderSelection:v,imagePreviews:S,imageValidation:S,itemSizeValidation:d,pause:p,progressBar:w,resume:h,scaling:S&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return w.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=S[e]&&S[e].xhr;return n||(n=t?t:w.cors.expected?o():qq.createXhrInstance(),S[e].xhr=n),n}function a(e){var t,n=qq.indexOf(v,e),i=w.maxConnections;delete S[e],v.splice(n,1),v.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=w.endpointStore.get(e),o=S[e].addToPath;return void 0!=o&&(i+="/"+o),b&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function f(e){var t=w.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function p(e){return function(){s(e)}}function h(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=w.customHeaders,s=S[e].additionalHeaders||{},u=w.method,l={};i(o)||(w.acceptHeader&&o.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",w.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(w.successfulResponseCodes[w.method],e)>=0}function g(e,t,n,i,o,r,a){if(S[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},v.push(e)<=w.maxConnections)return l(e,t)}var _,b,v=[],S={},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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(w,e),_=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");b="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=f.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),f.cleanup(e,s,a)},function(t,o){var r=f.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||f.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,p=f.normalizeResponse(n,!1);if(p.reset)l.reset(t);else{var h=o._getFileState(t).chunking.inProgress;d=h?qq.indexOf(h,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,p,r)||f.cleanup(t,p,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),p=d.attemptingResume,h=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),p&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),p=!1),null==r&&0===h.length)l.finalize(e);else{h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:p};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=f.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],f.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),f.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=f.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),f.maybeNewUuid(e,r),f.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=f.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||f.cleanup(e,r,o)})}},f={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),f.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),f.maybeSendDeferredFiles(e),c.free(e)}),!1):f.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(f.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,f.now(i);else if(f.isDeferredEligibleForUpload(i))return!1})):(n=!0,f.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=f.normalizeResponse(n.responseJSON,!1);f.cleanup(e,o)}})},start:function(e){var t=f.getProxyOrBlob(e);return t?f.maybeDefer(e,t):(f.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&f.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?f.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){f.cancel(e)}):t!==!1&&f.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),f.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],f&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[h(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},f=r.isCors,p=r.inputName,h=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",p),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;f?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,f=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,f=c[t]||qq.sliceBlob(r,s,u);return c[t]=f,{part:t,start:s,end:u,count:l,blob:f,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=p(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:f(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,f=d(e),p=l-(c-i),h=u;s[t]=p,qq.each(s,function(e,t){h+=t}),m(e,r,h,f)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,f=n.naturalHeight,p=u.width,h=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:f,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:h,targetWidth:p}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:p,origHeight:h}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",p,h,c.newWidth,c.newHeight),"warn"),p=c.newWidth,h=c.newHeight)),a(s,p,h,u.orientation),qq.ios()?function(){e(n)&&(d/=2,f/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,f):1,c=Math.ceil(a*p/d),m=Math.ceil(a*h/f/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===p?function(){var t=e.src;n(r.srcImage,r.blob,i,f).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===p&&o(this.srcImage,this.blob,e,i,f),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,f=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;f.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),f.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function f(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function p(e,r,s){var u=new qq.Promise,c=s.scale,p=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?f(e,r,u,p):d(e,r,u,p):f(e,r,u,p):n(r)?d(e,r,u,p):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),p(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),f=i.indexOf(c);if(f>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(f,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var f=this,p=[],h=d.blob?d.blob:d;return new qq.Identify(h,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=f._determineOutputType({defaultType:r,requestedType:i.type,refType:h.type});p.push({uuid:qq.getUniqueId(),name:f._getName(c,{name:i.name,type:l,refType:h.type}),blob:new qq.BlobProxy(h,qq.bind(f._generateScaledImage,f,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),p.push({uuid:e,name:c,size:h.size,blob:i?h:null})):p.push({uuid:e,name:c,size:h.size,blob:h}),p},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,f=s.uploadData,p=s.paramsStore,h=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=f.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:h}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):f.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:f.retrieve({id:c}).uuid,qqparentsize:f.retrieve({id:c}).size};n[a]=f.retrieve({id:t}).uuid,f.setParentId(t,c),p.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=f.retrieve({id:c}).uuid,p.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){f(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(f(e,0,i),n[e]={loaded:0,total:i})},f=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){f(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5533,12 +5793,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5566,6 +5821,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5653,9 +5916,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5695,8 +5955,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5721,6 +5983,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -5773,7 +6037,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -5856,6 +6120,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6584,7 +6850,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6716,7 +6982,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -6780,15 +7046,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -6894,13 +7160,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -6912,6 +7178,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -6921,7 +7188,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } @@ -7411,4 +7678,4 @@ }); }; })(window); -//# sourceMappingURL=fine-uploader.js.map +//# sourceMappingURL=fine-uploader.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.js.map b/styles/bootstrap/fine-uploader/fine-uploader.js.map index f04b96e4a..a87518cba 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA;ICEV,IAAIC,KAAK,SAASC;QACd;QAEA;YACIC,MAAM;gBACFD,QAAQE,MAAMC,UAAU;gBACxB,OAAOC;;YAIXC,QAAQ,SAASC,MAAMC;gBACnB,IAAIP,QAAQQ,kBAAkB;oBAC1BR,QAAQQ,iBAAiBF,MAAMC,IAAI;uBAChC,IAAIP,QAAQS,aAAa;oBAC5BT,QAAQS,YAAY,OAAOH,MAAMC;;gBAErC,OAAO;oBACHR,GAAGC,SAASU,OAAOJ,MAAMC;;;YAIjCG,QAAQ,SAASJ,MAAMC;gBACnB,IAAIP,QAAQW,qBAAqB;oBAC7BX,QAAQW,oBAAoBL,MAAMC,IAAI;uBACnC,IAAIP,QAAQS,aAAa;oBAC5BT,QAAQY,YAAY,OAAON,MAAMC;;gBAErC,OAAOH;;YAGXS,UAAU,SAASC;gBAKf,KAAKA,YAAY;oBACb,OAAO;;gBAIX,IAAId,YAAYc,YAAY;oBACxB,OAAO;;gBAGX,IAAId,QAAQa,UAAU;oBAClB,OAAOb,QAAQa,SAASC;uBACrB;oBAEH,UAAUA,WAAWC,wBAAwBf,WAAW;;;YAOhEgB,cAAc,SAASC;gBACnBA,SAASC,WAAWF,aAAahB,SAASiB;gBAC1C,OAAOb;;YAGXe,QAAQ;gBACJnB,QAAQkB,WAAWE,YAAYpB;gBAC/B,OAAOI;;YAOXiB,KAAK,SAASC;gBAEV,IAAItB,QAAQE,SAAS,MAAM;oBACvB,MAAM,IAAIH,GAAGwB,MAAM;;gBAIvB,IAAID,OAAOE,WAAW,MAAM;oBACxB,WAAWxB,QAAQE,MAAMsB,YAAY,mBAAoBxB,QAAe,YAAM,aAAa;wBACvFsB,OAAOG,SAAS,mBAAmBC,KAAKC,MAAM,MAAML,OAAOE,WAAW;;;gBAG9EzB,GAAG6B,OAAO5B,QAAQE,OAAOoB;gBAEzB,OAAOlB;;YAGXyB,UAAU,SAASC,MAAMC;gBACrB,IAAIC,KAAK,IAAIC,OAAO,UAAUH,OAAO;gBACrC,OAAOE,GAAGE,KAAKlC,QAAQmC,iBAAiBJ,kBAAkBC,GAAGE,KAAKlC,QAAQkB,WAAWiB;;YAGzFC,UAAU,SAASN;gBACf,KAAK/B,GAAGC,SAAS6B,SAASC,OAAO;oBAC7B9B,QAAQmC,aAAa,MAAML;;gBAE/B,OAAO1B;;YAGXiC,aAAa,SAASP;gBAClB,IAAIE,KAAK,IAAIC,OAAO,UAAUH,OAAO;gBACrC9B,QAAQmC,YAAYnC,QAAQmC,UAAUG,QAAQN,IAAI,KAAKM,QAAQ,cAAc;gBAC7E,OAAOlC;;YAGXmC,YAAY,SAASJ,WAAWK;gBAC5B,IAAIC,YACAC;gBAEJ,IAAIF,SAASxC,QAAQ2C,eAAe;oBAChC,OAAO3C,QAAQ2C,cAAc,MAAMR;uBAElC,IAAInC,QAAQ4C,kBAAkB;oBAC/B,OAAO5C,QAAQ4C,iBAAiB,MAAMT;;gBAG1CM,aAAazC,QAAQ6C,qBAAqB;gBAE1C9C,GAAG+C,KAAKL,YAAY,SAASM,KAAKC;oBAC9B,IAAIjD,GAAGiD,KAAKnB,SAASM,YAAY;wBAC7BO,OAAOO,KAAKD;;;gBAGpB,OAAOR,QAAQE,OAAO,KAAKA;;YAG/BQ,iBAAiB,SAASf;gBACtB,OAAOpC,GAAGC,SAASuC,WAAWJ,WAAW;;YAG7CgB,UAAU;gBACN,IAAIA,eACAC,QAAQpD,QAAQqD;gBAEpB,OAAOD,OAAO;oBACV,IAAIA,MAAME,aAAa,GAAG;wBACtBH,SAASF,KAAKG;;oBAElBA,QAAQA,MAAMG;;gBAGlB,OAAOJ;;YAGXK,SAAS,SAASC;gBACdzD,QAAQ0D,YAAYD;gBACpBzD,QAAQ2D,cAAcF;gBACtB,OAAOrD;;YAGXwD,WAAW;gBACP,OAAO7D,GAAGC,SAASwD,QAAQ;;YAK/BK,cAAc,SAASC;gBACnB,IAAIC;gBAEJ,IAAI/D,QAAQ6D,cAAc;oBAEtB,KAAK7D,QAAQ6D,aAAaC,WAAW;wBACjC,OAAO;;oBAIX,OAAO,WAAaE,KAAKhE,QAAQiE,aAAaH,cAAc;uBAE3D;oBACDC,UAAU/D,QAAQ8D;oBAElB,IAAIC,YAAYG,WAAW;wBACvB,OAAO;;oBAIX,OAAO,WAAaF,KAAKD,YAAY;;;;;KAMpD;QACG;QAEAhE,GAAGoE,eAAe,SAASC,QAAQC,MAAMC;YACrC,OAAOvE,GAAGwE,cAAcH,OAAOI,UAAUH,MAAMC;;QAGnDvE,GAAGwE,gBAAgB,SAASE;YACxB,IAAIC,aAAaC,YACbC,aAAa,SAASC,MAAMR;gBACxB,IAAIS,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;gBAErC,IAAIK,aAAa;oBACbA,YAAYC,OAAOP;oBACnB,OAAOM,YAAYE,QAAQhB;uBAE1B;oBACD,OAAO,IAAIiB,OAAMT;wBAAQvE,MAAM+D;;;eAGvCkB,UAAUC;YAGd,IAAIf,QAAQgB,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cf,aAAagB,KAAKlB,QAAQgB,MAAM,KAAK;mBAEpC;gBACDd,aAAaiB,UAAUnB,QAAQgB,MAAM,KAAK;;YAI9CD,aAAaf,QAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBf,cAAc,IAAImB,YAAYlB,WAAWmB;YACzCP,WAAW,IAAIQ,WAAWrB;YAC1B3E,GAAG+C,KAAK6B,YAAY,SAAS5B,KAAKiD;gBAC9BT,SAASxC,OAAOiD,UAAUC,WAAW;;YAGzC,OAAOrB,WAAWF,aAAac;;QAGnCzF,GAAGmG,MAAM,SAASC,SAASC;YACvB,IAAIrB,OAAOsB,SAAS;gBAChB,KAAKD,SAASA,UAAU,QAAQ;oBAC5BrB,OAAOsB,QAAQH,IAAIC;uBAGvB;oBACI,IAAIpB,OAAOsB,QAAQD,QAAQ;wBACvBrB,OAAOsB,QAAQD,OAAOD;2BAErB;wBACDpB,OAAOsB,QAAQH,IAAI,MAAME,QAAQ,OAAOD;;;;;QAMxDpG,GAAGuG,WAAW,SAASC;YACnB,OAAOA,aAAaA,SAASjD,YAAYkD,OAAOC,UAAUC,SAASC,KAAKJ,cAAc;;QAG1FxG,GAAG6G,aAAa,SAASL;YACrB,cAAc,aAAe;;QASjCxG,GAAG8G,UAAU,SAASC;YAClB,OAAON,OAAOC,UAAUC,SAASC,KAAKG,WAAW,oBAC5CA,SAAS/B,OAAOc,eAAeiB,MAAMC,UAAUD,MAAMC,OAAOC,gBAAgBnB;;QAIrF9F,GAAGkH,aAAa,SAASC;YACrB,OAAOV,OAAOC,UAAUC,SAASC,KAAKO,mBAAmB;;QAK7DnH,GAAGoH,aAAa,SAASC;YACrB,OAAOZ,OAAOC,UAAUC,SAASC,KAAKS,mBAAmB,uBAGpDA,cAAcC,QAAQD,cAAcE;;QAG7CvH,GAAGwH,WAAW,SAASC;YACnB,OAAOhB,OAAOC,UAAUC,SAASC,KAAKa,iBAAiB;;QAG3DzH,GAAG0H,UAAU,SAASC;YAClB,IAAIC,OAAOlB,UAAUmB,MAAM;gBACvB,OAAOF,OAAOE;;YAGlB,OAAOF,OAAOpF,QAAQ,cAAc;;QAOxCvC,GAAG8H,SAAS,SAASC;YAEjB,IAAIC,OAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW,IAC9CC,SAASL,KACTM,mBAAmBD,OAAOzC,QAAQ;YAEtC3F,GAAG+C,KAAKiF,MAAM,SAAShF,KAAKC;gBACxB,IAAIqF,YAAYF,OAAOG,UAAU,GAAGF,mBAChCG,WAAWJ,OAAOG,UAAUF,mBAAmB;gBAEnDD,SAASE,YAAYrF,MAAMuF;gBAC3BH,mBAAmBD,OAAOzC,QAAQ,MAAM0C,mBAAmBpF,IAAI8C;gBAG/D,IAAIsC,mBAAmB,GAAG;oBACtB,OAAO;;;YAIf,OAAOD;;QAGXpI,GAAGyI,SAAS,SAASC;YACjB,OAAO1D,OAAO2D,QAAQlC,OAAOC,UAAUC,SAASC,KAAK8B,eAAe;;QAGxE1I,GAAG4I,aAAa,SAASC;YACrB,OAAO7D,OAAO8D,YAAYrC,OAAOC,UAAUC,SAASC,KAAKiC,mBAAmB;;QAGhF7I,GAAG+I,gBAAgB,SAASC;YACxB,OAAOhJ,GAAGyI,OAAOO,qBAAqBhJ,GAAGiJ,QAAQD;;QAGrDhJ,GAAGiJ,UAAU,SAASC,YAAYC;YAC9B,IAAIC,eAAe,SAAS7I;gBACxB,IAAI8I,iBAAiB9I,KAAK+I;gBAE1B,IAAIH,SAAS;oBACT,OAAOE,mBAAmB;;gBAG9B,OAAOA,mBAAmB;;YAG9B,IAAIrE,OAAOuE,kBAAkB;gBACzB,IAAI9C,OAAOC,UAAUC,SAASC,KAAKsC,gBAAgB,6BAA6B;oBAC5E,IAAIA,WAAW3I,QAAQ6I,aAAaF,WAAW3I,OAAO;wBAClD,OAAO;;;;YAInB,IAAI2I,WAAWM,SAAS;gBACpB,IAAIN,WAAWM,QAAQF,kBAAkB,SAAS;oBAC9C,IAAIJ,WAAW3I,QAAQ6I,aAAaF,WAAW3I,OAAO;wBAClD,OAAO;;;;YAKnB,OAAO;;QAGXP,GAAGyJ,SAAS,SAASC;YACjB,IAAI1E,OAAOO,QAAQkB,OAAOC,UAAUC,SAASC,KAAK8C,eAAe,iBAAiB;gBAC9E,OAAO;;;QAIf1J,GAAG2J,uBAAuB;YACtB,IAAIC,QAAQC,SAASC,cAAc;YACnCF,MAAMrJ,OAAO;YAEb,OACIqJ,MAAMG,aAAa5F,oBACRwE,SAAS,sBACTqB,aAAa,sBACZhK,GAAGiK,oBAAqBC,WAAW;;QAIvDlK,GAAGiK,oBAAoB;YACnB,IAAIjF,OAAOmF,gBAAgB;gBACvB,OAAO,IAAIA;;YAGf;gBACI,OAAO,IAAIC,cAAc;cAE7B,OAAOC;gBACHrK,GAAGmG,IAAI,yCAAyC;gBAChD,OAAO;;;QAIfnG,GAAGsK,wBAAwB,SAASC;YAChC,OAAOA,aAAaC,SAChBD,aAAaC,MAAMzE,SAAS,KAC5BwE,aAAaC,MAAM,GAAGC;;QAG9BzK,GAAG0K,0BAA0B;YACzB,QAAQ1K,GAAG2K,kBACP3K,GAAG2J,2BACFhB,KAAKjC,UAAUwB,UAAU/D,aAAawE,KAAKjC,UAAUkE,gBAAgBzG,aAAawE,KAAKjC,UAAUmE,aAAa1G;;QAGvHnE,GAAG8K,YAAY,SAASC,YAAYC,OAAOC;YACvC,IAAIC,SAASH,WAAW7C,SAAS6C,WAAWF,YAAYE,WAAWH;YAEnE,OAAOM,OAAOtE,KAAKmE,YAAYC,OAAOC;;QAG1CjL,GAAGmL,mBAAmB,SAASnE;YAC3B,IAAIoE,aAAa,IACbC,QAAQ,IAAIrF,WAAWgB;YAE3BhH,GAAG+C,KAAKsI,OAAO,SAASrI,KAAKsI;gBACzB,IAAIC,eAAeD,IAAI3E,SAAS;gBAEhC,IAAI4E,aAAaxF,SAAS,GAAG;oBACzBwF,eAAe,MAAMA;;gBAGzBH,cAAcG;;YAGlB,OAAOH;;QAGXpL,GAAGwL,gBAAgB,SAASC,MAAMC,aAAa3F;YAC3C,IAAI4F,cAAc3L,GAAG8K,UAAUW,MAAMC,aAAaA,cAAc3F,SAC5D6F,aAAa,IAAIC,cACjBC,UAAU,IAAI9L,GAAG+L;YAErBH,WAAWI,SAAS;gBAChBF,QAAQG,QAAQjM,GAAGmL,iBAAiBS,WAAWjJ;;YAGnDiJ,WAAWM,UAAUJ,QAAQK;YAE7BP,WAAWQ,kBAAkBT;YAE7B,OAAOG;;QAGX9L,GAAG6B,SAAS,SAASY,OAAO4J,QAAQC;YAChCtM,GAAG+C,KAAKsJ,QAAQ,SAASE,MAAMtJ;gBAC3B,IAAIqJ,gBAAgBtM,GAAGuG,SAAStD,MAAM;oBAClC,IAAIR,MAAM8J,UAAUpI,WAAW;wBAC3B1B,MAAM8J;;oBAEVvM,GAAG6B,OAAOY,MAAM8J,OAAOtJ,KAAK;uBAE3B;oBACDR,MAAM8J,QAAQtJ;;;YAItB,OAAOR;;QAaXzC,GAAGwM,WAAW,SAASC,QAAQC;YAC3B,IAAIC,aACAC,SAASF,SAASC;YAEtB3M,GAAG+C,KAAK6J,QAAQ,SAASC,aAAaC;gBAClC,IAAIL,OAAOI,iBAAiB1I,WAAW;oBACnCwI,OAAOE,eAAeJ,OAAOI;;gBAGjCJ,OAAOI,eAAeC;;YAG1B,OAAOL;;QAMXzM,GAAG2F,UAAU,SAASoH,KAAKC,KAAKC;YAC5B,IAAIF,IAAIpH,SAAS;gBACb,OAAOoH,IAAIpH,QAAQqH,KAAKC;;YAG5BA,OAAOA,QAAQ;YACf,IAAIC,MAAMH,IAAIhH;YAEd,IAAIkH,OAAO,GAAG;gBACVA,QAAQC;;YAGZ,MAAOD,OAAOC,KAAKD,QAAQ,GAAG;gBAC1B,IAAIF,IAAII,eAAeF,SAASF,IAAIE,UAAUD,KAAK;oBAC/C,OAAOC;;;YAGf,QAAQ;;QAIZjN,GAAGoN,cAAc;YACb,OAAO,uCAAuC7K,QAAQ,SAAS,SAAS8K;gBAEpE,IAAIC,IAAI3L,KAAK4L,WAAW,KAAK,GAAGC,IAAIH,KAAK,MAAMC,IAAKA,IAAI,IAAM;gBAC9D,OAAOE,EAAE7G,SAAS;;;QAM1B3G,GAAGyN,KAAK;YACJ,OAAOC,UAAUC,UAAUhI,QAAQ,aAAa,KAC5C+H,UAAUC,UAAUhI,QAAQ,gBAAgB;;QAGpD3F,GAAG4N,MAAM;YACL,OAAOF,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG6N,MAAM;YACL,OAAOH,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG8N,OAAO;YACN,OAAOJ,UAAUC,UAAUhI,QAAQ,gBAAgB;;QAGvD3F,GAAG+N,OAAO;YACN,OAAO/N,GAAGyN,QAAQC,UAAUC,UAAUhI,QAAQ,cAAc;;QAGhE3F,GAAGgO,OAAO;YACN,OAAON,UAAUC,UAAUhI,QAAQ,WAAW;;QAGlD3F,GAAGiO,SAAS;YACR,OAAOP,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,cAAc;;QAGpF3F,GAAGmO,SAAS;YACR,OAAOT,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,eAAe;;QAGrF3F,GAAGoO,QAAQ;YACP,OAAOV,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,cAAc;;QAGpF3F,GAAGqO,UAAU;YACT,QAASrO,GAAGgO,WAAWhO,GAAG+N,UAAUL,UAAUC,UAAUhI,QAAQ,gBAAgB,KAAK+H,UAAUQ,WAAW/J,aAAauJ,UAAUQ,WAAW;;QAGhJlO,GAAGsO,UAAU;YACT,OAAOZ,UAAUa,aAAa;;QAGlCvO,GAAGwO,UAAU;YACT,OAAOd,UAAUC,UAAUrE,cAAc3D,QAAQ,gBAAgB;;QAKrE3F,GAAG2K,eAAe;YACd,OAAO3K,GAAGwO,aAAad,UAAUC,UAAUrE,cAAc3D,QAAQ,YAAY;;QAGjF3F,GAAGyO,OAAO;YACN,OAAOzO,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGlE3F,GAAG2O,OAAO;YACN,OAAO3O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGlE3F,GAAG4O,OAAO;YACN,OAAO5O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAIlE3F,GAAG6O,SAAS;YACR,OAAO7O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,iBAAiB;;QAGpE3F,GAAG0O,MAAM;YAEL,OAAOhB,UAAUC,UAAUhI,QAAQ,aAAa,KACzC+H,UAAUC,UAAUhI,QAAQ,aAAa,KACzC+H,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG8O,YAAY;YACX,OAAO9O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,cAAc;;QAGjE3F,GAAG+O,YAAY;YACX,OAAO/O,GAAG0O,UAAU1O,GAAG8O,eAAepB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGrF3F,GAAGgP,mBAAmB;YAClB,OAAOhP,GAAG0O,UAAU1O,GAAG8O,gBAAgB9O,GAAG+O;;QAM9C/O,GAAGiP,iBAAiB,SAASC;YACzB,IAAIA,EAAED,gBAAgB;gBAClBC,EAAED;mBACC;gBACHC,EAAEC,cAAc;;;QAQxBnP,GAAGoP,YAAa;YACZ,IAAIC,MAAMxF,SAASC,cAAc;YACjC,OAAO,SAASwF;gBACZD,IAAIE,YAAYD;gBAChB,IAAIrP,UAAUoP,IAAI/L;gBAClB+L,IAAIhO,YAAYpB;gBAChB,OAAOA;;;QAKfD,GAAG+C,OAAO,SAASyM,cAAcC;YAC7B,IAAIC,YAAYC;YAEhB,IAAIH,cAAc;gBAEd,IAAIxK,OAAO4K,WAAWJ,aAAavI,gBAAgBjC,OAAO4K,SAAS;oBAC/D,KAAKF,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASD,aAAaK,IAAIH,aAAaF,aAAaM,QAAQN,aAAaK,IAAIH;wBACtF,IAAIC,WAAW,OAAO;4BAClB;;;uBAMP,IAAI3P,GAAG8G,QAAQ0I,iBAAiBxP,GAAGkH,WAAWsI,iBAAiBxP,GAAGoH,WAAWoI,eAAe;oBAC7F,KAAKE,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASC,YAAYF,aAAaE;wBAC3C,IAAIC,WAAW,OAAO;4BAClB;;;uBAIP,IAAI3P,GAAGwH,SAASgI,eAAe;oBAChC,KAAKE,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASC,YAAYF,aAAaO,OAAOL;wBAClD,IAAIC,WAAW,OAAO;4BAClB;;;uBAIP;oBACD,KAAKD,cAAcF,cAAc;wBAC7B,IAAI/I,OAAOC,UAAUyG,eAAevG,KAAK4I,cAAcE,aAAa;4BAChEC,SAASF,SAASC,YAAYF,aAAaE;4BAC3C,IAAIC,WAAW,OAAO;gCAClB;;;;;;;QASxB3P,GAAGgQ,OAAO,SAASC,SAASC;YACxB,IAAIlQ,GAAG6G,WAAWoJ,UAAU;gBACxB,IAAIjI,OAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW;gBAElD,OAAO;oBACH,IAAIgI,UAAUnQ,GAAG6B,WAAWmG;oBAC5B,IAAIG,UAAUpC,QAAQ;wBAClBoK,UAAUA,QAAQC,OAAOnI,MAAMvB,UAAUwB,MAAMtB,KAAKuB;;oBAExD,OAAO8H,QAAQI,MAAMH,SAASC;;;YAItC,MAAM,IAAI3O,MAAM;;QAmBpBxB,GAAGsQ,UAAU,SAASC,KAAKC,MAAMC;YAE7B,IAAIC,iBACAC,SAAS,KACTC,MAAM,SAASC,SAASC;gBACpB,IAAIC,WAAWP,OACR,QAAQrO,KAAKqO,QACdA,OACAA,OAAO,MAAMM,IAAI,MACjBA;gBACN,IAAKC,aAAa,eAAiBD,MAAM,aAAc;oBACnDJ,WAAWxN,YACC2N,YAAY,WACd7Q,GAAGsQ,QAAQO,SAASE,UAAU,QAC7BtK,OAAOC,UAAUC,SAASC,KAAKiK,aAAa,sBAC7CG,mBAAmBD,YAAY,MAAMC,mBAAmBH,aACxDG,mBAAmBD,YAAY,MAAMC,mBAAmBH;;;YAK9E,KAAKJ,cAAcD,MAAM;gBACrBG,SAAU,KAAKxO,KAAKqO,QAAU,MAAMrO,KAAKqO,QAAS,KAAK,MAAM;gBAC7DE,WAAWxN,KAAKsN;gBAChBE,WAAWxN,KAAKlD,GAAGsQ,QAAQC;mBACxB,IAAK9J,OAAOC,UAAUC,SAASC,KAAK2J,SAAS,2BAA6BA,QAAQ,aAAc;gBACnGvQ,GAAG+C,KAAKwN,KAAK,SAASvN,KAAKC;oBACvB2N,IAAI3N,KAAKD;;mBAEV,WAAYuN,QAAQ,eAAiBA,QAAQ,eAAiBA,QAAQ,UAAW;gBACpFvQ,GAAG+C,KAAKwN,KAAK,SAAShE,MAAMtJ;oBACxB2N,IAAI3N,KAAKsJ;;mBAEV;gBACHmE,WAAWxN,KAAK8N,mBAAmBR,QAAQ,MAAMQ,mBAAmBT;;YAGxE,IAAIC,MAAM;gBACN,OAAOE,WAAWO,KAAKN;mBACpB;gBACH,OAAOD,WAAWO,KAAKN,QAClBpO,QAAQ,MAAM,IACdA,QAAQ,QAAQ;;;QAI7BvC,GAAGkR,eAAe,SAASX,KAAKY,UAAUC;YACtC,KAAKD,UAAU;gBACXA,WAAW,IAAInH;;YAGnBhK,GAAG+C,KAAKwN,KAAK,SAASV,KAAK5M;gBACvB4M,MAAMuB,eAAeA,eAAe,MAAMvB,MAAM,MAAMA;gBAEtD,IAAI7P,GAAGuG,SAAStD,MAAM;oBAClBjD,GAAGkR,aAAajO,KAAKkO,UAAUtB;uBAE9B,IAAI7P,GAAG6G,WAAW5D,MAAM;oBACzBkO,SAAS9L,OAAOwK,KAAK5M;uBAEpB;oBACDkO,SAAS9L,OAAOwK,KAAK5M;;;YAI7B,OAAOkO;;QAGXnR,GAAGqR,aAAa,SAASd,KAAKe;YAC1B,IAAI1H;YAEJ,KAAK0H,MAAM;gBACPA,OAAOzH,SAASC,cAAc;;YAGlC9J,GAAGkR,aAAaX;gBACZlL,QAAQ,SAASwK,KAAK5M;oBAClB2G,QAAQC,SAASC,cAAc;oBAC/BF,MAAM2H,aAAa,QAAQ1B;oBAC3BjG,MAAM2H,aAAa,SAAStO;oBAC5BqO,KAAKE,YAAY5H;;;YAIzB,OAAO0H;;QAOXtR,GAAGyR,YAAY,SAASC;YAEpB,IAAI1M,OAAO2M,QAAQ3R,GAAG6G,WAAW8K,KAAKC,QAAQ;gBAC1C,OAAOD,KAAKC,MAAMF;mBACf;gBACH,OAAOG,KAAK,MAAMH,OAAO;;;QAUjC1R,GAAG8R,eAAe,SAASC;YACvB,IAAIC,SAASD,SAASE,YAAY,OAAO;YAEzC,IAAID,SAAS,GAAG;gBACZ,OAAOD,SAASG,OAAOF,QAAQD,SAAShM,SAASiM;;;QAIzDhS,GAAGmS,cAAc,SAASC;YAGtB,IAAIpS,GAAGiJ,QAAQmJ,kBAAkB;gBAE7B,OAAOA,gBAAgBrL,MAAMxE,QAAQ,aAAa;mBAEjD,IAAIvC,GAAGyI,OAAO2J,kBAAkB;gBACjC,IAAIA,gBAAgBC,aAAa,QAAQD,gBAAgBC,aAAalO,WAAW;oBAC7E,OAAOiO,gBAAgBC;;;YAI/B,OAAOD,gBAAgBrQ;;QAM3B/B,GAAGsS,iBAAiB;YAChB,IAAIC;YAEJ;gBAEIC,SAAS;oBACL,IAAIC;oBACJ,GAAG;wBACCA,WAAWF,UAAUG;wBACrB,IAAID,UAAU;4BACVA;;6BAGDA;;gBAIXnS,QAAQ;oBACJ,IAAI0H,OAAOG;oBAEX9H,KAAKsS,YAAY3S,GAAGgI,KAAK,IAAI1H,OAAO+P,MAAMhQ,MAAM4H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW;;gBAI1FwK,aAAa,SAASC;oBAClBL,UAAUrP,KAAK0P;;;;;KCt2B9B;QACG;QACA,WAAWC,WAAW,cAAcA,OAAOC,KAAK;YAC5CD,OAAO;gBACH,OAAO7S;;eAGV,WAAW+S,WAAW,eAAeA,OAAOC,SAAS;YACtDD,OAAOC,UAAUhT;eAEhB;YACDD,OAAOC,KAAKA;;;KCRnB;QACG;QAEAA,GAAGwB,QAAQ,SAAS4E;YAChB/F,KAAK+F,UAAU,oBAAoBpG,GAAGiT,UAAU,OAAO7M;;QAG3DpG,GAAGwB,MAAMkF,YAAY,IAAIlF;;ICV7BxB,GAAGiT,UAAU;ICAbjT,GAAGkT,oBAAqB;QACpB;QAEA,IAAIC,mBACAC,wBACAC,kBACAC,2BACAC,oBACAC,kBACAC,gBACAC,wBACAC,oBACAC,uBACAC,2BACAC,wBACAC,yBACAC,uBACAC;QAEJ,SAASC;YACL,IAAIC,YAAY,MACZC;YAEJ;gBACIA,YAAYvK,SAASC,cAAc;gBACnCsK,UAAU7T,OAAO;gBACjBP,GAAGoU,WAAWlU;gBAEd,IAAIkU,UAAUC,UAAU;oBACpBF,YAAY;;cAGpB,OAAOG;gBACHH,YAAY;;YAGhB,OAAOA;;QAIX,SAASI;YACL,QAAQvU,GAAGmO,YAAYnO,GAAGoO,YACtBV,UAAUC,UAAU6G,MAAM,2CAA2CrQ;;QAI7E,SAASsQ;YACL,IAAIzP,OAAOmF,gBAAgB;gBACvB,IAAIuK,MAAM1U,GAAGiK;gBAGb,OAAOyK,IAAIC,oBAAoBxQ;;YAGnC,OAAO;;QAIX,SAASyQ;YACL,OAAO5P,OAAO6P,mBAAmB1Q;;QAKrC,SAAS2Q;YACL,IAAIL,6BAA6B;gBAC7B,OAAO;;YAGX,OAAOG;;QAGX,SAASG;YAEL,OAAOlL,SAASC,cAAc,SAASkL,oBAAoB7Q;;QAG/D,SAAS8Q;YACL;gBACI,SAASjQ,OAAOkQ,gBAEZlV,GAAG6G,WAAW7B,OAAOkQ,aAAaC;cAE1C,OAAO9K;gBAEH,OAAO;;;QAIf,SAAS+K;YACL,IAAIC,OAAOxL,SAASC,cAAc;YAElC,QAAQ,eAAeuL,QAAS,iBAAiBA,QAAQ,YAAYA,UAChErV,GAAGwO,cAAcxO,GAAG0O;;QAG7ByE,oBAAoBe;QAEpBZ,4BAA4BH,qBAAqBnT,GAAG2J;QAEpDyJ,yBAAyBE,8BAA8BtT,GAAG2K;QAE1D0I,mBAAmBC,6BAA6B8B;QAGhD7B,qBAAqBF,oBAAqB;YACtC,IAAIzJ,QAAQC,SAASC,cAAc;YAEnCF,MAAMrJ,OAAO;YACb,UAAU,sBAAsBqJ,SAASC,SAAShH,iBAAiB,oBAAoB;;QAG3F2Q,mBAAmBF,6BAA6BtT,GAAG0K;QAEnD+I,iBAAiBH,6BAA6BE,oBAAoByB;QAElEvB,yBAAyBJ,6BAA6BiB;QAEtDZ,qBAAqBR,sBAAsBnO,OAAOsQ,gBAAgBnR,aAAamP;QAE/EO,4BAA4BY;QAE5Bb,wBAAwBgB;QAExBd,yBAAyBgB;QAEzBf,0BAA0BgB;QAE1Bf,wBAAwBV,6BAA6BtO,OAAO6G,eAAe1H;QAE3E8P,yBAA0B;YACtB,IAAIX,2BAA2B;gBAC3B,QAAQtT,GAAG2K,mBAAmB3K,GAAG8O;;YAErC,OAAO;;QAGX;YACIyG,eAAejC;YACfkC,eAAepC;YACfqC,kBAAkBnC;YAClBoC,UAAUlC;YACVmC,gBAAgB7B;YAChB8B,mBAAmBhC;YACnBiC,mBAAmBhC;YACnBiC,iBAAiB9Q,OAAO+Q;YACxBC,UAAU3C;YACV4C,YAAY1C;YACZ2C,iBAAiBnC;YACjBoC,eAAenC;YACfoC,iBAAiBpC;YACjBqC,oBAAoB/C;YACpBgD,OAAO9C;YACP+C,aAAatC;YACbuC,QAAQ/C;YACRgD,SAASzC,yBAAyBZ;YAClCsD,cAAc1W,GAAGiO;YACjB0I,2BAA2B3W,GAAG0O;YAC9BkI,WAAWzD;YACX0D,YAAYlD;YACZmD,qBAAqBxD;YACrByD,oBAAoBzD;YACpB0D,gBAAgBtD;;;IChKxB1T,GAAGiX,mBAAmB,SAASC;QAC3B;QACA,UAAUA,gBAAgBA,aAAaC,QAAQnX,GAAG6G,WAAWqQ,aAAaC;;IAG9EnX,GAAG+L,UAAU;QACT;QAEA,IAAIqL,aAAaC,aACbC,uBACAC,uBACAC,oBACAC,QAAQ;QAEZzX,GAAG6B,OAAOxB;YACN8W,MAAM,SAASO,WAAWC;gBACtB,IAAIF,UAAU,GAAG;oBACb,IAAIC,WAAW;wBACXJ,iBAAiBpU,KAAKwU;;oBAE1B,IAAIC,WAAW;wBACXJ,iBAAiBrU,KAAKyU;;uBAGzB,IAAIF,WAAW,GAAG;oBACnBE,aAAaA,UAAUtH,MAAM,MAAMgH;uBAElC,IAAIK,WAAW;oBAChBA,UAAUrH,MAAM,MAAM+G;;gBAG1B,OAAO/W;;YAGXuX,MAAM,SAASnI;gBACX,IAAIgI,UAAU,GAAG;oBACbD,cAActU,KAAKuM;uBAElB;oBACDA,SAASY,MAAM,MAAMgH,gBAAgBlT,YAAYiT,cAAcC;;gBAGnE,OAAOhX;;YAGX4L,SAAS;gBACLwL,QAAQ;gBACRL,cAAcjP;gBAEd,IAAImP,iBAAiBvR,QAAQ;oBACzB/F,GAAG+C,KAAKuU,kBAAkB,SAAStU,KAAKyM;wBACpCA,SAASY,MAAM,MAAM+G;;;gBAI7B,IAAII,cAAczR,QAAQ;oBACtB/F,GAAG+C,KAAKyU,eAAe,SAASxU,KAAKyM;wBACjCA,SAASY,MAAM,MAAM+G;;;gBAI7B,OAAO/W;;YAGX8L,SAAS;gBACLsL,SAAS;gBACTJ,cAAclP;gBAEd,IAAIoP,iBAAiBxR,QAAQ;oBACzB/F,GAAG+C,KAAKwU,kBAAkB,SAASvU,KAAKyM;wBACpCA,SAASY,MAAM,MAAMgH;;;gBAI7B,IAAIG,cAAczR,QAAQ;oBACtB/F,GAAG+C,KAAKyU,eAAe,SAASxU,KAAKyM;wBACjCA,SAASY,MAAM,MAAMgH;;;gBAI7B,OAAOhX;;;;IC3EnBL,GAAG6X,YAAY,SAASC,eAAeC;QACnC;QAEA/X,GAAG6B,OAAOxB;YACNyX,eAAeA;YAEfE,QAAQ;gBACJ,OAAOD,SAASD;;;;ICF5B9X,GAAGiY,eAAe,SAASC;QACvB;QAEA,IAAIC,OAAO9X,MAEP+X,iBAAiB,IAAIpY,GAAGsS,kBAExB+F;YAEIC,aAAa;YAGbrY,SAAS;YAETsY,YAAY;YAGZC,SAAS;YAGTC,YAAY;YAEZC,4BAA4B;YAG5B3O,UAAU;YAGVhI,MAAM;YAGN4W,UAAU,SAAS/O;YAEnBgP,OAAO;WAEXhP,OAAOiP;QAGX7Y,GAAG6B,OAAOwW,SAASH;QAEnBW,WAAW7Y,GAAGoN;QAGd,SAAS0L;YACL,IAAIlP,QAAQC,SAASC,cAAc;YAEnCF,MAAM2H,aAAavR,GAAGiY,aAAac,qBAAqBF;YACxDjP,MAAM2H,aAAa,SAAS8G,QAAQO;YAEpCT,KAAKa,YAAYX,QAAQtO,UAAUH;YAEnC,IAAIyO,QAAQG,WAAWxY,GAAGkT,kBAAkBgD,iBAAiB;gBAEzDtM,MAAM2H,aAAa,mBAAmB;;YAG1C,IAAI8G,QAAQC,aAAa;gBACrB1O,MAAM2H,aAAa,UAAU8G,QAAQC;;YAGzC1O,MAAM2H,aAAa,QAAQ;YAC3B3H,MAAM2H,aAAa,QAAQ8G,QAAQtW;YAEnC/B,GAAG4J,OAAOtI;gBACN2X,UAAU;gBAIVC,OAAO;gBACPC,KAAK;gBACLC,YAAY;gBASZC,UAAUrZ,GAAGyN,SAASzN,GAAG6N,QAAQ,WAAW;gBAC5CyL,QAAQ;gBACRC,SAAS;gBACTC,QAAQ;gBACR/X,SAAS;;aAKZzB,GAAG4N,SAAS5N,GAAG4J,OAAOtI;gBAAKmY,QAAQ;;YAEpCpB,QAAQpY,QAAQuR,YAAY5H;YAE5BwO,eAAe9X,OAAOsJ,OAAO,UAAU;gBACnCyO,QAAQM,SAAS/O;;YAIrBwO,eAAe9X,OAAOsJ,OAAO,aAAa;gBACtC5J,GAAGqY,QAAQpY,SAASoC,SAASgW,QAAQI;;YAEzCL,eAAe9X,OAAOsJ,OAAO,YAAY;gBACrC5J,GAAGqY,QAAQpY,SAASqC,YAAY+V,QAAQI;;YAG5CL,eAAe9X,OAAOsJ,OAAO,SAAS;gBAClC5J,GAAGqY,QAAQpY,SAASoC,SAASgW,QAAQE;;YAEzCH,eAAe9X,OAAOsJ,OAAO,QAAQ;gBACjC5J,GAAGqY,QAAQpY,SAASqC,YAAY+V,QAAQE;;YAG5C,OAAO3O;;QAIX5J,GAAGqY,QAAQpY,SAASqB;YAChB2X,UAAU;YACVS,UAAU;YAEVC,WAAW;;QAIf3Z,GAAG6B,OAAOxB;YACNuZ,UAAU;gBACN,OAAOhQ;;YAGXiQ,aAAa;gBACT,OAAOhB;;YAGXG,aAAa,SAASc,YAAYC;gBAC9B,IAAInQ,QAAQmQ,YAAY1Z,KAAKuZ;gBAK7B,IAAIvB,QAAQK,8BAA8B1Y,GAAG4O,WAAW5O,GAAG8O,eAAe9O,GAAGgP,qBAAqB;oBAC9FpF,MAAM2H,aAAa,YAAY;uBAG9B;oBACD,IAAIuI,YAAY;wBACZlQ,MAAM2H,aAAa,YAAY;2BAE9B;wBACD3H,MAAMoQ,gBAAgB;;;;YAKlCC,gBAAgB,SAAS3B;gBACrB,IAAIA,gBAAgBD,QAAQC,aAAa;oBACrC1O,MAAM2H,aAAa,UAAU+G;;;YAIrC4B,OAAO;gBACH,IAAItQ,MAAMzI,YAAY;oBAClBnB,GAAG4J,OAAOxI;;gBAGdpB,GAAGqY,QAAQpY,SAASqC,YAAY+V,QAAQE;gBACxC3O,QAAQ;gBACRA,QAAQkP;;;QAIhBlP,QAAQkP;;IAGZ9Y,GAAGiY,aAAac,sBAAsB;ICxLtC/Y,GAAGma,aAAa,SAASC;QACrB;QAEA,IAAItV,WACAuV,aACAC,eACAC,qBACAC;QAEJ,SAASC,aAAaC;YAClB,IAAI1a,GAAG8G,QAAQ4T,UAAU;gBACrB,IAAIC;gBAEJ3a,GAAG+C,KAAK2X,SAAS,SAAS1X,KAAK4X;oBAC3BD,QAAQzX,KAAK4B,KAAK8V;;gBAGtB,OAAOD;;YAGX,OAAO7V,KAAK4V;;QAGhB,SAASG,eAAeC;YACpB,IAAI9a,GAAG8G,QAAQgU,QAAQ;gBACnB,IAAIH;gBAEJ3a,GAAG+C,KAAK+X,OAAO,SAAS9X,KAAK+X;oBACzBJ,QAAQzX,KAAK4B,KAAKuV,OAAOU;;gBAG7B,OAAOJ;;YAGX,OAAO7V,KAAKuV,OAAOS;;QAGvB,SAASE,gBAAgBC;YACrB,IAAIC,oBACAC,cAAc/K,OAAO6K;YAEzBjb,GAAG+C,KAAKoY,UAAU,SAASC,OAAOC;gBAC9B,IAAIC,sBAAsBhB,SAASe;gBAEnC,IAAIC,wBAAwBnX,WAAW;oBACnCnE,GAAG+C,KAAKuY,qBAAqB,SAASxK,GAAGyK;wBACrCL,cAAchY,KAAK4B,KAAKyW;;;;YAKpC,OAAOL;;QAGXlb,GAAG6B,OAAOxB;YAgBNmb,SAAS,SAASC;gBACd,IAAIR,SAASQ,KAAKR,UAAUjb,GAAGib,OAAOS,YAClCd,KAAK9V,KAAK5B;oBACNnB,MAAM0Z,KAAK1Z;oBACX4Z,cAAcF,KAAK1Z;oBACnBgZ,MAAMU,KAAKV;oBACXa,MAAMH,KAAKG,QAAQ,QAAQ,IAAIH,KAAKG;oBACpCX,QAAQA;oBACRY,MAAMJ,KAAKI;qBACV;gBAET,IAAIJ,KAAKK,SAAS;oBACdhX,KAAK8V,IAAIkB,UAAUL,KAAKK;oBAExB,IAAItB,UAAUiB,KAAKK,aAAa3X,WAAW;wBACvCqW,UAAUiB,KAAKK;;oBAEnBtB,UAAUiB,KAAKK,SAAS5Y,KAAK0X;;gBAGjC,IAAIa,KAAKM,cAAc;oBACnBjX,KAAK8V,IAAImB,eAAeN,KAAKM;oBAE7B,IAAIxB,eAAekB,KAAKM,kBAAkB5X,WAAW;wBACjDoW,eAAekB,KAAKM;;oBAExBxB,eAAekB,KAAKM,cAAc7Y,KAAK0X;;gBAG3C9V,KAAK8V,IAAIA,KAAKA;gBACdP,OAAOoB,KAAKV,QAAQH;gBAEpB,IAAIN,SAASW,YAAY9W,WAAW;oBAChCmW,SAASW;;gBAEbX,SAASW,QAAQ/X,KAAK0X;gBAEtBa,KAAKO,wBAAwBP,KAAKO,qBAAqBpB;gBACvDR,cAAc6B,eAAerB,IAAI,MAAMK;gBAEvC,OAAOL;;YAGXsB,UAAU,SAASC;gBACf,IAAInc,GAAGuG,SAAS4V,mBAAmBrX,KAAKiB,QAAS;oBAC7C,IAAIoW,eAAevB,OAAOzW,WAAW;wBACjC,OAAOsW,aAAa0B,eAAevB;2BAGlC,IAAIuB,eAAepB,SAAS5W,WAAW;wBACxC,OAAO0W,eAAesB,eAAepB;2BAGpC,IAAIoB,eAAelB,QAAQ;wBAC5B,OAAOD,gBAAgBmB,eAAelB;;uBAGzC;oBACD,OAAOjb,GAAG6B,WAAWiD,MAAM;;;YAInCsX,eAAe,SAASxB;gBACpB,IAAIyB,SAAS5B,aAAaG;gBAE1B,IAAIyB,QAAQ;2BACDA,OAAOR;;;YAItB3B,OAAO;gBACHpV;gBACAuV;gBACAC;gBACAE;;YAGJ8B,WAAW,SAAS1B,IAAI2B;gBACpB,IAAIC,YAAY1X,KAAK8V,IAAIK,QACrBwB,yBAAyBzc,GAAG2F,QAAQ2U,SAASkC,YAAY5B;gBAE7DN,SAASkC,WAAWE,OAAOD,wBAAwB;gBAEnD3X,KAAK8V,IAAIK,SAASsB;gBAElB,IAAIjC,SAASiC,eAAepY,WAAW;oBACnCmW,SAASiC;;gBAEbjC,SAASiC,WAAWrZ,KAAK0X;gBAEzBR,cAAc6B,eAAerB,IAAI4B,WAAWD;;YAGhDI,aAAa,SAAS/B,IAAIgC;gBACtB,IAAIC,UAAU/X,KAAK8V,IAAIG;gBAEvBjW,KAAK8V,IAAIG,OAAO6B;gBAChBvC,OAAOuC,WAAWhC;uBACXP,OAAOwC;;YAGlBC,YAAY,SAASlC,IAAImC;gBACrBjY,KAAK8V,IAAI7Y,OAAOgb;;YAGpBC,YAAY,SAASpC,IAAIqC;gBACrBnY,KAAK8V,IAAIgB,OAAOqB;;YAIpBC,aAAa,SAASC,UAAUC;gBAC5BtY,KAAKqY,UAAUC,WAAWA;;YAG9BC,oBAAoB,SAASzC;gBACzB,IAAImB,eAAejX,KAAK8V,IAAImB;gBAE5B,IAAIA,cAAc;oBACd,OAAOxB,eAAewB;;gBAE1B;;YAGJuB,eAAe,SAAS1C;gBACpB,IAAIkB,UAAUhX,KAAK8V,IAAIkB;gBAEvB,OAAOtB,UAAUsB;;;;IAK7B9b,GAAGib;QACCS,YAAY;QACZ6B,WAAW;QACXC,UAAU;QACVC,QAAQ;QACRC,UAAU;QACVC,QAAQ;QACRC,WAAW;QACXC,mBAAmB;QACnBC,iBAAiB;QACjBC,mBAAmB;QACnBC,eAAe;QACfC,eAAe;QACfC,UAAU;QACVC,SAAS;;KCpNZ;QACG;QAEAne,GAAGoe;YAECC,UAAU,SAASC,iBAAiBC,QAAQC;gBACxCne,KAAKoe,SAASH,iBAAiBC,QAAQC;;YAG3CE,iBAAiB,SAASC;gBACtB,IAAIxG,OAAO9X;gBAEXL,GAAG+C,KAAK4b,gBAAgB,SAASvD,OAAOwD;oBACpCzG,KAAK0G,eAAeD;;;YAI5BH,UAAU,SAAS3Z,MAAMyZ,QAAQC;gBAC7Bne,KAAKye;gBAEL,IAAIhD,UAAUzb,KAAK0e,WAAWhZ,WAAW,IAAI/F,GAAGoN,gBAAgB/M,KAAK2e,iBAEjEC,cAAcjf,GAAGgQ,KAAK,SAASvE;oBAC3BpL,KAAK6e;wBACDzT,MAAMA;wBACN1J,MAAM1B,KAAK8e,SAASC,MAAMC;uBAC3BvD,SAASwD;mBACbjf,OAEHkf,kBAAkBvf,GAAGgQ,KAAK,SAASwP;oBAC/Bnf,KAAK6e,eAAeM,UAAU1D,SAASwD;mBACxCjf,OAEHof,gBAAgBzf,GAAGgQ,KAAK,SAAS3L;oBAC7B,IAAIoH,OAAOzL,GAAGoE,aAAaC;oBAE3BhE,KAAK6e;wBACDzT,MAAMA;wBACN1J,MAAM1B,KAAK8e,SAASC,MAAMC,cAAc;uBACzCvD,SAASwD;mBACbjf,OAEHqf,oBAAoB1f,GAAGgQ,KAAK,SAAS2P;oBACjC,IAAIC,oBAAoBD,WAAWpb,WAAWob,WAAWpb,UAAU,KAC/DkH,OAAOzL,GAAGoE,aAAaub,WAAWtb,QAAQsb,WAAWpf,MAAMqf;oBAE/Dvf,KAAK6e;wBACDzT,MAAMA;wBACN1J,MAAM4d,WAAW5d;uBAClB+Z,SAASwD;mBACbjf,OAEHwf,qBAAqB7f,GAAGgQ,KAAK,SAAS8P;oBAClC,IAAI9f,GAAGiJ,QAAQ6W,gBAAgB9f,GAAGkT,kBAAkBqC,eAAe;wBAC/D,IAAIwK,QAAQ9X,MAAMvB,UAAUwB,MAAMtB,KAAKkZ,YAAYC,QAC/C5H,OAAO9X;wBAEXL,GAAG+C,KAAKgd,OAAO,SAAS/c,KAAK6Y;4BACzB1D,KAAK+G,eAAerD,MAAMC,SAASwD;;2BAGtC;wBACDjf,KAAK6e,eAAeY,aAAahE,SAASwD;;mBAE/Cjf,OAEH2f,gBAAgB;oBACZ,IAAIhgB,GAAG4I,WAAW9D,OAAO;wBACrBA,OAAOmD,MAAMvB,UAAUwB,MAAMtB,KAAK9B;;oBAEtCA,UAAUsL,OAAOtL;mBAGrBqT,OAAO9X,MACPif;gBAEJjf,KAAK2e,kBAAkBlD;gBAEvB,IAAIhX,MAAM;oBACNkb;oBAEAhgB,GAAG+C,KAAK+B,MAAM,SAAS9B,KAAKid;wBACxB,IAAIjgB,GAAG+I,cAAckX,gBAAgB;4BACjCJ,mBAAmBI;+BAElB,IAAIjgB,GAAGyJ,OAAOwW,gBAAgB;4BAC/BhB,YAAYgB;+BAEX,IAAIjgB,GAAGuG,SAAS0Z,gBAAgB;4BACjC,IAAIA,cAAcxU,QAAQwU,cAAcle,MAAM;gCAC1Cwd,gBAAgBU;mCAEf,IAAIA,cAAc5b,UAAU4b,cAAcle,MAAM;gCACjD2d,kBAAkBO;;+BAGrB,IAAIA,cAAczW,WAAWyW,cAAczW,QAAQF,kBAAkB,UAAU;4BAChFmW,cAAcQ;+BAEb;4BACD9H,KAAKhS,IAAI8Z,gBAAgB,8CAA8C;;;oBAI/E5f,KAAK8F,IAAI,cAAcmZ,cAAcvZ,SAAS;oBAC9C1F,KAAK6f,uBAAuBZ,eAAef,QAAQC;;;YAI3D2B,QAAQ,SAASvF;gBACb,IAAIwF,aAAa/f,KAAKggB,YAAYnE;oBAAUtB,IAAIA;;gBAEhD,IAAIwF,cAAcA,WAAWnF,WAAWjb,GAAGib,OAAO4C,mBAAmB;oBACjExd,KAAK8F,IAAInG,GAAG8H,OAAO,4DAA4D8S,IAAIva,KAAKigB,QAAQ1F,MAAM;uBAErG;oBACDva,KAAKkgB,SAASJ,OAAOvF;;;YAI7B4F,WAAW;gBACP,IAAIC,oBACAtI,OAAO9X;gBAEXL,GAAG6B,OAAO4e,eAAepgB,KAAK0e;gBAC9B/e,GAAG+C,KAAK0d,eAAe,SAASzd,KAAK0d;oBACjCvI,KAAKgI,OAAOO;;gBAGhBrgB,KAAKkgB,SAASC;;YAGlBG,kBAAkB;gBACdtgB,KAAK0e;;YAGT6B,gBAAgB,SAAShG;gBACrB,IAAIwF,aAAa/f,KAAKggB,YAAYnE;oBAAUtB,IAAIA;;gBAEhD,KAAK5a,GAAGkT,kBAAkBoD,UAAUjW,KAAK8e,SAASzJ,SAASmL,SAAS;oBAChE,OAAO;;gBAGX,IAAIT,WAAWnF,WAAWjb,GAAGib,OAAO0C,QAAQ;oBACxCtd,KAAK8F,IAAInG,GAAG8H,OAAO,0DAA0D8S,IAAIva,KAAKigB,QAAQ1F;oBAC9Fva,KAAKygB,YAAYlG;oBACjB,OAAO;uBAEN;oBACDva,KAAK8F,IAAInG,GAAG8H,OAAO,uDAAuD8S,IAAIva,KAAKigB,QAAQ1F,MAAM;;gBAGrG,OAAO;;YAGXmG,YAAY,SAASnG;gBACjB,OAAOva,KAAK2gB,gBAAgBpG;;YAIhCqG,WAAW,SAASC;gBAChB,OAAO7gB,KAAKkgB,SAASY,QAAQD;;YAOjCE,eAAe,SAASC,QAAQC,aAAaC,SAASC,YAAYC;gBAC9D,IAAIC,kBAAkB,IAAI1hB,GAAG+L,WACzB4V,WAAWtJ;gBAEf,IAAIhY,KAAKuhB,iBAAiB;oBACtBD,YAAYthB,KAAKwhB,eAAeR;oBAChChJ;wBACIoJ,sBAAsBA;wBACtBF,SAASA,UAAU,IAAIA,UAAU;wBACjCO,OAAOP,UAAU;;oBAKrB,KAAKC,cAAcxhB,GAAGkT,kBAAkBiD,eAAe;wBACnDwL,YAAYthB,KAAK0hB,QAAQV;;oBAI7B,IAAIM,aAAa,MAAM;wBACnBD,gBAAgBvV;4BAAS6V,WAAWV;4BAAajX,OAAO;;2BAEvD;wBACDhK,KAAKuhB,gBAAgBK,SAASN,WAAWL,aAAajJ,SAASlB,KAC3D,SAASlL,QAAQiW;4BACbR,gBAAgBzV,QAAQiW;2BAG5B,SAAS/V,QAAQ6V,WAAWG;4BACxBT,gBAAgBvV;gCAAS6V,WAAWA;gCAAW3X,OAAO8X,UAAU;;;;uBAK3E;oBACDT,gBAAgBvV;wBAAS6V,WAAWV;wBAAajX,OAAO;;;gBAG5D,OAAOqX;;YAGXU,WAAW,SAASf;gBAChB,OAAOhhB,KAAKgiB,WAAWhiB,KAAKiiB,qBAAqBjB;;YAGrDkB,aAAa,SAASlB;gBAClB,OAAOhhB,KAAKmiB,eAAeC,IAAIpB;;YAGnCU,SAAS,SAASb;gBACd,IAAIrF,OAAOxb,KAAKkgB,SAASwB,QAAQb;gBACjC,IAAIwB;gBAEJ,KAAK7G,MAAM;oBACP6G,mBAAmBriB,KAAKggB,YAAYnE;wBAAUtB,IAAIsG;;oBAElD,IAAIwB,kBAAkB;wBAClB7G,OAAO6G,iBAAiB7G;;;gBAIhC,OAAOA,QAAQ;;YAGnB8G,eAAe;gBACX,OAAOtiB,KAAKggB,YAAYnE;oBACpBjB,UACIjb,GAAGib,OAAO2C,WACV5d,GAAGib,OAAO6C,iBACV9d,GAAGib,OAAOwC;mBAEf1X;;YAGPua,SAAS,SAAS1F;gBACd,OAAOva,KAAKggB,YAAYnE;oBAAUtB,IAAIA;mBAAK7Y;;YAI/C6gB,aAAa,SAAShI;gBAClB,IAAIiI,kBAAkBxiB,KAAKyiB;oBAAYlI,IAAIA;oBACvCwC,WAAW;gBAEf,IAAIyF,iBAAiB;oBACjB,IAAIA,gBAAgBzF,aAAajZ,WAAW;wBACxCiZ,WAAWyF,gBAAgBzF;;;gBAInC,OAAOA;;YAGX2F,uBAAuB;gBACnB,OAAO1iB,KAAKkgB,SAASwC;;YAGzBC,SAAS,SAASpI;gBACd,OAAOva,KAAKggB,YAAYnE;oBAAUtB,IAAIA;mBAAKgB;;YAG/CqH,eAAe;gBACX,OAAO5iB,KAAK6iB;;YAGhBC,0BAA0B;gBACtB,IAAIC,eAAe/iB,KAAKgjB;gBAExB,IAAID,eAAe,GAAG;oBAClB,OAAOA,eAAe/iB,KAAKijB;;gBAG/B,OAAO;;YAGXR,YAAY,SAAS3G;gBACjB,OAAO9b,KAAKggB,YAAYnE,SAASC;;YAGrCoH,SAAS,SAAS3I;gBACd,OAAOva,KAAKggB,YAAYnE;oBAAUtB,IAAIA;mBAAKG;;YAG/CyI,aAAa,SAAS5I;gBAClB,OAAOva,KAAKkgB,SAASkD,gBAAgB7I;;YAGzCzU,KAAK,SAAS4B,KAAK1B;gBACf,IAAIhG,KAAK8e,SAASuE,WAAWrd,SAASA,UAAU,SAAS;oBACrDrG,GAAGmG,IAAI,oBAAoBnG,GAAGiT,UAAU,OAAOlL;uBAE9C,IAAI1B,SAASA,UAAU,QAAQ;oBAChCrG,GAAGmG,IAAI,oBAAoBnG,GAAGiT,UAAU,OAAOlL,KAAK1B;;;YAK5Dsd,aAAa,SAAS/I;gBAClB,IAAIwF,aAAa/f,KAAKggB,YAAYnE;oBAAUtB,IAAIA;;gBAEhD,KAAK5a,GAAGkT,kBAAkBoD,UAAUjW,KAAK8e,SAASzJ,SAASmL,SAAS;oBAChE,OAAO;;gBAIX,IAAI7gB,GAAG2F,UAAS3F,GAAGib,OAAO2C,WAAW5d,GAAGib,OAAO6C,mBAAkBsC,WAAWnF,WAAW,GAAG;oBACtF,IAAI5a,KAAKkgB,SAASjK,MAAMsE,KAAK;wBACzBva,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAO0C;wBACzC,OAAO;2BAEN;wBACDtd,KAAK8F,IAAInG,GAAG8H,OAAO,oCAAoC8S,IAAIva,KAAKigB,QAAQ1F,MAAM;;uBAGjF;oBACDva,KAAK8F,IAAInG,GAAG8H,OAAO,yDAAyD8S,IAAIva,KAAKigB,QAAQ1F,MAAM;;gBAGvG,OAAO;;YAGXwB,eAAe,SAASxB;gBACpBva,KAAKkgB,SAASqD,QAAQhJ;gBACtBva,KAAKggB,YAAYjE,cAAcxB;;YAGnCV,OAAO;gBACH7Z,KAAK8F,IAAI;gBAET9F,KAAKkgB,SAASrG;gBACd7Z,KAAK0e;gBACL1e,KAAKwjB;gBACLxjB,KAAKyjB;gBACLzjB,KAAK0jB;gBACL1jB,KAAKwhB;gBAEL7hB,GAAG+C,KAAK1C,KAAK2jB,UAAU,SAAShhB,KAAKihB;oBACjCA,OAAO/J;;gBAGX7Z,KAAK6jB,aAAahK;gBAClB7Z,KAAKmiB,eAAetI;gBACpB7Z,KAAKijB,uBAAuB;gBAC5BjjB,KAAK6iB,eAAe;gBACpB7iB,KAAKggB,YAAYnG;gBACjB7Z,KAAKiiB;gBAELjiB,KAAK8jB,iBAAiB9jB,KAAK8jB,cAAcjK;gBACzC7Z,KAAK8e,SAASiF,QAAQC,kBAAkBhkB,KAAKikB;gBAE7CjkB,KAAKkkB;gBACLlkB,KAAKmkB;gBAELnkB,KAAKokB,kBAAkBpkB,KAAKokB,eAAevK;gBAE3C7Z,KAAKqkB,uBAAuBxK;;YAGhCyK,OAAO,SAAS/J;gBACZ,OAAOva,KAAKukB,aAAahK;;YAG7BiK,YAAY,SAASjK,IAAIkK;gBACrB,IAAI3M,OAAO9X;gBAEX,OAAOL,GAAG+kB,OAAOre,UAAUme,WAAWjK,IAAIkK;oBACtC3e,KAAKnG,GAAGgQ,KAAKmI,KAAKhS,KAAKgS;oBACvB4J,SAAS/hB,GAAGgQ,KAAKmI,KAAK4J,SAAS5J;oBAC/BiI,YAAYjI,KAAKkI;;;YAIzB2E,kBAAkB,SAASC,SAASrK;gBAChCva,KAAK6kB,oBAAoBC,IAAIF,SAASrK;;YAG1CwK,qBAAqB,SAASxK,IAAI9V;gBAC9BzE,KAAKqkB,uBAAuBS,IAAIrgB,MAAM8V;;YAG1CyK,4BAA4B,SAASJ,SAASrK;gBAC1Cva,KAAKilB,8BAA8BH,IAAIF,SAASrK;;YAGpD2K,uBAAuB,SAAS/G,UAAU5D;gBACtCva,KAAKmlB,yBAAyBL,IAAI3G,UAAU5D;;YAGhD6K,qBAAqB,SAASlH,QAAQ3D;gBAClCva,KAAKqlB,uBAAuBP,IAAI5G,QAAQ3D;;YAI5C+K,aAAa,SAASnH,UAAU5D;gBAC5Bva,KAAKmiB,eAAe2C,IAAI3G,UAAU5D;;YAGtCgL,SAAS,SAASC;gBACdxlB,KAAKylB,4BAA4BD;;YAGrCE,cAAc,SAASC;gBACnB3lB,KAAKgjB,oBAAoB2C;;YAG7BC,SAAS,SAASrL,IAAImC;gBAClB1c,KAAKggB,YAAYvD,WAAWlC,IAAImC;;YAGpCmJ,WAAW,SAAS3H,QAAQ3D;gBACxBva,KAAK6jB,aAAaiB,IAAI5G,QAAQ3D;;YAGlCuL,SAAS,SAASvL,IAAIgC;gBAClB,OAAOvc,KAAKggB,YAAY1D,YAAY/B,IAAIgC;;YAY5CN,WAAW,SAAS1B,IAAI2B;gBACpB,IAAI6J,aAAa/lB,KAAKyiB;oBAAYlI,IAAIA;;gBACtC,KAAKwL,YAAY;oBACb,MAAM,IAAIpmB,GAAGwB,MAAMoZ,KAAK;;gBAG5B,QAAQ2B;kBACJ,KAAKvc,GAAGib,OAAOkD;oBACX9d,KAAKgmB,kBAAkBzL,IAAI,MAAM;oBACjC;;kBACJ,KAAK5a,GAAGib,OAAOgD;oBACX5d,KAAKgmB,kBAAkBzL,IAAI,MAAM;oBACjC;;kBACJ;oBACI,IAAI0L,eAAe,iCAAiCvkB,OAAO,+BAA+Bwa;oBAC1Flc,KAAK8F,IAAImgB;oBACT,MAAM,IAAItmB,GAAGwB,MAAM8kB;;;YAI/BC,mBAAmB;gBACf,IAAIlmB,KAAK0e,WAAWhZ,WAAW,GAAG;oBAC9B1F,KAAKmmB,WAAW;uBAEf;oBACDnmB,KAAKomB;;;;QAQjBzmB,GAAG0mB;YAEC7H,gBAAgB,SAAS8H;gBACrB,IAAIxO,OAAO9X;gBAEX,OAAOA,KAAKggB,YAAY7E;oBACpBT,MAAM4L,YAAY5L;oBAClBhZ,MAAM4kB,YAAY5kB;oBAClB6Z,MAAM+K,YAAY/K;oBAClBX,QAAQjb,GAAGib,OAAO8C;oBAClB/B,sBAAsB,SAASpB;wBAC3B+L,YAAYC,sBAAsBzO,KAAKoN,sBAAsBoB,YAAYC,oBAAoBhM;wBAC7F+L,YAAYE,oBAAoB1O,KAAKsN,oBAAoBkB,YAAYE,kBAAkBjM;wBAEvF,IAAI+L,YAAYG,cAAc;4BAC1B3O,KAAK0J,eAAejH,MAAM+L,YAAYG;;wBAG1C3O,KAAK+K;wBACL/K,KAAKmL;;;;YAKjByD,uBAAuB,SAASlL,MAAMmL;gBAClC,IAAIhnB,GAAGyI,OAAOoT,OAAO;oBACjBA,KAAKoL,aAAa5mB,KAAK6mB,aAAaF;;;YAI5CG,aAAa,SAAS/gB;gBAClB/F,KAAK8e,SAASiI,UAAUC,QAAQ,MAAM,MAAMjhB,SAASjC;;YAGzDmjB,sBAAsB;gBAClB,IAAInP,OAAO9X;gBAEX,OAAO,IAAIL,GAAGunB;oBACVC,QAAQnnB,KAAK8e,SAAS4B,WAAWyG,OAAOC;oBACxCC,gBAAgBrnB,KAAK8e,SAASuI;oBAC9BC,eAAetnB,KAAK8e,SAASyI,QAAQC;oBACrCC,eAAeznB,KAAKilB;oBACpByC,aAAa1nB,KAAKqlB;oBAClBsC,eAAe3nB,KAAKmlB;oBACpByC,MAAM5nB,KAAK8e,SAAS8I;oBACpB9hB,KAAKnG,GAAGgQ,KAAKmI,KAAKhS,KAAKgS;oBACvB+P,UAAU,SAAStN;wBACfzC,KAAKgQ,UAAUvN;wBACfzC,KAAKgH,SAASiI,UAAUc,SAAStN;;oBAErCwN,kBAAkB,SAASxN,IAAIyN,UAAUC;wBACrCnQ,KAAKkO,kBAAkBzL,IAAIyN,UAAUC;wBACrCnQ,KAAKgH,SAASiI,UAAUgB,iBAAiBxN,IAAIyN,UAAUC;;;;YAMnEC,qBAAqB;gBACjB,IAAIpQ,OAAO9X;gBAEX,OAAO,IAAIL,GAAGwoB;oBACVC,eAAepoB,KAAK8e,SAASuJ,MAAMD;oBACnCrB;wBACIjhB,KAAKnG,GAAGgQ,KAAKmI,KAAKhS,KAAKgS;wBACvBwQ,eAAe,SAASld;4BACpB0M,KAAKyQ;gCACD7mB,MAAM;gCACN0N,UAAUzP,GAAGgQ,KAAKmI,KAAKgH,SAASiI,UAAUyB,iBAAiB1Q,MAAM1M;gCACjEiM,WAAW1X,GAAGgQ,KAAKmI,KAAK2Q,qBAAqB3Q,MAAM1M;gCACnDsd,YAAY;;;;;;YAOhCC,cAAc,SAASC,cAAcC;gBACjC,IAAIC,YACAC,WAAWH,cACXI,0BACAC,iBAAiBJ,kBACjBK,OAAO,SAASC;oBACZ,IAAIxpB,GAAGuG,SAASijB,OAAO;wBACnB,OAAOxpB,GAAG6B,WAAW2nB;;oBAEzB,OAAOA;mBAEXC,oBAAoB;oBAChB,IAAIzpB,GAAG6G,WAAWyiB,iBAAiB;wBAC/B,OAAOA;;oBAEX,OAAOA;mBAEXI,wBAAwB,SAAS9O,IAAI+O;oBACjC,IAAIL,kBAAkBtpB,GAAGuG,SAASojB,WAAW;wBACzC3pB,GAAG6B,OAAO8nB,UAAUF;;oBAGxB,IAAIJ,oBAAoBzO,KAAK;wBACzB5a,GAAG6B,OAAO8nB,UAAUN,oBAAoBzO;;;gBAIpD;oBACIuK,KAAK,SAASliB,KAAK2X;wBAEf,IAAIA,MAAM,MAAM;4BACZuO;4BACAC,WAAWG,KAAKtmB;+BAEf;4BACDkmB,MAAMvO,MAAM2O,KAAKtmB;;;oBAIzBwf,KAAK,SAAS7H;wBACV,IAAIgP;wBAGJ,IAAIhP,MAAM,QAAQuO,MAAMvO,KAAK;4BACzBgP,SAAST,MAAMvO;+BAEd;4BACDgP,SAASL,KAAKH;;wBAGlBM,sBAAsB9O,IAAIgP;wBAE1B,OAAOL,KAAKK;;oBAGhBC,aAAa,SAASjP,IAAIgP;wBAEtB,IAAI5pB,GAAGuG,SAAS4iB,QAAQ;4BAEpB,IAAIvO,OAAO,MAAM;gCACb,IAAI5a,GAAG6G,WAAW+iB,SAAS;oCACvBN,iBAAiBM;uCAEhB;oCACDN,iBAAiBA;oCACjBtpB,GAAG6B,OAAOynB,gBAAgBM;;mCAG7B;gCACDP,oBAAoBzO,MAAMyO,oBAAoBzO;gCAC9C5a,GAAG6B,OAAOwnB,oBAAoBzO,KAAKgP;;;;oBAK/CxoB,QAAQ,SAASigB;wBACb,cAAc8H,MAAM9H;;oBAGxBnH,OAAO;wBACHiP;wBACAE;wBACAD,WAAWH;;;;YAKvBa,0BAA0B;gBACtB,IAAI3R,OAAO9X;gBAEX,OAAO,IAAIL,GAAGma;oBACVmG,SAAS,SAAS1F;wBACd,OAAOzC,KAAKmI,QAAQ1F;;oBAExB2I,SAAS,SAAS3I;wBACd,OAAOzC,KAAKoL,QAAQ3I;;oBAExBoI,SAAS,SAASpI;wBACd,OAAOzC,KAAK6K,QAAQpI;;oBAExBqB,gBAAgB,SAASrB,IAAI4B,WAAWD;wBACpCpE,KAAK4R,sBAAsBnP,IAAI4B,WAAWD;wBAC1CpE,KAAKgH,SAASiI,UAAUnL,eAAerB,IAAI4B,WAAWD;wBACtDpE,KAAK6R,kBAAkBpP,IAAI2B;wBAE3B,IAAIpE,KAAKsM,gBAAgB;4BACrBwF,WAAW;gCACP9R,KAAKsM,eAAexI,eAAerB,IAAI4B,WAAWD;+BACnD;;;;;YAcnB2N,qBAAqB,SAASzO;gBAC1B,IAAItD,OAAO9X,MACPiY,cAAcmD,KAAK0O,UAAU9pB,KAAK8e,SAASiL,WAAW9R,aACtD+R,oBAAoB5O,KAAK4O,qBAAqBhqB,KAAK8e,SAASiL,WAAWC,mBACvEpG;gBAEJ,SAASqG;oBACL,IAAItqB,GAAGkT,kBAAkBqC,eAAe;wBAEpC,IAAI4C,KAAKgH,SAASoL,YAAYC,kBAC1BxqB,GAAG0O,UACF1O,GAAGyO,UACJ0J,KAAKsS,oBAAoBJ,mBAAmB,SAAS;4BAErD,OAAO;;wBAGX,IAAI5O,KAAK1R,aAAa5F,WAAW;4BAC7B,OAAOgU,KAAKgH,SAASpV;;wBAGzB,OAAO0R,KAAK1R;;oBAGhB,OAAO;;gBAGXka,SAAS,IAAIjkB,GAAGiY;oBACZK,aAAaA;oBACbrY,SAASwb,KAAKxb;oBACdsY,YAAYlY,KAAK8e,SAASuL,QAAQC;oBAClCnS,SAASiD,KAAKjD;oBACdC,YAAYpY,KAAK8e,SAASuL,QAAQE;oBAClClS,4BAA4BrY,KAAK8e,SAASoL,YAAYM;oBACtD9gB,UAAUugB;oBACVvoB,MAAM1B,KAAK8e,SAASyI,QAAQkD;oBAC5BnS,UAAU,SAAS/O;wBACfuO,KAAK4S,eAAenhB;;oBAExBgP,OAAO6C,KAAK7C,SAAS,OAAOvY,KAAK8e,SAASzb,KAAKsnB,iBAAiBvP,KAAK7C;;gBAGzEvY,KAAK4qB,gBAAgBtY,YAAY;oBAC7BsR,OAAOzR;;gBAGX2F,KAAK6L,SAAS9gB,KAAK+gB;gBAEnB,OAAOA;;YAGXiH,sBAAsB,SAASC,mBAAmBC;gBAC9C,IAAIjT,OAAO9X,MACPgrB,qBACAhT;oBACIqL,OAAOrjB,KAAK8e,SAASuE;oBACrBgE,gBAAgBrnB,KAAK8e,SAASuI;oBAC9BO,MAAM5nB,KAAK8e,SAAS8I;oBACpBF,aAAa1nB,KAAK6jB;oBAClB8D,eAAe3nB,KAAKmiB;oBACpB9M,UAAUrV,KAAK8e,SAASzJ;oBACxBc,QAAQnW,KAAK8e,SAAS3I;oBACtB4I,OAAO/e,KAAK8e,SAASC;oBACrBjZ,KAAKnG,GAAGgQ,KAAKmI,KAAKhS,KAAKgS;oBACvBmT,mBAAmBjrB,KAAK8e,SAASwF,MAAM4G;oBACvCC,YAAY,SAAS5Q,IAAI7Y,MAAM0pB,QAAQC;wBACnC,IAAID,SAAS,KAAKC,QAAQ,GAAG;4BACzB;;wBAGJ,IAAIL,eAAezQ,KAAK;4BACpB,IAAIyQ,eAAezQ,IAAI6Q,WAAWA,UAAUJ,eAAezQ,IAAI8Q,UAAUA,OAAO;gCAC5EvT,KAAKwT,YAAY/Q,IAAI7Y,MAAM0pB,QAAQC;gCACnCvT,KAAKgH,SAASiI,UAAUoE,WAAW5Q,IAAI7Y,MAAM0pB,QAAQC;;+BAGxD;4BACDvT,KAAKwT,YAAY/Q,IAAI7Y,MAAM0pB,QAAQC;4BACnCvT,KAAKgH,SAASiI,UAAUoE,WAAW5Q,IAAI7Y,MAAM0pB,QAAQC;;wBAGzDL,eAAezQ;4BAAO6Q,QAAQA;4BAAQC,OAAOA;;;oBAGjDE,YAAY,SAAShR,IAAI7Y,MAAMY,QAAQ+R;+BAC5B2W,eAAezQ;wBAEtB,IAAIK,SAAS9C,KAAK2K;4BAAYlI,IAAIA;2BAAKK,QACnCtL;wBAMJ,IAAIsL,WAAWjb,GAAGib,OAAO8C,qBAAqB9C,WAAWjb,GAAGib,OAAO+C,eAAe;4BAC9E;;wBAGJrO,SAASwI,KAAK0T,YAAYjR,IAAI7Y,MAAMY,QAAQ+R;wBAI5C,IAAI/E,kBAAmB3P,GAAG+L,SAAS;4BAC/B4D,OAAOiI,KAAK;gCACRO,KAAKgH,SAASiI,UAAUwE,WAAWhR,IAAI7Y,MAAMY,QAAQ+R;;+BAGxD;4BACDyD,KAAKgH,SAASiI,UAAUwE,WAAWhR,IAAI7Y,MAAMY,QAAQ+R;;;oBAG7DoX,UAAU,SAASlR,IAAI7Y,MAAMgqB;wBACzB,IAAIjgB,UAAU,IAAI9L,GAAG+L;wBAErBoM,KAAKyQ;4BACD7mB,MAAM;4BACN0N,UAAUzP,GAAGgQ,KAAKmI,KAAKgH,SAASiI,UAAU0E,UAAU3T,MAAMyC,IAAI7Y;4BAC9D4V,WAAW7L,QAAQK;4BACnBuL,WAAW;gCACPqU,yBAAyB5U,KAAK;oCAC1BgB,KAAK6T,UAAUpR,IAAI7Y;;gCAGvB+J,QAAQG;;4BAEZ8c,YAAYnO;;wBAGhB,OAAO9O;;oBAEXmgB,cAAcjsB,GAAGgQ,KAAK3P,KAAK6rB,eAAe7rB;oBAC1C8rB,UAAU,SAASvR,IAAI7Y;wBACnBoW,KAAKiU,UAAUxR,IAAI7Y;wBACnB,IAAIsqB,iBAAiBlU,KAAKgH,SAASiI,UAAU+E,SAASvR,IAAI7Y;wBAE1D,IAAI/B,GAAGiX,iBAAiBoV,iBAAiB;4BACrClU,KAAKhS,IAAInG,GAAG8H,OAAO,gEAAgE8S;4BACnF,OAAOyR;;wBAGX,OAAO,IAAIrsB,GAAG+L,UAAUE;;oBAE5BqgB,eAAe,SAAS1R,IAAI7Y,MAAMwqB;wBAC9BpU,KAAKqU,eAAe5R,IAAI2R;wBACxB,IAAIE,sBAAsBtU,KAAKgH,SAASiI,UAAUkF,cAAc1R,IAAI7Y,MAAMwqB;wBAE1E,IAAIvsB,GAAGiX,iBAAiBwV,sBAAsB;4BAC1CtU,KAAKhS,IAAInG,GAAG8H,OAAO,wEAAwE8S,IAAI2R,UAAUG;4BACzG,OAAOD;;wBAGX,OAAO,IAAIzsB,GAAG+L,UAAUE;;oBAE5B0gB,sBAAsB,SAAS/R,IAAI2R,WAAW5pB,QAAQ+R;wBAClDyD,KAAKyU,sBAAsBhS,IAAI2R;wBAC/BpU,KAAKgH,SAASiI,UAAUuF,qBAAqBtc,MAAM8H,MAAMhQ;;oBAE7D0kB,UAAU,SAASjS,IAAI7Y,MAAMwqB,WAAWO;wBACpC,OAAO3U,KAAKgH,SAASiI,UAAUyF,SAASjS,IAAI7Y,MAAMwqB,WAAWO;;oBAEjEC,aAAa,SAASnS,IAAI7Y,MAAMirB,cAActY;wBAC1C,OAAOyD,KAAK8U,aAAa5c,MAAM8H,MAAMhQ;;oBAEzC+kB,eAAe,SAAStS,IAAIgC;wBACxBzE,KAAKhS,IAAI,wCAAwCgS,KAAKoL,QAAQ3I,MAAM,WAAWgC,UAAU;wBACzFzE,KAAKgO,QAAQvL,IAAIgC;;oBAErB0D,SAAStgB,GAAGgQ,KAAKmI,KAAKmI,SAASnI;oBAC/BoL,SAASvjB,GAAGgQ,KAAKmI,KAAKoL,SAASpL;oBAC/B6K,SAAShjB,GAAGgQ,KAAKmI,KAAK6K,SAAS7K;oBAC/BgV,SAASntB,GAAGgQ,KAAKmI,KAAKiV,UAAUjV;oBAChCkV,eAAe,SAAStS;wBACpB,OAAO5C,KAAK2K;4BAAY/H,MAAMA;;;oBAElCuS,UAAU,SAAS1S;wBACf,IAAIK,SAAS9C,KAAK2K;4BAAYlI,IAAIA;2BAAKK;wBACvC,OAAOA,WAAWjb,GAAGib,OAAOwC,UACxBxC,WAAWjb,GAAGib,OAAOsC,aACrBtC,WAAWjb,GAAGib,OAAO6C,mBACrB7C,WAAWjb,GAAGib,OAAO0C;;oBAE7BN,oBAAoBlF,KAAKkI,YAAYhD;oBACrCC,eAAenF,KAAKkI,YAAY/C;oBAChCiQ,cAAc,SAAS3S;wBACnB,OAAOzC,KAAK2K;4BAAYlI,IAAIA;2BAAKK,WAAWjb,GAAGib,OAAO2C;;oBAE1D4P,qBAAqBxtB,GAAGgQ,KAAKmI,KAAKsV,sBAAsBtV;oBACxDmE,WAAW,SAAS1B,IAAIK;wBACpB9C,KAAKkI,YAAY/D,UAAU1B,IAAIK;;;gBAI3Cjb,GAAG+C,KAAK1C,KAAK8e,SAASyI,SAAS,SAASrb,MAAMtJ;oBAC1CoV,QAAQ9L,QAAQtJ;;gBAGpBoV,QAAQyP,gBAAgBznB,KAAK6kB;gBAE7B,IAAIiG,mBAAmB;oBACnBnrB,GAAG+C,KAAKooB,mBAAmB,SAAStb,KAAK5M;wBACrCoV,QAAQxI,OAAO5M;;;gBAIvB,OAAO,IAAIjD,GAAG0tB,wBAAwBrV,SAAS+S;;YAGnDuC,qBAAqB,SAAS/S;gBAC1Bva,KAAKijB;gBACLjjB,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAOuC;;YAG7CoQ,aAAa,SAASviB;gBAClB,IAAIA,UAAU,GAAG;oBACb,OAAOA,QAAQhL,KAAK8e,SAASzb,KAAKmqB,YAAY;;gBAElD,IAAI/c,KAAK;gBACT,GAAG;oBACCzF,QAAQA,QAAQ;oBAChByF;yBACKzF,QAAQ;gBAEjB,OAAO1J,KAAKmsB,IAAIziB,OAAO,IAAK0iB,QAAQ,KAAK1tB,KAAK8e,SAASzb,KAAKmqB,YAAY/c;;YAK5Ekd,2BAA2B;gBACvB,IAAI7V,OAAO9X;gBAEXA,KAAK4tB;gBAELjuB,GAAG+C,KAAK1C,KAAK8e,SAAS+O,cAAc,SAASlrB,KAAKmrB;oBAC9C,IAAIpkB,WAAWokB,uBAAuBpkB,UAClCqgB,aAAapqB,GAAG6B,WAAWsW,KAAKgH,SAASiL,YAAY,OACrDgE,kBAAkBpuB,GAAG6B,WAAWssB;oBAEpC,IAAIpkB,aAAa5F,WAAW;wBACxB4F,WAAWoO,KAAKgH,SAASpV;;oBAG7B,IAAIqkB,gBAAgBhE,YAAY;wBAC5BpqB,GAAG6B,OAAOuoB,YAAY+D,uBAAuB/D,YAAY;;oBAG7DpqB,GAAG6B,OAAOusB;wBACNrkB,UAAUA;wBACVqgB,YAAYA;uBACb;oBAEHjS,KAAKkW,iBAAiBD;;;YAI9B/L,YAAY,SAASxJ;gBACjB,IAAIyV,mBAAmBjuB,KAAK4tB,kBAAkBpV;gBAE9C,IAAIyV,kBAAkB;oBAClB,OAAOA,iBAAiBruB;uBAEvB,IAAI4Y,aAAaxY,KAAKkuB,kBAAkB;oBACzC,OAAOluB,KAAK8e,SAAS8E;;;YAW7BiD,cAAc,SAASsH;gBACnB,IAAIC,QAAQC,WACRC,kBAAkBH;gBAGtB,IAAIG,2BAA2B3uB,GAAG6X,WAAW;oBACzC8W,kBAAkBA,gBAAgB7W;;gBAItC,IAAI6W,oBAAoB3uB,GAAGyJ,OAAOklB,kBAAkB;oBAChD,IAAI3uB,GAAGyI,OAAOkmB,kBAAkB;wBAC5B,OAAOA,gBAAgB1H;2BAEtB,IAAI0H,gBAAgBnlB,QAAQF,kBAAkB,WAC/CqlB,gBAAgBpuB,KAAK+I,kBAAkB,QAAQ;wBAE/C,OAAOqlB,gBAAgBzqB,aAAalE,GAAGiY,aAAac;;oBAGxD0V,SAASE,gBAAgB7rB,qBAAqB;oBAE9C9C,GAAG+C,KAAK0rB,QAAQ,SAASzrB,KAAK4G;wBAC1B,IAAIA,MAAM1F,aAAa,YAAY,QAAQ;4BACvCwqB,YAAY9kB;4BACZ,OAAO;;;oBAIf,IAAI8kB,WAAW;wBACX,OAAOA,UAAUxqB,aAAalE,GAAGiY,aAAac;;;;YAK1D0U,sBAAsB,SAASpM;gBAC3B,OAAOhhB,KAAKqkB,uBAAuBjC,IAAIpB;;YAG3CuN,iBAAiB;gBACb,OAAOvuB,KAAKggB,YAAYnE;oBACpBjB,UACIjb,GAAGib,OAAO2C,WACV5d,GAAGib,OAAO6C,iBACV9d,GAAGib,OAAOwC,QACVzd,GAAGib,OAAOS,YACV1b,GAAGib,OAAOsC,WACVvd,GAAGib,OAAO0C;mBAEf5X;;YAKP8oB,oBAAoB,SAAShW;gBACzB,IAAIuV,kBAAkB/tB,KAAK4tB,kBAAkBpV;gBAE7C,OAAOuV,kBAAkBA,gBAAgBhE,aAAa/pB,KAAK8e,SAASiL;;YAGxE0E,0BAA0B,SAASC;gBAC/B,IAAIA,YAAYlT,gBAAgB7b,GAAG6X,WAAW;oBAC1C;wBACI9V,MAAM/B,GAAGmS,YAAY4c,YAAYlT,KAAK/D;wBACtC8D,MAAMmT,YAAYlT,KAAK/D,cAAc8D;;;gBAI7C;oBACI7Z,MAAM1B,KAAKyiB;wBAAYlI,IAAImU,YAAYnU;uBAAK7Y;oBAC5C6Z,MAAMvb,KAAKyiB;wBAAYlI,IAAImU,YAAYnU;uBAAKgB;;;YAIpDoT,2BAA2B,SAASC;gBAChC,IAAI9W,OAAO9X,MACP6uB;gBAEJlvB,GAAG+C,KAAKksB,cAAc,SAASjsB,KAAK+rB;oBAChCG,gBAAgBhsB,KAAKiV,KAAK2W,yBAAyBC;;gBAGvD,OAAOG;;YAIXC,qBAAqB;gBACjB,IAAI9uB,KAAK8e,SAASiQ,OAAO1gB,OAAO1O,GAAG0O,OAAO;oBACtC,IAAI2gB,kBAAkB,0BAClBpL,SAAS5jB,KAAK8e,SAASiQ,OAAOnL,QAC9BpL,WAAWoL,SAAS5jB,KAAK6mB,aAAajD,UAAU5jB,KAAKkuB,kBACrDe,aAAajvB,KAAK8e;oBAGtB,IAAItG,YAAYA,aAAaxY,KAAKkuB,kBAAkB;wBAChDe,aAAajvB,KAAK4tB,kBAAkBpV;;oBAIxCyW,WAAWvlB,WAAW;oBAGtB,IAAIulB,WAAWlF,WAAW9R,gBAAgB,MAAM;wBAC5CgX,WAAWlF,WAAW9R,cAAc+W;2BAEnC;wBACDC,WAAWlF,WAAW9R,eAAe,MAAM+W;;oBAI/CrvB,GAAG+C,KAAK1C,KAAK2jB,UAAU,SAAShhB,KAAKihB;wBACjC,IAAIA,OAAOpK,kBAAkBhB,UAAU;4BACnCoL,OAAOjL,YAAYsW,WAAWvlB;4BAC9Bka,OAAOhK,eAAeqV,WAAWhX;4BAEjC,OAAO;;;;;YAMvBsQ,wBAAwB,SAAS2G;gBAC7B,IAAIpX,OAAO9X,MACPmvB,iBAAiBD,QAAQ9f;gBAE7B,IAAIzP,GAAGiX,iBAAiBuY,iBAAiB;oBACrCnvB,KAAK8F,IAAIopB,QAAQxtB,OAAO,oBAAoBwtB,QAAQxtB,OAAO,kCAAkCwtB,QAAQxG;oBACrG,OAAOyG,eAAerY,KAClB,SAASsY;wBACLtX,KAAKhS,IAAIopB,QAAQxtB,OAAO,0BAA0BwtB,QAAQxG;wBAC1DwG,QAAQ7X,UAAU+X;uBAEtB;wBACI,IAAIF,QAAQ5X,WAAW;4BACnBQ,KAAKhS,IAAIopB,QAAQxtB,OAAO,0BAA0BwtB,QAAQxG;4BAC1DwG,QAAQ5X;+BAEP;4BACDQ,KAAKhS,IAAIopB,QAAQxtB,OAAO,0BAA0BwtB,QAAQxG;;;;gBAK1E,IAAIyG,mBAAmB,OAAO;oBAC1BD,QAAQ7X,UAAU8X;uBAEjB;oBACD,IAAID,QAAQ5X,WAAW;wBACnBtX,KAAK8F,IAAIopB,QAAQxtB,OAAO,qCAAqCwtB,QAAQxG,aAAa;wBAClFwG,QAAQ5X;2BAEP;wBACDtX,KAAK8F,IAAIopB,QAAQxtB,OAAO,qCAAqCwtB,QAAQxG,aAAa;;;gBAI1F,OAAOyG;;YAIXtQ,gBAAgB,SAASrD,MAAMC,SAAS4T;gBACpC,IAAIvX,OAAO9X,MACP0a,OAAO/a,GAAGoN,eACVwO,QAAQ,GACR7Z,OAAO/B,GAAGmS,YAAY0J,OACtB8T,aAAa9T,KAAKpQ,QAAQoQ,MAC1B+T,UAAUvvB,KAAKwvB,wBACXxvB,KAAKwvB,wBACL7vB,GAAGgQ,KAAKmI,KAAK2X,uBAAuB3X;gBAE5C,KAAKnY,GAAGiJ,QAAQ0mB,eAAeA,WAAW/T,QAAQ,GAAG;oBACjDA,OAAO+T,WAAW/T;;gBAGtBgU,QAAQD,YAAY5tB,MAAMgZ,MAAMa,MAAM8T,oBAAoB5T,SAASzb,KAAK8e,SAASyI,QAAQC;oBACrFzH,YAAYjI,KAAKkI;oBACjB0H,aAAa5P,KAAK+L;oBAClB6L,kBAAkB,SAASnV,IAAIiB;wBAC3B1D,KAAKoI,SAAS3P,IAAIgK,IAAIiB;wBACtB1D,KAAKmL;wBACLnL,KAAK6X,aAAapV;;;;YAK9BkV,uBAAuB,SAASjU,MAAM9Z,MAAMgZ,MAAMa,MAAMqU,UAAUnU;gBAC9D,IAAIlB,KAAKva,KAAKggB,YAAY7E;oBACtBT,MAAMA;oBACNhZ,MAAMA;oBACN6Z,MAAMA;oBACNE,SAASA;oBACTD,MAAMA;;gBAGVxb,KAAKkgB,SAAS3P,IAAIgK,IAAIiB;gBAEtBxb,KAAK2vB,aAAapV;gBAElBva,KAAKijB;gBAEL2M,SAAS/sB;oBAAM0X,IAAIA;oBAAIiB,MAAMA;;;YAGjCiN,qBAAqB,SAASrd,MAAMykB;gBAChC,IAAIC,YAAY1kB,KAAKlL,KAAKmF,MAAM,KAAK,IACjC3D,OAAOmuB;gBAGX,IAAInuB,QAAQ,MAAM;oBACdA,OAAO1B,KAAK8e,SAASuJ,MAAMrJ;;gBAG/Btd,QAAQ,MAAMouB;gBAEd9vB,KAAKoe;oBACD1c,MAAMA;oBACN0J,MAAMA;;;YAId2kB,sBAAsB,SAASxV;gBAC3B,IAAIva,KAAKyiB;oBAAYlI,IAAIA;mBAAKK,WAAWjb,GAAGib,OAAOkD,SAAS;oBACxD,IAAIpc,OAAO1B,KAAKigB,QAAQ1F;oBAExBva,KAAKijB;oBACLjjB,KAAK6iB;oBACL7iB,KAAKkgB,SAASqD,QAAQhJ;oBACtBva,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAOkD;oBACzC9d,KAAK8F,IAAI,yBAAyBpE,OAAO;;;YAIjDsuB,qBAAqB,SAASzV,IAAIyN;gBAC9B,IAAItmB,OAAO1B,KAAKigB,QAAQ1F;gBAExBva,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAOgD;gBACzC5d,KAAK8F,IAAI,yBAAyBpE,OAAO,iBAAiB;gBAK1D,KAAKsmB,YAAYA,SAAS1T,oBAAoBxQ,WAAW;oBACrD9D,KAAK8e,SAASiI,UAAUC,QAAQzM,IAAI7Y,MAAM,yBAAyBsmB;uBAElE;oBACDhoB,KAAK8e,SAASiI,UAAUC,QAAQzM,IAAI7Y,MAAM,8CAA8CsmB,SAASpN,QAAQoN;;;YAKjHgG,kBAAkB,SAAS5S;gBACvB,IAAIwI,SAAS5jB,KAAK6pB;oBACdC,QAAQ1O,KAAK2O,WAAW9R;oBACxB+R,mBAAmB5O,KAAK2O,WAAWC;oBACnCpqB,SAASwb,KAAKxb;oBACduY,SAASiD,KAAKjD;oBACdzO,UAAU0R,KAAK1R;oBACf6O,OAAO6C,KAAKuP;;gBAGhB3qB,KAAK4tB,kBAAkBhK,OAAOpK,iBAAiB4B;;YAGnD6U,2BAA2B;gBACvBjwB,KAAKkwB,eAAevwB,GAAGwwB,eAAe,IAAIxwB,GAAGwwB,YACzCnwB,KAAK8e,SAAS7N,MAAMtR,GAAGgQ,KAAK3P,KAAKkmB,mBAAmBlmB,OAAOL,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;gBAGjF,IAAIA,KAAKkwB,gBAAgBlwB,KAAKkwB,aAAaE,gBAAgB;oBACvDpwB,KAAK6jB,eAAe7jB,KAAK2oB,aACrB3oB,KAAK8e,SAASyI,QAAQrJ,QAASle,KAAKkwB,aAAaG;oBAGrDrwB,KAAK8e,SAASwR,aAAatwB,KAAKkwB,aAAaK;oBAC7C,IAAIvwB,KAAKkwB,aAAaM,aAAa;wBAC/BxwB,KAAK8e,SAASyI,QAAQpJ,WAAWne,KAAKkwB,aAAaM;;uBAGtD;oBACDxwB,KAAK6jB,eAAe7jB,KAAK2oB,aAAa3oB,KAAK8e,SAASyI,QAAQrJ;;;YAIpEuS,mBAAmB;gBACf,KAAK9wB,GAAGunB,4BAA4BlnB,KAAK8e,SAAS4B,WAAWF,SAAS;oBAClE,OAAO;;gBAGX,IAAIxgB,KAAK8e,SAAS8I,KAAK8I,UAAU;oBAC7B,IAAI/wB,GAAGkT,kBAAkB2C,mBAAmB;wBACxC,OAAO;;oBAGX,IAAI7V,GAAGkT,kBAAkB0C,qBAAqBvV,KAAK8e,SAAS8I,KAAK+I,UAAU;wBACvE,OAAO;;oBAGX,OAAO;;gBAGX,OAAO;;YAGXvG,qBAAqB,SAASwG,SAAS5e;gBACnC,IAAI6e,QAAQ;gBAEZ,KAAKD,QAAQlrB,QAAQ;oBACjB,OAAO;;gBAGX/F,GAAG+C,KAAKkuB,SAAS,SAASjuB,KAAKmuB;oBAK3B,IAAInxB,GAAGwH,SAAS2pB,aAAa;wBAEzB,IAAIC,WAAW,IAAIlvB,OAAO,QAAQivB,aAAa,KAAK;wBAEpD,IAAI9e,SAASmC,MAAM4c,aAAa,MAAM;4BAClCF,QAAQ;4BACR,OAAO;;;;gBAKnB,OAAOA;;YAWX1K,YAAY,SAAS6K,MAAMC,kBAAkBhqB;gBACzC,IAAIlB,UAAU/F,KAAK8e,SAASoS,SAASF,OACjChH,wBACAmH,WAAWphB,OAAOkhB,mBAClBvvB,OAAOyvB,MAAM,IACb3Y,WAAWxY,KAAK6mB,aAAa5f,OAC7BmqB,iBAAiBpxB,KAAKwuB,mBAAmBhW,WACzC6Y,sBAAsBC;gBAE1B,SAASrkB,EAAEvL,MAAM6vB;oBAAexrB,UAAUA,QAAQ7D,QAAQR,MAAM6vB;;gBAEhE5xB,GAAG+C,KAAK0uB,eAAepH,mBAAmB,SAASrnB,KAAK6uB;oBAKpD,IAAI7xB,GAAGwH,SAASqqB,mBAAmB;wBAC/BxH,kBAAkBnnB,KAAK2uB;;;gBAI/BH,uBAAuBrH,kBAAkBpZ,KAAK,MAAM3H;gBAEpDgE,EAAE,UAAUjN,KAAK8e,SAAS2S,eAAe/vB;gBACzCuL,EAAE,gBAAgBokB;gBAClBpkB,EAAE,eAAejN,KAAKutB,YAAY6D,eAAeM;gBACjDzkB,EAAE,kBAAkBjN,KAAKutB,YAAY6D,eAAeO;gBAEpDL,mBAAmBvrB,QAAQoO,MAAM;gBACjC,IAAImd,qBAAqB,MAAM;oBAC3B3xB,GAAG+C,KAAK4uB,kBAAkB,SAAS3uB,KAAKivB;wBACpC3kB,EAAE2kB,aAAaT,MAAMxuB;;;gBAI7B3C,KAAK8e,SAASiI,UAAUC,QAAQ,MAAMtlB,MAAMqE,SAASjC;gBAErD,OAAOiC;;YAYXwe,cAAc,SAAShK,IAAInL;gBACvB,IAAIpP,KAAK6xB,qBAAqBtX,KAAK;oBAC/Bva,KAAKijB;oBACLjjB,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAO6C;oBAEzC,IAAIrO,UAAU;wBACVA,SAASmL;2BAER;wBACDva,KAAKkgB,SAASoE,MAAM/J;;oBAGxB,OAAO;;;YAIfoP,mBAAmB,SAASpP,IAAIK;gBAC5B,IAAI9C,OAAO9X,MACP8xB,cAAc9xB,KAAKuuB;gBAEvB,IAAI3T,WAAWjb,GAAGib,OAAO8C,mBAAmB;oBACxC1d,KAAKkkB,+BAA+BrhB,KAAK0X;uBAExC,IAAIK,WAAWjb,GAAGib,OAAO+C,eAAe;oBACzC3d,KAAKmkB,4BAA4BthB,KAAK0X;;gBAG1C,IAAIuX,gBAAgB,MACf9xB,KAAKkkB,+BAA+Bxe,UAAU1F,KAAKmkB,4BAA4Bze,SAAS;oBAEzFkkB,WAAW;wBACP9R,KAAKia,eAAeja,KAAKoM,gCAAgCpM,KAAKqM;uBAC/D;;;YAIX1F,kCAAkC;gBAC9B,IAAI3G,OAAO9X;gBAEX,IAAIA,KAAK8e,SAASoL,YAAY8H,qBAAqBryB,GAAG6O,YAAY7O,GAAG+O,aAAa;oBAC9Ekb,WAAW;wBACPjlB,OAAOstB,MAAMna,KAAKgH,SAASoS,SAASgB;uBACrC;oBACH,MAAM,IAAIvyB,GAAGwB,MAAMnB,KAAK8e,SAASoS,SAASgB;;;YAIlDC,+BAA+B,SAAS5X,IAAI7Y,MAAM0wB,UAAU/d;gBAGxD,KAAK+d,SAASxmB,SAAS;oBACnB,IAAIyI,OAAOA,IAAIuG,WAAW,QAAQwX,SAASpoB,OAAO;wBAC9ChK,KAAK8e,SAASiI,UAAUC,QAAQzM,IAAI7Y,MAAM,gCAAgC2S,IAAIuG,QAAQvG;2BAErF;wBACD,IAAIge,cAAcD,SAASpoB,QAAQooB,SAASpoB,QAAQhK,KAAK8e,SAASzb,KAAKivB;wBACvEtyB,KAAK8e,SAASiI,UAAUC,QAAQzM,IAAI7Y,MAAM2wB,aAAahe;;;;YAKnEke,8CAA8C,SAASC,WAAWroB,OAAO4Q,OAAOmD,QAAQC;gBACpF,IAAIrG,OAAO9X;gBAEX,IAAImK,MAAMzE,SAASqV,OAAO;oBACtB,IAAIyX,cAAcxyB,KAAK8e,SAASiL,WAAW0I,wBAAwB;wBAE/D7I,WAAW;4BACP,IAAI8I,uBAAuB5a,KAAK2W,yBAAyBtkB,MAAM4Q,SAC3DvC,WAAWV,KAAK+O,aAAa1c,MAAM4Q,OAAOS,OAC1CoI,SAAS9L,KAAKkK,WAAWxJ;4BAE7BV,KAAKyQ;gCACD7mB,MAAM;gCACN0N,UAAUzP,GAAGgQ,KAAKmI,KAAKgH,SAASiI,UAAU4L,YAAY7a,MAAM4a,sBAAsB9O;gCAClFvM,WAAW1X,GAAGgQ,KAAKmI,KAAK8a,4BAA4B9a,MAAM3N,OAAO4Q,OAAOmD,QAAQC;gCAChF7G,WAAW3X,GAAGgQ,KAAKmI,KAAK+a,4BAA4B/a,MAAM3N,OAAO4Q,OAAOmD,QAAQC;gCAChFuK,YAAY,WAAWgK,qBAAqBhxB,OAAO,cAAcgxB,qBAAqBnX;;2BAE3F;2BAEF,KAAKiX,WAAW;wBACjB,MAAOzX,QAAQ5Q,MAAMzE,QAAQqV,SAAS;4BAClCjD,KAAKwV,oBAAoBnjB,MAAM4Q,OAAOR;;;;;YAMtDwX,gBAAgB,SAASe,YAAYC;gBACjC/yB,KAAKokB,kBAAkBpkB,KAAKokB,eAAe4O,cAAcF,YAAYC,QAAQ/yB,KAAK0jB;gBAElF1jB,KAAK8e,SAASiI,UAAUiM,cAAcrzB,GAAG6B,WAAWsxB,aAAanzB,GAAG6B,WAAWuxB;gBAE/E/yB,KAAKkkB;gBACLlkB,KAAKmkB;;YAeTyI,cAAc,SAASrS,IAAI7Y,MAAMirB,cAActY,KAAKjF;gBAChD,IAAI0I,OAAO9X;gBAEX8X,KAAK4L,gBAAgBnJ,MAAMoS,aAAa7U,KAAKgH,SAASwF,MAAM4G;gBAE5D,IAAIpT,KAAKmb,iBAAiB1Y,KAAK;oBAC3B,IAAI2Y,kBAAkBpb,KAAKgH,SAASwF,MAAM6O,mBAAmB;oBAE7Drb,KAAKqa,8BAA8BniB,MAAM8H,MAAMhQ;oBAC/CgQ,KAAKgH,SAASiI,UAAU2F,YAAYnS,IAAI7Y,MAAMoW,KAAK0L,aAAajJ;oBAChEzC,KAAKsb,mBAAmB7Y,IAAI7Y;oBAE5BoW,KAAKkI,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAO6C;oBACzC3F,KAAK2L,eAAelJ,MAAMqP,WAAW;wBACjC9R,KAAKhS,IAAI,wBAAwBpE,OAAO;wBAExC,IAAI0N,UAAU;4BACVA,SAASmL;+BAER;4BACDzC,KAAKoI,SAASoE,MAAM/J;;uBAEzB2Y;oBAEH,OAAO;;;YAIfE,oBAAoB,SAAS7Y,IAAI7Y;gBAC7B1B,KAAK8F,IAAI,aAAa9F,KAAK8e,SAASwF,MAAM6O,mBAAmB,8BAA8BzxB,OAAO;;YAItGmwB,sBAAsB,SAAStX;gBAC3B,IAAI8Y,YAAYrzB,KAAKgjB,mBACjBhR;gBAEJ,IAAIhS,KAAK0jB,gBAAgBnJ,KAAK;oBAC1Bva,KAAK8F,IAAI,kCAAkCyU,IAAI;oBAC/C,OAAO;uBAEN,IAAIva,KAAKkgB,SAASY,QAAQvG,KAAK;oBAChCvI,WAAWhS,KAAKigB,QAAQ1F;oBAExB,IAAIva,KAAK8e,SAASiI,UAAUuM,cAAc/Y,IAAIvI,cAAc,OAAO;wBAC/D,OAAO;;oBAGX,IAAIqhB,YAAY,KAAKrzB,KAAKijB,uBAAuB,IAAIoQ,WAAW;wBAC5DrzB,KAAKmmB,WAAW;wBAChB,OAAO;;oBAGXnmB,KAAK8F,IAAI,0BAA0BkM,WAAW,YAAYuI,KAAK;oBAC/D,OAAO;uBAEN;oBACDva,KAAK8F,IAAI,MAAMyU,KAAK,4BAA4B;oBAChD,OAAO;;;YAIfoR,WAAW,SAASpR,IAAI7Y;gBACpB1B,KAAKijB;gBAELsQ,aAAavzB,KAAKyjB,eAAelJ;gBAEjC,IAAIiZ,kBAAkB7zB,GAAG2F,QAAQtF,KAAK0e,YAAYnE;gBAClD,KAAKva,KAAK8e,SAASwR,cAAckD,mBAAmB,GAAG;oBACnDxzB,KAAK0e,WAAWrC,OAAOmX,iBAAiB;;gBAG5CxzB,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAOyC;;YAG7CmO,aAAa,SAASjR,IAAI7Y,MAAMY,QAAQ+R;gBACpC,KAAK/R,OAAOsJ,SAAS;oBACjB5L,KAAKijB;oBACLjjB,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAO+C;oBAEzC,IAAIrb,OAAOtC,KAAK8e,SAASwF,MAAM4G,kCAAkC,MAAM;wBACnElrB,KAAK0jB,gBAAgBnJ,MAAM;;uBAG9B;oBACD,IAAIjY,OAAOmkB,cAAc;wBACrBzmB,KAAKwhB,eAAejH,MAAMjY,OAAOmkB;;oBAGrCzmB,KAAK6iB;oBACL7iB,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAO8C;;gBAG7C1d,KAAKmyB,8BAA8B5X,IAAI7Y,MAAMY,QAAQ+R;gBAErD,OAAO/R,OAAOsJ,UAAU,OAAO;;YAGnCkc,WAAW,SAASvN;gBAChBva,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAOiD;;YAG7CmI,mBAAmB,SAASzL,IAAIyN,UAAUC;gBACtC,IAAIvmB,OAAO1B,KAAKigB,QAAQ1F;gBAExB,IAAI0N,SAAS;oBACTjoB,KAAKgwB,oBAAoBzV,IAAIyN;uBAE5B;oBACDhoB,KAAK+vB,qBAAqBxV;;;YAIlCmQ,gBAAgB,SAASnhB;gBACrB,IAAIkqB;gBAEJ,IAAI9zB,GAAGkT,kBAAkBqC,eAAe;oBACpC,KAAKue,YAAY,GAAGA,YAAYlqB,MAAMmW,MAAMha,QAAQ+tB,aAAa;wBAC7DzzB,KAAK0mB,sBAAsBnd,MAAMmW,MAAM+T,YAAYlqB;;oBAGvDvJ,KAAKoe,SAAS7U,MAAMmW;uBAGnB,IAAInW,MAAM7C,MAAMhB,SAAS,GAAG;oBAC7B1F,KAAKoe,SAAS7U;;gBAGlB5J,GAAG+C,KAAK1C,KAAK2jB,UAAU,SAAShhB,KAAKihB;oBACjCA,OAAO/J;;;YAIfyR,aAAa,SAAS/Q,IAAI7Y,MAAM0pB,QAAQC;gBACpCrrB,KAAKokB,kBAAkBpkB,KAAKokB,eAAesP,qBAAqBnZ,IAAI6Q,QAAQC;;YAGhFsI,WAAW,SAASpZ,IAAI7Y;YAIxBkyB,0BAA0B,SAASrZ,IAAI7Y;gBACnC1B,KAAK2zB,UAAU3jB,MAAMhQ,MAAM8H;gBAC3B9H,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAOsC;gBACzCld,KAAK6zB,aAAa7jB,MAAMhQ,MAAM8H;gBAE9B,IAAI9H,KAAK8e,SAASwR,YAAY;oBAC1BtwB,KAAK8e,SAASiI,UAAU+M,YAAY9jB,MAAMhQ,MAAM8H;oBAChD9H,KAAKygB,YAAYlG;uBAEhB;oBACDva,KAAK+zB,eAAexZ;oBACpBva,KAAK8e,SAASiI,UAAU+M,YAAY9jB,MAAMhQ,MAAM8H;;;YAIxD6Y,iBAAiB,SAASpG,IAAIyZ,mBAAmBC;gBAC7C,IAAIvZ,OAAO1a,KAAKkjB,QAAQ3I,KACpB2Z;gBAEJ,IAAIF,mBAAmB;oBACnBE,4BAA4Bv0B,GAAGgQ,KAAKqkB,mBAAmBh0B,MAAMua,IAAIG,MAAMuZ;;gBAG3E,IAAIj0B,KAAKywB,qBAAqB;oBAC1BzwB,KAAKuoB;wBACD7mB,MAAM;wBACN0N,UAAUzP,GAAGgQ,KAAK3P,KAAK8e,SAASiI,UAAUoN,gBAAgBn0B,MAAMua;wBAChElD,WAAW6c,6BACPv0B,GAAGgQ,KAAK3P,KAAKo0B,eAAeC,YAAYr0B,MAAMua,IAAIG,MAAMuZ;wBAC5DvL,YAAYnO;;oBAEhB,OAAO;uBAEN;oBACDva,KAAK8F,IAAI,mCAAmCyU,KAAK,0DAC7C,oEAAoE;oBACxE,OAAO;;;YAIfsZ,cAAc,SAAStZ;YAIvB+Z,kBAAkB,SAASlJ,QAAQC;gBAC/BrrB,KAAK8e,SAASiI,UAAUwN,gBAAgBnJ,QAAQC;;YAGpDQ,eAAe,SAAStR;YAIxBwR,WAAW,SAASxR,IAAI7Y;gBACpB1B,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAO2C;;YAG7C4O,gBAAgB,SAAS5R,IAAI2R;YAI7BK,uBAAuB,SAAShS,IAAI2R;gBAChC,KAAKlsB,KAAK0jB,gBAAgBnJ,OAAOva,KAAK8e,SAASwF,MAAMkQ,YAAY;oBAC7Dx0B,KAAKwjB,aAAajJ,MAAM;;;YAIhCmP,uBAAuB,SAASnP,IAAI4B,WAAWD;gBAE3C,IAAIA,cAAcvc,GAAGib,OAAO0C,QAAQ;oBAChCiW,aAAavzB,KAAKyjB,eAAelJ;;;YAIzCka,iCAAiC,SAAS7F;gBACtC,IAAI9W,OAAO9X;gBAEXL,GAAG+C,KAAKksB,cAAc,SAASjsB,KAAK+rB;oBAChC5W,KAAKwV,oBAAoBoB,YAAYnU;;;YAI7Cma,iCAAiC,SAASC,uBAAuBxqB,OAAO+T,QAAQC,UAAUyF;gBACtF,IAAIqC,cACAoN,YAAYrzB,KAAKgjB,mBACjB4R,mCAAmC50B,KAAKijB;gBAE5C,IAAIoQ,cAAc,KAAKuB,oCAAoCvB,WAAW;oBAClE,IAAIlpB,MAAMzE,SAAS,GAAG;wBAClB1F,KAAKuoB;4BACD7mB,MAAM;4BACN0N,UAAUzP,GAAGgQ,KAAK3P,KAAK8e,SAASiI,UAAU4L,YAAY3yB,MAAM20B,sBAAsB,IAAI/Q;4BACtFvM,WAAW1X,GAAGgQ,KAAK3P,KAAK4yB,4BAA4B5yB,MAAMmK,OAAO,GAAG+T,QAAQC;4BAC5E7G,WAAW3X,GAAGgQ,KAAK3P,KAAK6yB,4BAA4B7yB,MAAMmK,OAAO,GAAG+T,QAAQC;4BAC5EuK,YAAY,WAAWve,MAAM,GAAGqR,KAAK9Z,OAAO,cAAcyI,MAAM,GAAGqR,KAAKD;;2BAG3E;wBACDvb,KAAKmmB,WAAW;;uBAGnB;oBACDnmB,KAAKy0B,gCAAgCtqB;oBACrC8b,eAAejmB,KAAK8e,SAASoS,SAAS2D,kBACjC3yB,QAAQ,iBAAiB0yB,kCACzB1yB,QAAQ,kBAAkBmxB;oBAC/BrzB,KAAK8mB,YAAYb;;;YAIzB4M,4BAA4B,SAAS1oB,OAAO4Q,OAAOmD,QAAQC;gBACvD,IAAI2W,YAAY/Z,QAAQ;gBAExB/a,KAAKstB,oBAAoBnjB,MAAM4Q,OAAOR,IAAIpQ,MAAM4Q,OAAOS,KAAK9Z;gBAE5D1B,KAAKuyB,6CAA6C,OAAOpoB,OAAO2qB,WAAW5W,QAAQC;;YAGvFyU,4BAA4B,SAASzoB,OAAO4Q,OAAOmD,QAAQC;gBACvD,IAAIrG,OAAO9X,MACP80B,YAAY/Z,QAAQ,GACpB2X,uBAAuB1yB,KAAKyuB,yBAAyBtkB,MAAM4Q;gBAE/D/a,KAAK+0B,wBAAwB5qB,MAAM4Q,QAAQ2X,sBACtC5b,KACD;oBACIgB,KAAKkd,QAAQ7qB,MAAM4Q,OAAOR,IAAI2D,QAAQC;oBACtCrG,KAAKya,6CAA6C,MAAMpoB,OAAO2qB,WAAW5W,QAAQC;mBAEtF;oBACIrG,KAAKya,6CAA6C,OAAOpoB,OAAO2qB,WAAW5W,QAAQC;;;YAK/F0B,wBAAwB,SAAS1V,OAAO+T,QAAQC;gBAC5C,IAAIhU,MAAMzE,WAAW,GAAG;oBACpB1F,KAAKmmB,WAAW;oBAChB;;gBAGJ,IAAIwO,wBAAwB30B,KAAK2uB,0BAA0BxkB,QACvDqO,WAAWxY,KAAK6mB,aAAa1c,MAAM,GAAGqR,OACtCoI,SAAS5jB,KAAKgiB,WAAWxJ;gBAE7BxY,KAAKuoB;oBACD7mB,MAAM;oBACN0N,UAAUzP,GAAGgQ,KAAK3P,KAAK8e,SAASiI,UAAUkO,iBAAiBj1B,MAAM20B,uBAAuB/Q;oBACxFvM,WAAW1X,GAAGgQ,KAAK3P,KAAK00B,iCAAiC10B,MAAM20B,uBAAuBxqB,OAAO+T,QAAQC,UAAUyF;oBAC/GtM,WAAW3X,GAAGgQ,KAAK3P,KAAKy0B,iCAAiCz0B,MAAMmK;oBAC/Due,YAAY;;;YAIpBwM,yBAAyB;gBACrB,IAAIpd,OAAO9X;gBAEXA,KAAK4qB,gBAAgB3qB,OAAO0E,QAAQ,gBAAgB,SAASkK;oBACzD,IAAIiJ,KAAKwK,iBAAiB;wBACtBzT,IAAIA,KAAKlK,OAAOwwB;wBAEhBtmB,EAAEC,cAAcgJ,KAAKgH,SAASoS,SAASkE;wBAEvC,OAAOtd,KAAKgH,SAASoS,SAASkE;;;;YAQ1CnR,qBAAqB;gBACjB,IAAInM,OAAO9X,MACPgY,UAAUhY,KAAK8e,SAASiF;gBAG5B,IAAIpkB,GAAG01B,WAAWr1B,KAAK8e,SAASiF,QAAQ5F,YAAY,MAAM;oBACtD,KAAKne,KAAKs1B,UAAU;wBAChB31B,GAAG6B,OAAOwW;4BAAU4P,MAAM5nB,KAAK8e,SAAS8I;;wBAExC5P,QAAQlS,MAAMnG,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;wBAChCgY,QAAQud,gBAAgB51B,GAAGgQ,KAAK3P,KAAKwe,gBAAgBxe;wBAErDA,KAAKs1B,WAAW,IAAI31B,GAAG01B,QAAQrd;;oBAGnC4R,WAAW;wBACP9R,KAAKwd,SAASE,UAAU1e,KAAK,SAASsb,UAAUpK;4BAC5ClQ,KAAK2d;4BACL3d,KAAKgH,SAASiI,UAAU2O,yBAAyBtD,UAAU,MAAMpK;2BAElE,SAASoK,UAAUpK;4BAElBlQ,KAAKgH,SAASiI,UAAU2O,yBAAyBtD,UAAU,OAAOpK;;uBAEvE;;;YAIXyN,yBAAyB;YAEzB1I,UAAU,SAASxS,IAAIqC;gBACnB5c,KAAKggB,YAAYrD,WAAWpC,IAAIqC;gBAChC5c,KAAKokB,kBAAkBpkB,KAAKokB,eAAeuR,UAAUpb;;YAGzD0Y,kBAAkB,SAAS1Y;gBACvB,IAAIwF,aAAa/f,KAAKggB,YAAYnE;oBAAUtB,IAAIA;;gBAGhD,KAAKva,KAAK0jB,gBAAgBnJ,OACnBva,KAAK8e,SAASwF,MAAMkQ,cACpBzU,WAAWnF,WAAWjb,GAAGib,OAAO0C,QAAQ;oBAE3C,IAAItd,KAAKwjB,aAAajJ,QAAQzW,WAAW;wBACrC9D,KAAKwjB,aAAajJ,MAAM;;oBAG5B,IAAIva,KAAKwjB,aAAajJ,MAAMva,KAAK8e,SAASwF,MAAMsR,iBAAiB;wBAC7D51B,KAAKwjB,aAAajJ,OAAO;wBACzB,OAAO;;;gBAIf,OAAO;;YAGXwZ,gBAAgB,SAASxZ;gBACrBva,KAAK0e,WAAW7b,KAAK0X;;YAIzBoV,cAAc,SAASpV;gBACnB,IAAI/B;gBAEJ,IAAI7Y,GAAGkT,kBAAkBqC,eAAe;oBACpCsD,WAAWxY,KAAKkgB,SAASwB,QAAQnH,IAAIqM;uBAEpC;oBACDpO,WAAWxY,KAAK6mB,aAAa7mB,KAAKkgB,SAAS3G,SAASgB;;gBAGxD,IAAI/B,UAAU;oBACVxY,KAAKiiB,qBAAqB1H,MAAM/B;;;YAIxCiN,6BAA6B,SAASoQ;gBAClC71B,KAAK8e,SAAS7N,KAAKrR,UAAUi2B;gBAE7B71B,KAAKkwB,eAAevwB,GAAGwwB,eAAe,IAAIxwB,GAAGwwB,YACrCnwB,KAAK8e,SAAS7N,MAAMtR,GAAGgQ,KAAK3P,KAAKkmB,mBAAmBlmB,OAAOL,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;gBAGrF,IAAIA,KAAKkwB,gBAAgBlwB,KAAKkwB,aAAaE,gBAAgB;oBACvDpwB,KAAK6jB,aAAa2F,YAAY,MAAMxpB,KAAKkwB,aAAaG;oBAEtDrwB,KAAK8e,SAASwR,aAAatwB,KAAKkwB,aAAaK;oBAC7C,IAAIvwB,KAAKkwB,aAAaM,aAAa;wBAC/BxwB,KAAKslB,YAAYtlB,KAAKkwB,aAAaM;;;;YAK/CwE,SAAS,SAASza,IAAI2D,QAAQC;gBAC1B,IAAIzc,OAAO1B,KAAKigB,QAAQ1F;gBAExB,IAAI2D,QAAQ;oBACRle,KAAK6lB,UAAU3H,QAAQ3D;;gBAG3B,IAAI4D,UAAU;oBACVne,KAAKslB,YAAYnH,UAAU5D;;gBAG/Bva,KAAKuoB;oBACD7mB,MAAM;oBACN0N,UAAUzP,GAAGgQ,KAAK3P,KAAK8e,SAASiI,UAAU+O,UAAU91B,MAAMua,IAAI7Y;oBAC9D2V,WAAW1X,GAAGgQ,KAAK3P,KAAK4zB,0BAA0B5zB,MAAMua,IAAI7Y;oBAC5D4V,WAAW3X,GAAGgQ,KAAK3P,KAAKstB,qBAAqBttB,MAAMua,IAAI7Y;oBACvDgnB,YAAYnO;;;YAIpBkG,aAAa,SAASlG;gBAClB,KAAKva,KAAKkgB,SAASrW,OAAO0Q,KAAK;oBAC3Bva,KAAKggB,YAAY/D,UAAU1B,IAAI5a,GAAGib,OAAOwC;;;YAIjDgJ,oBAAoB;gBAChB,IAAI2P,YAAYC,iBACZle,OAAO9X;gBAEX,OAAOA,KAAK0e,WAAWhZ,QAAQ;oBAC3BqwB,aAAa/1B,KAAK0e,WAAWrM;oBAC7BrS,KAAKygB,YAAYsV;;gBAIrBC,kBAAkBh2B,KAAKyiB;oBAAY7H,QAAQjb,GAAGib,OAAOS;mBAAa3V;gBAClE,IAAIswB,iBAAiB;oBACjBr2B,GAAGmG,IAAI,uBAAuBkwB,kBAAkB;oBAChDpM,WAAW;wBACP9R,KAAKsO;uBACN;;;YAYX2O,yBAAyB,SAASrG,aAAagE;gBAC3C,IAAI5a,OAAO9X,MACPwb,OAAQ;oBACJ,IAAIkT,YAAYlT,gBAAgB7b,GAAG6X,WAAW;wBAC1C,OAAOkX,YAAYlT,KAAK/D;;oBAE5B,OAAOiX,YAAYlT;qBAEvB9Z,OAAOgxB,qBAAqBhxB,MAC5B6Z,OAAOmX,qBAAqBnX,MAC5B/C,WAAWxY,KAAK6mB,aAAa6H,YAAYlT,OACzC4V,iBAAiBpxB,KAAKwuB,mBAAmBhW,WACzCyd,kBAAkB,IAAIt2B,GAAG+L;gBAE7BuqB,gBAAgBnf,KACZ,eACA;oBACIgB,KAAKwV,oBAAoBoB,YAAYnU,IAAI7Y;;gBAGjD,IAAI/B,GAAG+I,cAAc8S,UAAUxb,KAAKoqB,oBAAoBgH,eAAepH,mBAAmBtoB,OAAO;oBAC7F1B,KAAKmmB,WAAW,aAAazkB,MAAM8Z;oBACnC,OAAOya,gBAAgBnqB;;gBAG3B,KAAK9L,KAAK8e,SAASiL,WAAWmM,cAAc3a,SAAS,GAAG;oBACpDvb,KAAKmmB,WAAW,cAAczkB,MAAM8Z;oBACpC,OAAOya,gBAAgBnqB;;gBAG3B,IAAIyP,OAAO,KAAK6V,eAAeM,aAAanW,OAAO6V,eAAeM,WAAW;oBACzE1xB,KAAKmmB,WAAW,aAAazkB,MAAM8Z;oBACnC,OAAOya,gBAAgBnqB;;gBAG3B,IAAIyP,OAAO,KAAKA,OAAO6V,eAAeO,cAAc;oBAChD3xB,KAAKmmB,WAAW,gBAAgBzkB,MAAM8Z;oBACtC,OAAOya,gBAAgBnqB;;gBAG3B,IAAInM,GAAGw2B,mBAAmBx2B,GAAGkT,kBAAkBiD,iBAAiBnW,GAAGyI,OAAOoT,OAAO;oBAC7E,IAAI7b,GAAGw2B,gBAAgB3a,MAAM7b,GAAGgQ,KAAKmI,KAAKhS,KAAKgS,OAAOse,SAAShF,eAAeiF,OAAOvf,KACjFmf,gBAAgBrqB,SAChB,SAAS0qB;wBACLxe,KAAKqO,WAAWmQ,YAAY,cAAc50B,MAAM8Z;wBAChDya,gBAAgBnqB;;uBAIvB;oBACDmqB,gBAAgBrqB;;gBAGpB,OAAOqqB;;YAGXM,gBAAgB;gBACZ,IAAIze,MAAM0e,cAActqB;gBAExB4L,OAAO9X;gBAEPw2B,eAAe,SAAS90B,MAAM0N,UAAUzH;oBACpC,IAAI8uB;oBAEJ;wBACI,OAAOrnB,SAASY,MAAM8H,MAAMnQ;sBAEhC,OAAO+uB;wBACHD,WAAWC,UAAU3wB,WAAW2wB,UAAUpwB;wBAC1CwR,KAAKhS,IAAI,0BAA0BpE,OAAO,kBAAkB+0B,UAAU;;;gBAK9E,KAAKvqB,QAAQlM,KAAK8e,SAASiI,WAAW;qBACjC;wBACG,IAAI4P,cAAcC;wBAClBD,eAAezqB;wBACf0qB,eAAe9e,KAAKgH,SAASiI,UAAU4P;wBACvC7e,KAAKgH,SAASiI,UAAU4P,gBAAgB;4BACpC,OAAOH,aAAaG,cAAcC,cAAc9uB;;;;;;;KCr7DvE;QACG;QAEAnI,GAAGk3B,oBAAoB,SAAShf;YAC5B,IAAIC,OAAO9X;YAGXA,KAAK8e;gBACDuE,OAAO;gBACPO,QAAQ;gBACRla,UAAU;gBACV2d,gBAAgB;gBAChByP,6BAA6B;gBAC7BxG,YAAY;gBACZyG,kBAAkB;gBAElBxP;oBACIE;oBACAtJ,UAAU;oBACV6Y,eAAe;oBACfC,gBAAgB;oBAChBxM,WAAW;oBACXtD,QAAQ;oBACR+P,mBAAmB;oBACnBhZ;oBACAiZ,cAAc;oBACdC,oBAAoB;oBACpBC,mBAAmB;oBACnB7P,UAAU;;gBAGduC;oBACIC;oBACA0H,WAAW;oBACXC,cAAc;oBACd0B,WAAW;oBACXZ,wBAAwB;oBACxBxa,aAAa;oBACboe;wBACIiB,WAAW;wBACXC,UAAU;wBACVC,WAAW;wBACXC,UAAU;;oBAEdvB,YAAY;;gBAGhBnP;oBACI+O,UAAU,SAASvb,IAAI7Y;oBACvBoyB,aAAa,SAASvZ,IAAI7Y;oBAC1B6pB,YAAY,SAAShR,IAAI7Y,MAAMirB,cAAc+K;oBAC7C1E,eAAe,SAASF,YAAYC;oBACpCtH,UAAU,SAASlR,IAAI7Y;oBACvBoqB,UAAU,SAASvR,IAAI7Y;oBACvBuqB,eAAe,SAAS1R,IAAI7Y,MAAMwqB;oBAClCI,sBAAsB,SAAS/R,IAAI2R,WAAWS,cAActY;oBAC5DmY,UAAU,SAASjS,IAAIvI,UAAUka,WAAWO;oBAC5CtB,YAAY,SAAS5Q,IAAI7Y,MAAM0pB,QAAQC;oBACvCkJ,iBAAiB,SAASnJ,QAAQC;oBAClCrE,SAAS,SAASzM,IAAI7Y,MAAMogB,QAAQ6V;oBACpCjL,aAAa,SAASnS,IAAI7Y,MAAMk2B;oBAChCtE,eAAe,SAAS/Y,IAAI7Y;oBAC5BuzB,iBAAiB,SAAS4C;oBAC1BlF,YAAY,SAASkF;oBACrB1D,gBAAgB,SAAS5Z;oBACzBsN,UAAU,SAAStN;oBACnBwN,kBAAkB,SAASxN,IAAIyN,UAAUC;oBACzCO,iBAAiB,SAASpd;oBAC1BwQ,gBAAgB,SAASrB,IAAI4B,WAAWD;oBACxCwZ,0BAA0B,SAAStD,UAAUxmB,SAASoc;;gBAG1DkJ;oBACI4G,WAAW;oBACXC,WAAW;oBACXC,cAAc;oBACdC,YAAY;oBACZC,cAAc;oBACdrD,mBAAmB;oBACnBsD,qBAAqB;oBACrBC,oBAAoB;oBACpBC,qBAAqB;oBACrBC,oBAAoB;oBACpBC,uBAAuB;oBACvBnD,SAAS;oBACTlD,8BAA8B;;gBAGlC5N;oBACIkQ,YAAY;oBACZoB,iBAAiB;oBACjBzC,kBAAkB;oBAClBjI,8BAA8B;;gBAGlCb;oBACIE,aAAa;oBACbD,aAAa;;gBAGjBjV;oBACImL,SAAS;oBACTgY;wBACIhY,SAAS;;oBAEbiY,WAAW;oBACXC;wBACIrM,WAAW;wBACXsM,gBAAgB;wBAChBC,WAAW;wBACXC,eAAe;wBACfC,YAAY;;oBAEhBC,UAAU,SAASxe;wBACf,OAAO;;oBAGX3O;wBACIuS,UAAU;wBAEVyG,SAAS,SAASrK;4BACd,OAAO;;wBAGXye,aAAa;wBAEb7R,QAAQ;wBAERjJ,QAAQ,SAAS3D;4BACb,OAAO;;wBAGX0e;;;gBAIR9iB;oBACIqK,SAAS;oBACT0Y,iBAAiB;oBACjBR;wBACIS,UAAU;;oBAEdC,YAAY,SAASpY;wBACjB;;;gBAIRyQ,gBAAgB,SAAS4H;oBACrB,OAAOA;;gBAGXh2B;oBACIivB,sBAAsB;oBACtB3H,gBAAgB;oBAChB6C,eAAc,MAAM,MAAM,MAAM,MAAM,MAAM;;gBAGhD9M;oBACIF,SAAS;oBACT2G,QAAQ;oBACRhJ,UAAU;oBACVsJ;oBACAvJ;;gBAGJ0J;oBACI8I,UAAU;oBACV4I,iBAAiB;oBACjB3I,UAAU;;gBAGd5R;oBACIC,aAAa;;gBAGjBqJ;oBACID,eAAe;oBACfpJ,aAAa;;gBAGjB+P;oBACI1gB,KAAK;oBAGLuV,QAAQ;;gBASZiK;gBAIA9J;oBACI5F,UAAU;oBACVD;oBACAuJ;oBACAzD,gBAAgB;;gBAIpB/S;oBAEIrR,SAAS;oBAGT0wB,YAAY;oBAGZiJ,iBAAiB;;gBAIrBnjB;oBACIojB,eAAe;oBAGfC,cAAc;oBAGdC,QAAQ;oBAIRC,aAAa;oBAEbC,gBAAgB;oBAEhBC,aAAa;oBAEbC,aAAa;oBAGbC;;gBAGJ7P;oBACIC,gBAAgB;oBAChB6H,mBAAmB;oBACnBxH,kBAAkB;;;YAK1B7qB,GAAG6B,OAAOxB,KAAK8e,UAAUjH,GAAG;YAE5B7X,KAAK2jB;YACL3jB,KAAK4tB;YACL5tB,KAAKiiB;YAELjiB,KAAKu2B;YACLv2B,KAAK4qB,kBAAmB,IAAIjrB,GAAGsS;YAE/BjS,KAAK0e;YACL1e,KAAKwjB;YACLxjB,KAAKyjB;YACLzjB,KAAK0jB;YACL1jB,KAAKwhB;YAELxhB,KAAKijB,uBAAuB;YAC5BjjB,KAAK6iB,eAAe;YACpB7iB,KAAKggB,cAAchgB,KAAKypB;YAExBzpB,KAAKiwB;YAELjwB,KAAK6kB,sBAAsB7kB,KAAK2oB,aAAa3oB,KAAK8e,SAASyI,QAAQE;YACnEznB,KAAKilB,gCAAgCjlB,KAAK2oB,aAAa3oB,KAAK8e,SAAS4B,WAAW+G;YAEhFznB,KAAKqlB,yBAAyBrlB,KAAK2oB,aAAa3oB,KAAK8e,SAAS4B,WAAWxC;YAEzEle,KAAKmiB,iBAAiBniB,KAAK2oB,aAAa3oB,KAAK8e,SAASyI,QAAQpJ;YAC9Dne,KAAKmlB,2BAA2BnlB,KAAK2oB,aAAa3oB,KAAK8e,SAAS4B,WAAWvC;YAE3Ene,KAAKkgB,WAAWlgB,KAAK6qB;YAErB7qB,KAAKo0B,iBAAiBz0B,GAAGunB,2BAA2BlnB,KAAKinB;YAEzD,IAAIjnB,KAAK8e,SAAS8E,QAAQ;gBACtB5jB,KAAKkuB,mBAAmBluB,KAAK6pB;oBACzBjqB,SAASI,KAAK8e,SAAS8E;oBACvBrL,OAAOvY,KAAK8e,SAASzb,KAAKsnB;mBAC3BnR;;YAGPxZ,KAAK2tB;YAEL3tB,KAAK8uB;YAEL,IAAI9uB,KAAK8e,SAASuJ,MAAMD,eAAe;gBACnC,IAAIzoB,GAAGwoB,cAAc;oBACjBnoB,KAAK8jB,gBAAgB9jB,KAAKkoB;uBAEzB;oBACDloB,KAAK8F,IAAI,kCAAkC;;;YAInD9F,KAAK8e,SAASiY,oBAAoB/2B,KAAKk1B;YAEvCl1B,KAAKuhB,kBAAkB5hB,GAAGq6B,kBAAkB,IAAIr6B,GAAGq6B,eAAer6B,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;YACpFA,KAAKikB;YAELjkB,KAAKkkB;YACLlkB,KAAKmkB;YAELnkB,KAAKi6B,UAAWt6B,GAAG+kB,UAAU,IAAI/kB,GAAG+kB,OAAO1kB,KAAK8e,SAAS1I,SAASzW,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;YACpF,IAAIA,KAAKi6B,QAAQzZ,SAAS;gBACtBxgB,KAAKwvB,wBAAwB7vB,GAAGgQ,KAAK3P,KAAKi6B,QAAQC,eAAel6B,KAAKi6B;;YAG1E,IAAIt6B,GAAGw6B,iBAAiBx6B,GAAGkT,kBAAkBqD,aAAa;gBACtDlW,KAAKokB,iBAAiB,IAAIzkB,GAAGw6B,cACzBx6B,GAAGgQ,KAAK3P,KAAKs0B,kBAAkBt0B,OAE/B,SAASua;oBACL,IAAI6f,QAAQtiB,KAAKkI,YAAYnE;wBAAUtB,IAAIA;;oBAC3C,OAAQ6f,SAASA,MAAM7e,QAAS;;;YAK5Cvb,KAAKgjB,oBAAoBhjB,KAAK8e,SAASiL,WAAWsJ;YAElDrzB,KAAKqkB,yBAAyBrkB,KAAK2oB;;QAIvChpB,GAAGk3B,kBAAkBxwB,YAAY1G,GAAGoe;QACpCpe,GAAG6B,OAAO7B,GAAGk3B,kBAAkBxwB,WAAW1G,GAAG0mB;;IC3UjD1mB,GAAG06B,gBAAgB,SAASxiB;QACxB;QAEA,IAAI/R,KAAKw0B,6BACLC,YACAC,kBACAxiB;YACIyiB,cAAc;YACdC,gBAAe,SAAS,QAAQ;YAChCvT,QAAQ;YACRwT,aAAa;YACbtT,gBAAgB;YAChBI;YACAE;YACAD;YACAkT;YACAC,oCAAoC;YACpCC;gBACIC,UAAS,KAAK,KAAK;gBACnBC,SAAQ,KAAK,KAAK,KAAK,KAAK;gBAC5BC,QAAO,KAAK,KAAK,KAAK,KAAK;gBAC3BC,OAAM,KAAK,KAAK,KAAK,KAAK;gBAC1BC,OAAM;;YAEVvT;gBACI8I,UAAU;gBACV4I,iBAAiB;;YAErBxzB,KAAK,SAAS4B,KAAK1B;YACnBo1B,QAAQ,SAAS7gB;YACjBgR,YAAY,SAAShR,IAAIyN,UAAUC;YACnCkD,YAAY;;QAGpBxrB,GAAG6B,OAAOwW,SAASH;QACnB/R,MAAMkS,QAAQlS;QAEd,IAAInG,GAAG2F,QAAQ0S,QAAQ0iB,cAAc1iB,QAAQmP,UAAU,GAAG;YACtD,MAAM,IAAIhmB,MAAM,MAAM6W,QAAQmP,SAAS;;QAM3C,SAASkU;YACL,OAAO17B,GAAG2F,UAAS,OAAO,QAAQ,UAAS0S,QAAQmP,WAAW;;QAMlE,SAASmU,yBAAyB1W;YAC9B,IAAI2W,oBAAoB;YAExB57B,GAAG+C,KAAK64B,mBAAmB,SAAS54B,KAAK64B;gBACrC,IAAI77B,GAAG2F,UAAS,UAAU,mBAAmB,oBAAoB,kBAAiBk2B,UAAU,GAAG;oBAC3FD,oBAAoB;oBACpB,OAAO;;;YAIf,OAAOA;;QAGX,SAASE,MAAMpnB;YAEX,OAAO2D,QAAQ4P,KAAK8I,YAAYrc,IAAIC,oBAAoBxQ;;QAI5D,SAAS43B;YACL,IAAI1T;YAEJ,IAAIrjB,OAAOmF,kBAAkBnF,OAAOoF,eAAe;gBAC/Cie,WAAWroB,GAAGiK;gBAEd,IAAIoe,SAAS1T,oBAAoBxQ,WAAW;oBACxCkkB,WAAW,IAAIxT;oBAEfwT,SAASrc,SAAS;oBAClBqc,SAASnc,UAAU;oBACnBmc,SAAS2T,YAAY;oBACrB3T,SAAS4T,aAAa;;;YAI9B,OAAO5T;;QAIX,SAAS6T,YAAYthB,IAAIuhB;YACrB,IAAI9T,WAAWwS,YAAYjgB,OAAOigB,YAAYjgB,IAAIlG;YAElD,KAAK2T,UAAU;gBACX,IAAI8T,aAAa;oBACb9T,WAAW8T;uBAEV;oBACD,IAAI9jB,QAAQ4P,KAAK8I,UAAU;wBACvB1I,WAAW0T;2BAEV;wBACD1T,WAAWroB,GAAGiK;;;gBAItB4wB,YAAYjgB,IAAIlG,MAAM2T;;YAG1B,OAAOA;;QAIX,SAAS+T,QAAQxhB;YACb,IAAI9J,IAAI9Q,GAAG2F,QAAQi1B,OAAOhgB,KACtBkT,MAAMzV,QAAQqP,gBACd2U;mBAEGxB,YAAYjgB;YACnBggB,MAAMle,OAAO5L,GAAG;YAEhB,IAAI8pB,MAAM70B,UAAU+nB,OAAOhd,IAAIgd,KAAK;gBAChCuO,SAASzB,MAAM9M,MAAM;gBACrBwO,YAAYD;;;QAIpB,SAASzQ,WAAWhR,IAAI2hB;YACpB,IAAI7nB,MAAMwnB,YAAYthB,KAClB4M,SAASnP,QAAQmP,QACjBc,UAAUiU,aAAa;YAE3BH,QAAQxhB;YAER,IAAI0N,SAAS;gBACTniB,IAAIqhB,SAAS,kBAAkB5M,KAAK,eAAe;mBAElD,KAAKkhB,MAAMpnB,SAAS8nB,qBAAqB9nB,IAAIuG,SAAS;gBACvDqN,UAAU;gBACVniB,IAAIqhB,SAAS,kBAAkB5M,KAAK,iCAAiClG,IAAIuG,QAAQ;;YAGrF5C,QAAQuT,WAAWhR,IAAIlG,KAAK4T;;QAGhC,SAASmU,UAAU7hB;YACf,IAAI8hB,iBAAiB7B,YAAYjgB,IAAI+hB,kBACjC1B,iBAAiB5iB,QAAQ4iB,gBACzB1c;YAEJ,IAAIlG,QAAQ0P,YAAYtF,KAAK;gBACzBlE,SAASlG,QAAQ0P,YAAYtF,IAAI7H;;YAGrC,IAAI8hB,gBAAgB;gBAChB18B,GAAG+C,KAAK25B,gBAAgB,SAAS36B,MAAMkB;oBACnCsb,SAASA;oBACTA,OAAOxc,QAAQkB;;;YAIvB,IAAIg4B,gBAAgB;gBAChBj7B,GAAG+C,KAAKk4B,gBAAgB,SAASl5B,MAAMkB;oBACnCsb,SAASA;oBACTA,OAAOxc,QAAQkB;;;YAIvB,OAAOsb;;QAGX,SAAS+d,YAAY1hB,IAAIgiB;YACrB,IAAIloB,MAAMwnB,YAAYthB,IAAIgiB,SACtBpV,SAASnP,QAAQmP,QACjBjJ,SAASke,UAAU7hB,KACnBiiB,UAAUhC,YAAYjgB,IAAIiiB,SAC1BC;YAEJzkB,QAAQojB,OAAO7gB;YAEfkiB,MAAMC,UAAUniB,IAAI2D,QAAQsc,YAAYjgB,IAAIoiB;YAG5C,IAAIlB,MAAMpnB,MAAM;gBACZA,IAAI1I,SAASixB,kBAAkBriB;gBAC/BlG,IAAIxI,UAAUgxB,mBAAmBtiB;mBAEhC;gBACDlG,IAAIyoB,qBAAqBC,8BAA8BxiB;;YAG3DyiB,0BAA0BziB;YAG1BlG,IAAI4oB,KAAK9V,QAAQsV,KAAK;YAItB,IAAIzkB,QAAQ4P,KAAK8I,YAAY1Y,QAAQ4P,KAAK0R,oBAAoBmC,MAAMpnB,MAAM;gBACtEA,IAAIC,kBAAkB;;YAG1B4oB,WAAW3iB;YAEXzU,IAAI,aAAaqhB,SAAS,kBAAkB5M;YAE5C,IAAIiiB,SAAS;gBACTnoB,IAAI8oB,KAAKX;mBAER,IAAIlC,gCAAgCpc,QAAQ;gBAC7C7J,IAAI8oB;mBAEH,IAAIjf,UAAUlG,QAAQ2iB,eAAe3iB,QAAQ2iB,YAAY1xB,cAAc3D,QAAQ,wCAAwC,GAAG;gBAC3H+O,IAAI8oB,KAAKx9B,GAAGsQ,QAAQiO,QAAQ;mBAE3B,IAAIA,UAAUlG,QAAQ2iB,eAAe3iB,QAAQ2iB,YAAY1xB,cAAc3D,QAAQ,uBAAuB,GAAG;gBAC1G+O,IAAI8oB,KAAK7rB,KAAK8rB,UAAUlf;mBAEvB;gBACD7J,IAAI8oB,KAAKjf;;YAGb,OAAO7J;;QAGX,SAASqoB,UAAUniB,IAAI2D,QAAQye;YAC3B,IAAIxe,WAAWnG,QAAQ2P,cAAcvF,IAAI7H,KACrC8iB,YAAY7C,YAAYjgB,IAAI8iB;YAGhC,IAAIA,aAAav5B,WAAW;gBACxBqa,YAAY,MAAMkf;;YAGtB,IAAI/C,+BAA+Bpc,QAAQ;gBACvCC,WAAWxe,GAAGsQ,QAAQiO,QAAQC;;YAGlC,IAAIwe,uBAAuB;gBACvBxe,WAAWxe,GAAGsQ,QAAQ0sB,uBAAuBxe;;YAGjD,OAAOA;;QAKX,SAAS4e,8BAA8BxiB;YACnC,OAAO;gBACH,IAAIshB,YAAYthB,IAAI+iB,eAAe,GAAG;oBAClC/R,WAAWhR;;;;QAKvB,SAASyiB,0BAA0BziB;YAC/B,IAAI4Q,aAAanT,QAAQmT;YAEzB,IAAIA,YAAY;gBACZ0Q,YAAYthB,IAAI1Q,OAAO+xB,aAAa,SAAS/sB;oBACzC,IAAIA,EAAE0uB,kBAAkB;wBACpBpS,WAAW5Q,IAAI1L,EAAEuc,QAAQvc,EAAEwc;;;;;QAQ3C,SAASuR,kBAAkBriB;YACvB,OAAO;gBACHgR,WAAWhR;;;QAMnB,SAASsiB,mBAAmBtiB;YACxB,OAAO;gBACHgR,WAAWhR,IAAI;;;QAIvB,SAAS2iB,WAAW3iB;YAChB,IAAIlG,MAAMwnB,YAAYthB,KAClBkN,gBAAgBzP,QAAQyP,eACxB+V,kBAAkBhD,YAAYjgB,IAAIkjB,yBAClCtW,SAASnP,QAAQmP,QACjBuW;YAGJ,KAAKjC,MAAMpnB,MAAM;gBACb2D,QAAQyiB,gBAAgBpmB,IAAIspB,iBAAiB,UAAU3lB,QAAQyiB;gBAG/D,IAAIziB,QAAQ6iB,oCAAoC;oBAK5C,KAAK7iB,QAAQ4P,KAAK8I,cAAc2K,oBAAoBC,yBAAyB7T,iBAAiB;wBAC1FpT,IAAIspB,iBAAiB,oBAAoB;wBACzCtpB,IAAIspB,iBAAiB,iBAAiB;;;gBAI9C,IAAI3lB,QAAQ2iB,gBAAgBxT,WAAW,UAAUA,WAAW,QAAQ;oBAChE9S,IAAIspB,iBAAiB,gBAAgB3lB,QAAQ2iB;;gBAGjDh7B,GAAG6B,OAAOk8B,YAAY/9B,GAAG6G,WAAWihB,iBAAiBA,cAAclN,MAAMkN;gBACzE9nB,GAAG6B,OAAOk8B,YAAYF;gBAEtB79B,GAAG+C,KAAKg7B,YAAY,SAASh8B,MAAMkB;oBAC/ByR,IAAIspB,iBAAiBj8B,MAAMkB;;;;QAKvC,SAASu5B,qBAAqByB;YAC1B,OAAOj+B,GAAG2F,QAAQ0S,QAAQ8iB,wBAAwB9iB,QAAQmP,SAASyW,iBAAiB;;QAGxF,SAASC,cAActjB,IAAIgiB,QAAQc,WAAWf,kBAAkBK,uBAAuBc,mBAAmBjB;YACtGhC,YAAYjgB;gBACR8iB,WAAWA;gBACXf,kBAAkBA;gBAClBK,uBAAuBA;gBACvBc,mBAAmBA;gBACnBjB,SAASA;;YAGb,IAAI3vB,MAAM0tB,MAAM13B,KAAK0X;YAGrB,IAAI1N,OAAOmL,QAAQqP,gBAAgB;gBAC/B,OAAO4U,YAAY1hB,IAAIgiB;;;QAI/BjC,8BAA8BtiB,QAAQmP,WAAW,SAASnP,QAAQmP,WAAW;QAE7ExnB,GAAG6B,OAAOxB;YAEN89B,eAAe,SAASvjB;gBACpB,IAAIwjB,MAAM7f,QAAQ0G,SAAS4X,SAASwB,aAAarB;gBAEjD;oBAEIsB,UAAU,SAASC;wBACfH,OAAOG;wBACP,OAAOl+B;;oBAOXm+B,YAAY,SAAS7B;wBACjBpe,SAASoe;wBACT,OAAOt8B;;oBAGXo+B,iBAAiB,SAASC;wBACtB1B,wBAAwB0B;wBACxB,OAAOr+B;;oBAIXs+B,aAAa,SAASb;wBAClB7Y,UAAU6Y;wBACV,OAAOz9B;;oBAIXu+B,aAAa,SAASC;wBAClBhC,UAAUgC;wBACV,OAAOx+B;;oBAIXy+B,iBAAiB;wBACbT,cAAc;wBACd,OAAOh+B;;oBAIXm9B,MAAM,SAASZ;wBACX,IAAIyB,eAAer+B,GAAG2F,UAAS,OAAO,YAAW0S,QAAQmP,WAAW,GAAG;4BACnEjJ,OAAOwgB,cAAc,IAAIC,OAAOC;;wBAGpC,OAAOf,cAActjB,IAAIgiB,QAAQwB,MAAM7f,QAAQye,uBAAuB/X,SAAS4X;;;;YAK3FqC,UAAU,SAAStkB;gBACfwhB,QAAQxhB;;;;IC1YpB5a,GAAGm/B,gBAAgB,SAAS1jB;QACxB;QAEA,IAAI2jB,QAAQ3jB,KAAK2jB,OACbC,gBACAvT,WAAWsT,MAAMtT,UACjBxL,UAAU8e,MAAM9e;QAEpBtgB,GAAG6B,OAAOxB;YACNuQ,KAAK,SAASgK,IAAI0kB;gBACdD,UAAUzkB,MAAM0kB;gBAChBD,UAAUzkB,IAAIpK;;YAGlB2P,QAAQ,SAASvF;gBACb,IAAIzC,OAAO9X,MACP0rB,2BAA2B,IAAI/rB,GAAG+L,WAClCwzB,iBAAiBzT,SAASlR,IAAI0F,QAAQ1F,KAAKmR;gBAE/CwT,eAAepoB,KAAK;oBAChB,IAAIgB,KAAKgJ,QAAQvG,KAAK;wBAClBykB,UAAUzkB,IAAIskB,WAAW;wBACzB/mB,KAAKyL,QAAQhJ;;oBAEjBmR,yBAAyB9f;;;YAIjC2X,SAAS,SAAShJ;uBACPykB,UAAUzkB;;YAGrB4kB,qBAAqB,SAAS5kB;gBAC1B,OAAOykB,UAAUzkB,IAAI/K;;YAGzBsR,SAAS,SAASvG;gBACd,OAAOykB,UAAUzkB,QAAQzW;;YAG7B+V,OAAO;gBACHmlB;;YAGJI,eAAe,SAAS7kB;gBACpB,OAAOykB,UAAUzkB;;YAGrB8kB,sBAAsB,SAAS9kB,IAAI+kB;gBAC/BN,UAAUzkB,IAAI/K,MAAM8vB;;YAGxBC,cAAc,SAAShlB;gBACnB,SAASykB,UAAUzkB,IAAIskB;;;;ICpDnCl/B,GAAG0tB,0BAA0B,SAASxV,GAAGkT;QACrC;QAEA,IAAIyU,aAAax/B,MACby/B,mBAAmB,OACnBC,6BAA6B,OAC7BrqB,UAAUsqB,sBAAsB75B,KAAKypB,SAEzCvX;YACI0P;YACAL,gBAAgB;YAChBhS;gBACImL,SAAS;gBACT9W;oBACI8W,SAAS;;;YAGjB1a,KAAK,SAAS4B,KAAK1B;YACnBmlB,YAAY,SAAS5Q,IAAIvI,UAAUoZ,QAAQC;YAC3CE,YAAY,SAAShR,IAAIvI,UAAUogB,UAAU/d;YAC7CoX,UAAU,SAASlR,IAAIvI;YACvB4Z,cAAc,SAASrR;YACvBuR,UAAU,SAASvR,IAAIvI;YACvBia,eAAe,SAAS1R,IAAIvI,UAAUka;YACtCI,sBAAsB,SAAS/R,IAAI2R,WAAWkG,UAAU/d;YACxDqY,aAAa,SAASnS,IAAIvI,UAAUogB,UAAU/d;YAC9CmY,UAAU,SAASjS,IAAIvI,UAAUka,WAAWO;YAC5CI,eAAe,SAAStS,IAAIgC;YAC5B0D,SAAS,SAAS1F;YAClBuS,SAAS,SAASvS,IAAIqC;YACtBqQ,UAAU,SAAS1S;YACnByC,oBAAoB,SAASzC;YAC7B0C,eAAe,SAAS1C;YACxB2S,cAAc,SAAS3S;WAG3BqlB;YAEIroB,MAAM,SAASgD,IAAIslB,UAAUzN,UAAU/d;gBACnC,IAAI6X,YAAYqD,QAAQuQ,cAAcvlB,IAAIslB;gBAE1CtQ,QAAQ6P,cAAc7kB,IAAIwlB,mBAAmB;uBAEtCxQ,QAAQ6P,cAAc7kB,IAAIpK,KAAK6vB,cAAcH;gBACpDtQ,QAAQ6P,cAAc7kB,IAAI6Q,UAAUc,UAAU3Q;gBAE9CvD,QAAQsU,qBAAqB/R,IAAIgV,QAAQ0Q,yBAAyB/T,YAAYkG,UAAU/d;;YAK5F6rB,UAAU,SAAS3lB;gBACf,IAAIgB,OAAOvD,QAAQ2K,QAAQpI,KACvB7Y,OAAOsW,QAAQiI,QAAQ1F;gBAE3BzU,IAAI,uCAAuCyU,KAAK;gBAChDgV,QAAQ4Q,eAAe5lB,IAAIzD,KACvB,SAASsb,UAAU/d;oBACfvO,IAAI,6BAA6ByU;oBAEjC,IAAI6lB,oBAAoBv2B,OAAOw2B,kBAAkBjO,UAAU;oBAE3Dpa,QAAQmT,WAAW5Q,IAAI7Y,MAAM6Z,MAAMA;oBACnCgU,QAAQ+Q,+BAA+B/lB;oBACvC1Q,OAAO02B,QAAQhmB,IAAI6lB,mBAAmB/rB;mBAE1C,SAAS+d,UAAU/d;oBACf,IAAImsB,qBAAqB32B,OAAOw2B,kBAAkBjO,UAAU;oBAE5DtsB,IAAI,2CAA2CyU,KAAK,QAAQimB,mBAAmBx2B,OAAO;oBAEtF,IACIw2B,mBAAmB3mB,SAClBxF,OAAO2D,QAAQ3C,SAASzJ,QAAQqtB,cAAc3zB,QAAQ+O,IAAIuG,WAAW,GACxE;wBACEglB,QAAQ/lB,MAAMU;;oBAGlB,KAAKvC,QAAQ0U,YAAYnS,IAAI7Y,MAAM8+B,oBAAoBnsB,MAAM;wBACzDxK,OAAO02B,QAAQhmB,IAAIimB,oBAAoBnsB;;;;YAMvDosB,eAAe,SAASZ,UAAUtlB,IAAI6X,UAAU/d;gBAC5C,IAAI3S,OAAOsW,QAAQiI,QAAQ1F;gBAE3BzU,IAAI,uCAAuCyU,KAAK,aAAaslB;gBAE7DtQ,QAAQmR,iBAAiBnmB,IAAIslB;gBAE7B,IAAIc,mBAAmB92B,OAAOw2B,kBAAkBjO,UAAU,QACtDwO;gBAEJ,IAAID,iBAAiB9mB,OAAO;oBACxB+lB,QAAQ/lB,MAAMU;uBAEb;oBACD,IAAIsmB,wBAAwBtR,QAAQ6P,cAAc7kB,IAAIlF,SAASyrB;oBAE/DF,gBAAgBC,wBAAwBlhC,GAAG2F,QAAQu7B,uBAAuBhB,aAAa;oBACvF,IAAIe,iBAAiB,GAAG;wBACpBrR,QAAQ6P,cAAc7kB,IAAIlF,SAASyrB,WAAWzkB,OAAOukB,eAAe;wBACpErR,QAAQ6P,cAAc7kB,IAAIlF,SAAS0rB,UAAUC,QAAQnB;;;gBAM7D,KAAKtQ,QAAQ6P,cAAc7kB,IAAIpK,KAAK8wB,eAAe;oBAG/C,IAAIvB,4BAA4B;wBAC5BnQ,QAAQ6P,cAAc7kB,IAAIpK,KAAK8wB,gBAAgB;wBAE/Cn7B,IAAInG,GAAG8H,OAAO,oFAAoF6J,KAAK8rB,UAAUh3B,OAAO86B,KAAK3R,QAAQ4R,SAAS5mB,OAAOjJ,KAAK8rB,UAAU7N,QAAQ6P,cAAc7kB,IAAIlF,SAASyrB;wBACvMnhC,GAAG+C,KAAK6sB,QAAQ4R,SAAS5mB,KAAK,SAAS6mB,MAAMC;4BACzCv7B,IAAInG,GAAG8H,OAAO,uDAAuD8S,IAAI6mB,MAAMC,MAAM/D;4BACrF+D,MAAMC;4BAGND,MAAME,aAAa;;wBAIvBhS,QAAQiS,0BAA0BjnB;wBAIlCknB,kBAAkBC,KAAKnnB,IAAI;;oBAG/B,KAAKvC,QAAQ0U,YAAYnS,IAAI7Y,MAAMi/B,kBAAkBtsB,MAAM;wBAIvDxK,OAAO02B,QAAQhmB,IAAIomB,kBAAkBtsB;;;;YAKjDstB,cAAc,SAASpnB;gBACnB,SAASgV,QAAQ6P,cAAc7kB,IAAIlF,SAAS0rB,UAAUr7B;;YAG1Dk8B,UAAU,SAASrnB;gBACf,IAAIsnB,UAAUtS,QAAQ6P,cAAc7kB,IAAIlF,SAAS0rB,UAAU1uB;gBAE3D,IAAIwvB,WAAWtS,QAAQuS,gBAAgBvnB,KAAK;oBACxCsnB,UAAU;;gBAGd,OAAOA;;YAGXhoB,OAAO,SAASU;gBACZzU,IAAI,gGAAgGyU,IAAI;gBAExGgV,QAAQ+Q,+BAA+B/lB;gBACvCgV,QAAQwS,mBAAmBxnB;gBAC3BgV,QAAQ6P,cAAc7kB,IAAI6Q,SAAS;gBACnCmE,QAAQ6P,cAAc7kB,IAAIwlB,mBAAmB;;YAGjDiC,UAAU,SAASznB;gBACf,IAAIgB,OAAOvD,QAAQ2K,QAAQpI,KACvB7Y,OAAOsW,QAAQiI,QAAQ1F,KACvBslB,WAAWD,QAAQgC,SAASrnB,KAC5B2R,YAAYqD,QAAQuQ,cAAcvlB,IAAIslB,WACtCb,YAAYzP,QAAQ6P,cAAc7kB,KAClC4e,WAAW6F,UAAUe,kBACrBkC,mBAAmBjD,UAAU3pB,SAASyrB;gBAE1C,IAAI9B,UAAU5T,UAAU,MAAM;oBAC1B4T,UAAU5T,SAAS;;gBAIvB,IAAI+N,YAAYnhB,QAAQwU,SAASjS,IAAI7Y,MAAMwqB,WAAW8S,UAAUvS,sBAAsB,OAAO;oBACzFmT,QAAQ/lB,MAAMU;oBACdslB,WAAWD,QAAQgC,SAASrnB;oBAC5B2R,YAAYqD,QAAQuQ,cAAcvlB,IAAIslB;oBACtC1G,WAAW;;gBAIf,IAAI0G,YAAY,QAAQoC,iBAAiBv8B,WAAW,GAAG;oBACnDk6B,QAAQM,SAAS3lB;uBAIhB;oBACD0nB,iBAAiBp/B,KAAKg9B;oBACtBtQ,QAAQ6P,cAAc7kB,IAAIlF,SAASyrB,aAAamB;oBAEhD,IAAIvC,4BAA4B;wBAC5B+B,kBAAkBxE,KAAK1iB,IAAIslB;;oBAG/B,IAAIH,8BAA8B+B,kBAAkBS,eAAe3S,QAAQ6P,cAAc7kB,IAAIlF,SAAS0rB,UAAUr7B,QAAQ;wBACpHk6B,QAAQoC,SAASznB;;oBAGrB,IAAI2R,UAAU9gB,KAAKmQ,SAAS,GAAG;wBAC3BzV,IAAInG,GAAG8H,OAAO,gEAAgEo4B,UAAUtlB,KAAK;wBAC7FqlB,QAAQa,cAAcZ,UAAUtlB,IAAI,+BAA+B;;oBAGvE,IAAI4nB,uBAAuBnqB,QAAQiU,cAAc1R,IAAI7Y,MAAM6tB,QAAQ0Q,yBAAyB/T;oBAE5FiW,qBAAqBrrB,KACjB,SAASsrB;wBACL,KAAKpqB,QAAQkV,aAAa3S,KAAK;4BAC3BzU,IAAInG,GAAG8H,OAAO,8EAA8E8S,IAAIslB;+BAE/F;4BACD/5B,IAAInG,GAAG8H,OAAO,qEAAqE8S,IAAIslB,UAAU3T,UAAUvhB,QAAQ,GAAGuhB,UAAUthB,KAAK2Q;4BAErI,IAAI8mB;gCACAxC,UAAUA;gCACVtlB,IAAIA;gCACJ+nB,WAAWF;gCACXjJ,UAAUA;;4BAGd5J,QAAQgT,YAAYF,iBAAiBvrB,KAEjC,SAASlL,QAAQwmB,UAAU/d;gCACvBvO,IAAI,0CAA0CyU,KAAK,aAAaslB;gCAEhEtQ,QAAQmR,iBAAiBnmB,IAAIslB;gCAE7B,IAAIoC,mBAAmB1S,QAAQ6P,cAAc7kB,IAAIlF,SAASyrB,kBACtDH,mBAAmB92B,OAAOw2B,kBAAkBjO,UAAU,OACtDoQ,qBAAqB7iC,GAAG2F,QAAQ28B,kBAAkBpC;gCAEtD/5B,IAAInG,GAAG8H,OAAO,+CAA+Co4B,UAAUtlB;gCAEvEqlB,QAAQroB,KAAKgD,IAAIslB,UAAUc,kBAAkBtsB;gCAE7C,IAAImuB,sBAAsB,GAAG;oCACzBP,iBAAiB5lB,OAAOmmB,oBAAoB;;gCAGhDjT,QAAQkT,0BAA0BloB;gCAElC,KAAKqlB,QAAQ+B,aAAapnB,OAAO0nB,iBAAiBv8B,WAAW,GAAG;oCAC5Dk6B,QAAQM,SAAS3lB;uCAEhB,IAAIqlB,QAAQ+B,aAAapnB,KAAK;oCAC/BqlB,QAAQoC,SAASznB;uCAEhB;oCACDzU,IAAInG,GAAG8H,OAAO,qGAAqG8S,IAAIjJ,KAAK8rB,UAAU6E;;+BAK9I,SAASn2B,QAAQsmB,UAAU/d;gCACvBurB,QAAQa,cAAcZ,UAAUtlB,IAAI6X,UAAU/d;+BAGjDkD,KAAK;gCACFgY,QAAQmT,SAASnoB,IAAIslB;;;uBAKrC,SAAS71B;wBACL41B,QAAQa,cAAcZ,UAAUtlB,IAAIvQ,OAAO;;;;WAO/Dy3B;YACIkB;YACAC;YACAC;YAEAX,WAAW;gBACP,IAAIzU,MAAMzV,QAAQqP,gBACdyb,wBAAwB,GACxBC,kBAAkB;gBAEtBpjC,GAAG+C,KAAK++B,kBAAkBmB,aAAa,SAAS5hB,QAAQgiB;oBACpDF;oBACAC,mBAAmBC,iBAAiBt9B;;gBAGxC,OAAO+nB,OAAOgU,kBAAkBkB,MAAMj9B,SAASo9B,wBAAwBC;;YAM3ErB,MAAM,SAASnnB,IAAI0oB;gBACf,IAAIC,aAAaD,eACbE,eAAexjC,GAAG2F,QAAQm8B,kBAAkBoB,UAAUtoB,KACtD6oB,mBAAmBzjC,GAAG2F,QAAQm8B,kBAAkBkB,OAAOpoB,KACvDyhB;uBAEGyF,kBAAkBmB,YAAYroB;gBAErC,IAAI1Q,OAAOw5B,eAAe9oB,eAAe5a,GAAG6X,WAAW;oBACnD1R,IAAI,yCAAyCyU,KAAK;2BAC3CgV,QAAQ6P,cAAc7kB,IAAIiB;;gBAIrC,IAAI2nB,gBAAgB,GAAG;oBACnB1B,kBAAkBoB,SAASxmB,OAAO8mB,cAAc;uBAG/C,IAAID,aAAaE,oBAAoB,GAAG;oBACzC3B,kBAAkBkB,MAAMtmB,OAAO+mB,kBAAkB;oBAEjDpH,SAASyF,kBAAkBoB,SAASxwB;oBACpC,IAAI2pB,UAAU,GAAG;wBACbyF,kBAAkBkB,MAAM9/B,KAAKm5B;wBAC7BnyB,OAAOc,MAAMqxB;;;;YAKzBsH,uBAAuB;gBACnB,IAAIC;gBAIJ5jC,GAAG+C,KAAK++B,kBAAkBmB,aAAa,SAAS5hB,QAAQwiB;oBACpD,IAAIA,UAAUA,OAAO99B,QAAQ;wBACzB69B,mBAAmB1gC,KAAK4gC,SAASziB;;;gBAMzCrhB,GAAG+C,KAAK++B,kBAAkBkB,OAAO,SAAShgC,KAAKqe;oBAC3C,KAAKygB,kBAAkBmB,YAAY5hB,SAAS;wBACxCuiB,mBAAmB1gC,KAAK4gC,SAASziB;;;gBAKzCuiB,qBAAqBA,mBAAmBxzB,OAAO0xB,kBAAkBoB;gBAEjE,OAAOU;;YAGXG,mBAAmB,SAASnpB;gBACxB,OAAO5a,GAAG2F,QAAQm8B,kBAAkBkB,OAAOpoB,OAAO;;YAGtD0iB,MAAM,SAAS1iB,IAAIslB;gBACf,IAAIA,YAAY,MAAM;oBAClB4B,kBAAkBoB,SAAShgC,KAAK0X;;gBAGpC,IAAIknB,kBAAkBS,aAAa;oBAC/B,IAAIrC,YAAY,MAAM;wBAClB4B,kBAAkBoB,SAASc;wBAC3BlC,kBAAkBkB,MAAM9/B,KAAK0X;2BAE5B;yBACA;4BACG,IAAIqpB,kBAAkBnC,kBAAkBmB,YAAYroB;4BACpDqpB,gBAAgB/gC,KAAKg9B;4BACrB4B,kBAAkBmB,YAAYroB,MAAMqpB;;;oBAI5C,OAAO;;gBAGX,OAAO;;YAGX/pB,OAAO;gBACH4nB,kBAAkBoB;gBAClBpB,kBAAkBkB;;WAI1BkB;YACI1G,MAAM,SAAS5iB,IAAI7Y;gBACf,IAAIs9B,YAAYzP,QAAQ6P,cAAc7kB;gBAEtC,KAAKykB,WAAW;oBACZl5B,IAAI,2EAA2EyU,IAAI;oBACnF;;gBAGJykB,UAAU5T,SAAS;gBAEnBtlB,IAAI,uCAAuCyU;gBAC3CgV,QAAQuU,WAAWvpB,IAAIzD,KACnB,SAASsb,UAAUmK;oBACfz2B,IAAI,yCAAyCyU;oBAE7C,IAAIomB,mBAAmB92B,OAAOw2B,kBAAkBjO,UAAU,OACtD7W,OAAOvD,QAAQ2K,QAAQpI;oBAE3BvC,QAAQmT,WAAW5Q,IAAI7Y,MAAM6Z,MAAMA;oBACnC1R,OAAOk6B,aAAaxpB,IAAIomB;oBACxB92B,OAAO02B,QAAQhmB,IAAIomB,kBAAkBpE;mBAGzC,SAASnK,UAAUmK;oBACfz2B,IAAI,sCAAsCyU;oBAE1C,IAAIomB,mBAAmB92B,OAAOw2B,kBAAkBjO,UAAU;oBAE1D,KAAKpa,QAAQ0U,YAAYnS,IAAI7Y,MAAMi/B,kBAAkBpE,SAAS;wBAC1D1yB,OAAO02B,QAAQhmB,IAAIomB,kBAAkBpE;;;;WAOzD1yB;YACIiW,QAAQ,SAASvF;gBACbzU,IAAI,gBAAgByU;gBACpBvC,QAAQ0P,YAAY3mB,OAAOwZ;gBAC3BknB,kBAAkBC,KAAKnnB;;YAG3BgmB,SAAS,SAAShmB,IAAI6X,UAAUmK;gBAC5B,IAAI76B,OAAOsW,QAAQiI,QAAQ1F;gBAE3BvC,QAAQuT,WAAWhR,IAAI7Y,MAAM0wB,UAAUmK;gBAEvC,IAAIhN,QAAQ6P,cAAc7kB,KAAK;oBAC3BgV,QAAQyU,cAAczU,QAAQyU,WAAWzpB;;gBAG7CknB,kBAAkBC,KAAKnnB;;YAK3B8oB,gBAAgB,SAAS9oB;gBACrB,OAAQgV,QAAQ0U,YAAY1U,QAAQ0U,SAAS1pB,OACxCgV,QAAQ7N,WAAW6N,QAAQ7N,QAAQnH;;YAG5C2pB,aAAa;gBACT,IAAIC,cAAcpZ,YAAYprB,GAAGorB,aAAaprB,GAAGykC,aAC7CC,uBAAuB1kC,GAAGkT,kBAAkBqC,gBAAgB,QAAQ;gBAExEqa,UAAU,IAAI4U,YAAYE,uBAAuB,iBAC7CrsB;oBAEImV,qBAAqBnV,QAAQmV;oBAC7BH,eAAehV,QAAQgV;oBACvB/M,SAASjI,QAAQiI;oBACjB0C,SAAS3K,QAAQ2K;oBACjBO,SAASlL,QAAQkL;oBACjBpd,KAAKA;oBACL2lB,UAAUzT,QAAQyT;oBAClBN,YAAYnT,QAAQmT;oBACpB0B,eAAe7U,QAAQ6U;oBACvByX,cAAc,SAAS/pB;wBACnBvC,QAAQiE,UAAU1B,IAAI5a,GAAGib,OAAO4C;;;gBAK5C,IAAI+R,QAAQgV,+BAA+B;oBACvChV,QAAQgV;;;YAIhBC,6BAA6B,SAASjqB;gBAClC,OAAOvC,QAAQiV,SAAS1S;;YAM5BkqB,YAAY,SAASlqB,IAAInP;gBAIrB,IAAIA,SAASmkB,QAAQ7N,QAAQnH,OAAOnP,gBAAgBzL,GAAG6X,WAAW;oBAK9DQ,QAAQ4T,aAAarR;oBAErBzU,IAAI,iDAAiDyU;oBACrDnP,KAAKuM,SAASb,KAAK,SAAS4tB;wBACxB5+B,IAAI,qCAAqCyU;wBAGzCgV,QAAQoV,WAAWpqB,IAAImqB;wBAGvB1sB,QAAQ8U,QAAQvS,IAAImqB,cAAcnpB;wBAGlCgU,QAAQwS,mBAAmBxnB;wBAE3B1Q,OAAO+6B,uBAAuBrqB;uBAIlC,SAAS0L;wBACL,IAAI4e;wBAEJ,IAAI5e,cAAc;4BACd4e,cAAc76B,QAAQic;;wBAG1BngB,IAAInG,GAAG8H,OAAO,0DAA0D8S,IAAI0L,eAAe;wBAE3FjO,QAAQuT,WAAWhR,IAAIvC,QAAQiI,QAAQ1F,KAAK5a,GAAG6B,OAAOqjC,eAAelF,uBAAuB;wBAC5F91B,OAAO+6B,uBAAuBrqB;wBAC9BknB,kBAAkBC,KAAKnnB;;uBAG1B;oBACD,OAAO1Q,OAAO+6B,uBAAuBrqB;;gBAGzC,OAAO;;YAIXqqB,wBAAwB,SAASrqB;gBAC7B,IAAIuqB,aAAa9sB,QAAQgF,mBAAmBzC,KACxCwqB,iBAAiB;gBAErB,IAAID,cAAcA,WAAWp/B,QAAQ;oBACjCI,IAAI,4CAA4CyU;oBAEhD5a,GAAG+C,KAAKoiC,YAAY,SAASniC,KAAKqiC;wBAC9B,IAAIn7B,OAAO26B,4BAA4BQ,gBAAgBzV,QAAQ7N,QAAQsjB,YAAY;4BAC/ED,iBAAiBC,cAAczqB;4BAC/B1Q,OAAOo7B,IAAID;+BAEV,IAAIn7B,OAAO26B,4BAA4BQ,YAAY;4BACpD,OAAO;;;uBAId;oBACDD,iBAAiB;oBACjBl7B,OAAOo7B,IAAI1qB;;gBAGf,OAAOwqB;;YAGXhB,cAAc,SAASxpB,IAAI6X;gBACvB,IAAIA,SAAS7V,YAAYzY,WAAW;oBAChCkU,QAAQ6U,cAActS,IAAI6X,SAAS7V;;;YAO3C8jB,mBAAmB,SAAS6E,kBAAkBpS;gBAC1C,IAAIV,WAAW8S;gBAIf,KAAKvlC,GAAGuG,SAASg/B,mBAAmB;oBAChC9S;oBAEA,IAAIzyB,GAAGwH,SAAS+9B,sBAAsBpS,YAAY;wBAC9CV,SAASpoB,QAAQk7B;;;gBAIzB9S,SAASxmB,UAAUknB;gBAEnB,OAAOV;;YAGX6S,KAAK,SAAS1qB;gBACV,IAAI7Y,OAAOsW,QAAQiI,QAAQ1F;gBAE3B,KAAKilB,WAAW1e,QAAQvG,KAAK;oBACzB,MAAM,IAAI5a,GAAGwB,MAAMoZ,KAAK;;gBAG5BvC,QAAQ8T,SAASvR,IAAI7Y,MAAMoV,KACvB,SAASsb;oBACL,IAAIA,YAAYA,SAASnc,OAAO;wBAC5B+B,QAAQiE,UAAU1B,IAAI5a,GAAGib,OAAO0C;wBAChCiS,QAAQtZ,MAAMsE;wBACdknB,kBAAkBC,KAAKnnB;2BAEtB;wBACD,IAAIklB,oBAAoBlQ,QAAQ4V,qBAAqB5qB,KAAK;4BACtDqlB,QAAQoC,SAASznB;+BAEhB;4BACDspB,OAAO1G,KAAK5iB,IAAI7Y;;;mBAK5B,SAASsI;oBACLA,QAAQA;oBAERlE,IAAIyU,KAAK,uEAAuEvQ,OAAO;oBAEvF,KAAKgO,QAAQ0U,YAAYnS,IAAI7Y,MAAMsI,MAAM2iB,qBAAqB;wBAC1D,IAAIyF,WAAWvoB,OAAOw2B,kBAAkBr2B,MAAM2iB,cAAc;wBAC5D9iB,OAAO02B,QAAQhmB,IAAI6X;;;;YAMnCznB,OAAO,SAAS4P;gBACZ,IAAI6qB,eAAev7B,OAAOw5B,eAAe9oB;gBAEzC,IAAI6qB,cAAc;oBACd,OAAOv7B,OAAO46B,WAAWlqB,IAAI6qB;uBAE5B;oBACDv7B,OAAOo7B,IAAI1qB;oBACX,OAAO;;;;QAKnB5a,GAAG6B,OAAOxB;YAINuQ,KAAK,SAASgK,IAAIiB;gBACd+T,QAAQhf,IAAIP,MAAMhQ,MAAM8H;;YAM5B+B,QAAQ,SAAS0Q;gBACb,IAAIknB,kBAAkBxE,KAAK1iB,KAAK;oBAC5B,OAAO1Q,OAAOc,MAAM4P;;gBAExB,OAAO;;YAGX+J,OAAO,SAAS/J;gBAKZ,IAAImlB,4BAA4B;oBAC5BnQ,QAAQ6P,cAAc7kB,IAAIpK,KAAK8wB,gBAAgB;;gBAKnD,IAAIQ,kBAAkBiC,kBAAkBnpB,KAAK;oBACzC,OAAO1Q,OAAOc,MAAM4P;uBAMnB;oBACD,OAAOilB,WAAW31B,OAAO0Q;;;YAOjCuF,QAAQ,SAASvF;gBACb,IAAI8qB,eAAe9V,QAAQzP,OAAOvF;gBAElC,IAAI5a,GAAGiX,iBAAiByuB,eAAe;oBACnCA,aAAavuB,KAAK;wBACdjN,OAAOiW,OAAOvF;;uBAGjB,IAAI8qB,iBAAiB,OAAO;oBAC7Bx7B,OAAOiW,OAAOvF;;;YAOtB4F,WAAW;gBACP,IAAIojB,qBAAqB9B,kBAAkB6B,yBACvC7yB;gBAIJ,IAAI8yB,mBAAmB79B,QAAQ;oBAC3B,KAAK+K,IAAI8yB,mBAAmB79B,SAAS,GAAG+K,KAAK,GAAGA,KAAK;wBACjD+uB,WAAW1f,OAAOyjB,mBAAmB9yB;;;gBAI7CgxB,kBAAkB5nB;;YAKtB6H,SAAS,SAASnH;gBACd,IAAIgV,QAAQ0U,YAAY1U,QAAQ0U,SAAS1pB,KAAK;oBAC1C,OAAOgV,QAAQ0U,SAAS1pB,IAAI9C;;gBAGhC,OAAO8X,QAAQ7N,WAAW6N,QAAQ7N,QAAQnH;;YAI9C+qB,WAAW,SAAS/qB;gBAChB,UAAUgV,QAAQ0U,YAAY1U,QAAQ0U,SAAS1pB;;YAGnDhB,UAAU,SAASgB;gBACf,IAAIgV,QAAQhW,UAAU;oBAClB,OAAOgW,QAAQhW,SAASgB;;;YAIhCV,OAAO;gBACH/T,IAAI;gBACJ05B,WAAWrf;gBACXshB,kBAAkB5nB;gBAClB0V,QAAQ1V;;YAGZ0J,SAAS,SAAShJ;gBACd,IAAIilB,WAAW1e,QAAQvG,KAAK;oBACxB,OAAOgV,QAAQhM,QAAQhJ;;;YAO/BuG,SAAS,SAASvG;gBACd,OAAOgV,QAAQzO,QAAQvG;;YAG3B6I,iBAAiB,SAAS7I;gBACtB,IAAI/K,MAAM+f,QAAQzO,QAAQvG,OACtBgV,QAAQgW,sBACRhW,QAAQgW,mBAAmBhrB;gBAE/B,IAAI/K,KAAK;oBACL,SAASqF,aAAapF,QAAQD;;gBAGlC,OAAO;;YAGXkT,uBAAuB;gBACnB,IAAI6M,QAAQ7M,uBAAuB;oBAC/B,OAAO6M,QAAQ7M;;gBAEnB;;YAWJyc,qBAAqB,SAAS5kB;gBAC1B,IAAIilB,WAAW1e,QAAQvG,KAAK;oBACxB,OAAOgV,QAAQ4P,oBAAoB5kB;;;YAS3CtE,OAAO,SAASsE;gBACZ,IAAIilB,WAAWrc,YAAY5I,OAAOgV,QAAQtZ,SAASupB,WAAW1e,QAAQvG,OAAOgV,QAAQtZ,MAAMsE,KAAK;oBAC5FknB,kBAAkBC,KAAKnnB;oBACvBgV,QAAQiS,0BAA0BjnB;oBAClC,OAAO;;gBAEX,OAAO;;YAGXirB,oBAAoB,SAASjrB;gBACzB,SAASgV,QAAQiW,sBAAsBjW,QAAQiW,mBAAmBjrB;;YAItE4I,aAAa,SAAS5I;gBAClB,SAASgV,QAAQpM,eAAeoM,QAAQpM,YAAY5I;;;QAI5D5a,GAAG6B,OAAOwW,SAASH;QACnB/R,MAAMkS,QAAQlS;QACd25B,mBAAmBznB,QAAQ3C,SAASmL,WAAW7gB,GAAGkT,kBAAkBwC;QACpEqqB,6BAA6BD,oBAAoBznB,QAAQ3C,SAASmjB,WAAWhY;QAE7Emf,uBAAwB;YACpB,IAAIvN;YAEJA,SAASpa,QAAQiT,qBAAqB;YAEtC,OAAOmH;;QAGXvoB,OAAOq6B;;IC1zBXvkC,GAAG8lC,uBAAuB,SAAS5tB;QAC/B;QAEA,IAAIG;YACIlS,KAAK,SAASC,SAASC;WAE3B0/B;QAEJ/lC,GAAG6B,OAAOwW,SAASH;QAEnBlY,GAAG6B,OAAOxB;YACN2lC,gBAAgB,SAASprB,IAAInL;gBACzB,IAAIw2B,2BAA2B,SAASzQ;oBAChC/lB,SAAS+lB,MAAM1wB;;gBAGvB,IAAIE,OAAOsQ,aAAa;oBACpBywB,yBAAyBnrB,MAAM5a,GAAGgF,QAAQ1E,OAAO,WAAW2lC;uBAE3D;oBACD9/B,IAAI,yDAAyD;;;YAIrE+/B,uBAAuB,SAAStrB;gBAC5B,IAAI5V,OAAOsQ,aAAa;oBACpB,IAAI6wB,WAAWJ,yBAAyBnrB;oBACxC,IAAIurB,UAAU;wBACVA;;;;;;ICvBpBnmC,GAAGomC,oBAAoB,SAAS3qB;QAC5B;QAEA,IAAIpD,UAAUoD,KAAKpD,SACfuX,UAAUvvB,MACV++B,QAAQ3jB,KAAK2jB,OACbiH,wBAAwBrmC,GAAGoN,eAC3Bk5B,sBACAC,uBACAC,gCACAC,SAASpuB,QAAQouB,QACjB3b,YAAYzS,QAAQyS,WACpBvH,UAAU6b,MAAM7b,SAChBpd,MAAMi5B,MAAMj5B,KACZugC,sBAAsB,IAAI1mC,GAAG8lC;YAAsB3/B,KAAKA;;QAO5D,SAASwgC,YAAY/rB;mBACV2rB,iBAAiB3rB;YAKxB,IAAI6rB,QAAQ;gBACR7S,aAAa4S,0BAA0B5rB;uBAChC4rB,0BAA0B5rB;gBACjC8rB,oBAAoBR,sBAAsBtrB;;YAG9C,IAAIgsB,SAAS/8B,SAASg9B,eAAejX,QAAQkX,eAAelsB;YAC5D,IAAIgsB,QAAQ;gBAIRA,OAAOr1B,aAAa,OAAO;gBAE3BvR,GAAG4mC,QAAQxlC;;;QAQnB,SAAS2lC,uBAAuBC;YAC5B,OAAOA,WAAWthC,MAAM,KAAK;;QAUjC,SAASuhC,oBAAoBllC;YACzB,IAAI6kC,SAAS5mC,GAAGoP,UAAU,2CAA2CrN,OAAO;YAE5E6kC,OAAOr1B,aAAa,MAAMxP;YAE1B6kC,OAAOzmC,MAAMC,UAAU;YACvByJ,SAASq9B,KAAK11B,YAAYo1B;YAE1B,OAAOA;;QAUX,SAASO,4BAA4BP,QAAQn3B;YACzC,IAAIu3B,aAAaJ,OAAOhsB,IACpByG,SAAS0lB,uBAAuBC,aAChCjsB,OAAOwI,QAAQlC;YAEnBilB,gBAAgBvrB,QAAQtL;YAIxB82B,iBAAiBllB,UAAUrhB,GAAG4mC,QAAQtmC,OAAO,QAAQ;gBACjD,IAAIsvB,QAAQhW,SAASyH,SAAS;oBAC1Blb,IAAI,qEAAqE6gC,aAAa;oBAEtFR,0BAA0BQ,cAAc/c,WAAW;wBAC/C,IAAI3D,eAAe,kEAAkE0gB;wBACrF7gC,IAAImgB,cAAc;wBAClB7W;4BACIpF,OAAOic;;uBAEZ;;;YAMXogB,oBAAoBV,eAAegB,YAAY,SAAS5gC;gBACpDD,IAAI,6CAA6CC,UAAU;gBAC3D,IAAIib,SAAS0lB,uBAAuBC,aAChCvU,WAAW7C,QAAQwX,mBAAmBhhC,UACtC2U,OAAO0X,SAAS1X,MAChBssB;gBAEJ,IAAItsB,QAAQurB,gBAAgBvrB,OAAO;oBAC/B5U,IAAI,uCAAuC6gC;oBAC3CpT,aAAa4S,0BAA0BQ;2BAChCR,0BAA0BQ;oBAEjCpX,QAAQ0X,iBAAiBN;oBAEzBK,iBAAiBf,gBAAgBvrB;2BAE1BurB,gBAAgBvrB;oBACvB2rB,oBAAoBR,sBAAsBc;oBAC1CK,eAAe5U;uBAEd,KAAK1X,MAAM;oBACZ5U,IAAI,MAAMC,UAAU;;;;QAKhCpG,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGm/B,cAAc1jB;QAErCzb,GAAGwM,SAASnM,MAAM,SAASsM;YACvB;gBAIIiE,KAAK,SAASgK,IAAI8T;oBACd/hB,OAAOiE,IAAIgK;wBAAKhR,OAAO8kB;;oBAEvBA,UAAUnd,aAAa,QAAQuZ;oBAG/B,IAAI4D,UAAUvtB,YAAY;wBACtBnB,GAAG0uB,WAAWttB;;;gBAItBwiB,SAAS,SAAShJ;oBACd+rB,YAAY/rB;oBACZjO,OAAOiX,QAAQhJ;;gBAGnBuG,SAAS,SAASvG;oBACd,OAAOjO,OAAOwU,QAAQvG,OAClBgV,QAAQ6P,cAAc7kB,IAAIhR,UAAUzF;;;;QAKpDnE,GAAG6B,OAAOxB;YACNuZ,UAAU,SAASgB;gBACf,OAAOgV,QAAQ6P,cAAc7kB,IAAIhR;;YAWrC29B,kBAAkB,SAASX,QAAQn3B;gBAE/B,IAAI+3B;gBAEJ,IAAIf,QAAQ;oBACRU,4BAA4BP,QAAQn3B;uBAEnC;oBACD82B,iBAAiBK,OAAOhsB,MAAM5a,GAAG4mC,QAAQtmC,OAAO,QAAQ;wBACpD6F,IAAI,2BAA2BygC,OAAOhsB;wBAKtC,KAAKgsB,OAAOzlC,YAAY;4BACpB;;wBAGJ;4BAEI,IAAIylC,OAAOa,mBACPb,OAAOa,gBAAgBP,QACvBN,OAAOa,gBAAgBP,KAAK33B,aAAa,SAAS;gCAKlD;;0BAGR,OAAOlF;4BAEHlE,IAAI,gFAAgFkE,MAAMjE,UAAU,KAAK;4BACzGohC;gCAAsBv7B,SAAS;;;wBAGnCwD,SAAS+3B;;;;YAWrBE,eAAe,SAAS9sB;gBACpB,IAAIosB,aAAapX,QAAQkX,eAAelsB;gBAExC,OAAOqsB,oBAAoBD;;YAQ/BM,kBAAkB,SAAS1sB;gBACvB,IAAI2rB,iBAAiB3rB,QAAQzW,WAAW;oBACpCoiC,iBAAiB3rB;2BACV2rB,iBAAiB3rB;;;YAQhCksB,gBAAgB,SAASzlB;gBACrB,OAAOA,SAAS,MAAMglB;;YAY1BsB,oBAAoB,SAASlsB;gBACzB,IAAI+L,SAAS/L,KAAK+L,QACdhJ,WAAW/C,KAAK+C,UAChBD,SAAS9C,KAAK8C,QACdiZ,eAAe/b,KAAK+b,cACpBoQ,aAAansB,KAAKmsB,YAClBt2B,OAAOtR,GAAGoP,UAAU,mBAAmBoY,SAAS,4CAChDsV,MAAMte;gBAEV,IAAIgZ,cAAc;oBACdx3B,GAAGqR,WAAWkN,QAAQjN;uBAErB;oBACDwrB,MAAM98B,GAAGsQ,QAAQiO,QAAQC;;gBAG7BlN,KAAKC,aAAa,UAAUurB;gBAC5BxrB,KAAKC,aAAa,UAAUq2B;gBAC5Bt2B,KAAKnR,MAAMC,UAAU;gBACrByJ,SAASq9B,KAAK11B,YAAYF;gBAE1B,OAAOA;;YAOX81B,oBAAoB,SAASS;gBACzB,IAAIpV;gBAEJ;oBACIA,WAAWzyB,GAAGyR,UAAUo2B;kBAE5B,OAAOx9B;oBACHlE,IAAI,4DAA4DkE,MAAMjE,UAAU,KAAK;;gBAGzF,OAAOqsB;;;;ICnSnBzyB,GAAG8nC,mBAAmB,SAASrsB;QAC3B;QAEA,IAAImU,UAAUvvB,MACV+qB,YAAY3P,KAAKpD,QAAQ+S,WACzBgU,QAAQ3jB,KAAK2jB,OACb1pB,WAAW+F,KAAKpD,QAAQ3C,UACxBqyB,eAAe,SAASntB;YACpB,IAAIykB,YAAYzP,QAAQ6P,cAAc7kB;YAEtC,IAAIykB,UAAUpG,WAAW;gBACrB,OAAOoG,UAAUpG;mBAGhB;gBACD,IAAIA,YAAYvjB,SAAS0jB;gBAEzB,IAAIp5B,GAAG6G,WAAWoyB,YAAY;oBAC1BA,YAAYA,UAAUre,IAAIoI,QAAQpI;;gBAGtCykB,UAAUpG,YAAYA;gBACtB,OAAOA;;WAGfziB,SAASiF,KAAKpD,QAAQ7B,QACtBwxB,aAAatyB,YAAY+F,KAAKpD,QAAQ3C,SAASmL,WAAW7gB,GAAGkT,kBAAkBwC,UAC/EuyB,gBAAgBzxB,UAAUiF,KAAKpD,QAAQ7B,OAAOqK,WAAWmnB,cAAchoC,GAAGkT,kBAAkBsD,QAC5F8J,UAAU8e,MAAM9e,SAChB0C,UAAUoc,MAAMpc,SAChBO,UAAU6b,MAAM7b,SAChBhB,cAAc6c,MAAM7c,aACpB8K,gBAAgB+R,MAAM/R,eACtBH,gBAAgBkS,MAAMlS,eACtB1B,aAAa4T,MAAM5T,YACnBrlB,MAAMi5B,MAAMj5B,KACZqnB,sBAAsB4R,MAAM5R;QAEhC,SAASmU,MAAM/mB;YACX5a,GAAG+C,KAAK6sB,QAAQ4R,SAAS5mB,KAAK,SAASstB,OAAOxzB;gBAC1C,IAAIyzB,gBAAgBvY,QAAQwY,kBAAkBxtB,IAAIstB;gBAElDxzB,IAAIyoB,qBAAqB;gBACzBzoB,IAAIxK,OAAO+xB,aAAa;gBACxBvnB,IAAIitB;gBACJwG,iBAAiBA,cAAcjJ,YAAYiJ,cAAcjJ,SAAStkB;;;QAI1E5a,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGm/B,cAAc1jB;QAErCzb,GAAGwM,SAASnM,MAAM,SAASsM;YACvB;gBAIIiE,KAAK,SAASgK,IAAIytB;oBACd,IAAIroC,GAAGyI,OAAO4/B,gBAAgBroC,GAAGyJ,OAAO4+B,cAAc;wBAClD17B,OAAOiE,IAAIgK;4BAAKiB,MAAMwsB;;2BAErB,IAAIA,uBAAuBroC,GAAG6X,WAAW;wBAC1ClL,OAAOiE,IAAIgK;4BAAKwkB,OAAOiJ;;2BAEtB;wBACD,MAAM,IAAI7mC,MAAM;;oBAGpBouB,QAAQ0Y,eAAe1tB;oBACvBqtB,iBAAiBrY,QAAQ2Y,uBAAuB3tB;;gBAGpDgJ,SAAS,SAAShJ;oBACd+mB,MAAM/mB;oBACNgV,QAAQ+Q,+BAA+B/lB;oBACvCgV,QAAQyU,WAAWzpB;oBACnBjO,OAAOiX,QAAQhJ;;;;QAK3B5a,GAAG6B,OAAOxB;YAEN0gC,kBAAkB,SAASnmB,IAAIslB;gBAC3B,IAAIb,YAAYzP,QAAQ6P,cAAc7kB;gBAEtC,IAAIykB,WAAW;2BACJA,UAAU7uB,KAAKg4B,aAAatI;;;YAI3C6C,UAAU,SAASnoB,IAAIslB;gBACnB,IAAIuI,YAAY7Y,QAAQ6P,cAAc7kB,IAAIpK;gBAE1C,IAAIi4B,UAAUC,MAAM;2BACTD,UAAUC,KAAKxI;;gBAE1B,IAAIuI,UAAUE,gBAAgB;2BACnBF,UAAUE,eAAezI;;;YAMxCM,gBAAgB,SAAS5lB,IAAIguB;gBACzB,IAAIC,eAAejZ,QAAQuS,gBAAgBvnB,MAAM,GAC7ClG,MAAMkb,QAAQkZ,QAAQluB,IAAIiuB;gBAE9B,IAAID,gBAAgB;oBAChB,OAAO,IAAI5oC,GAAG+L,UAAUE,QAAQ28B,eAAel0B,MAAMA;;gBAGzD,OAAO,IAAI1U,GAAG+L,UAAUE,YAAYyI;;YAGxCqN,SAAS,SAASnH;gBACd,OAAOgV,QAAQzO,QAAQvG,OAAOgV,QAAQ6P,cAAc7kB,IAAIiB;;YAG5DyoB,UAAU,SAAS1pB;gBACf,OAAOgV,QAAQzO,QAAQvG,OAAOgV,QAAQ6P,cAAc7kB,IAAIwkB;;YAO5Drc,uBAAuB;gBACnB,IAAIgmB;gBAEJnZ,QAAQoZ,sBAAsB,SAASn5B,KAAKuQ;oBACxCwP,QAAQiS,0BAA0B,MAAMzhB,WAAW1K,SAASyrB,YAAa/gB,WAAW1K,SAAS0rB;oBAE7F,IAAIt8B;wBACA/C,MAAMqe,WAAWre;wBACjBq/B,WAAWhhB,WAAW1K,SAAS0rB;wBAC/BxlB,MAAMwE,WAAWxE;wBACjBb,MAAMqF,WAAWrF;;oBAGrB,IAAIqF,WAAWvQ,KAAK;wBAChB/K,KAAK+K,MAAMuQ,WAAWvQ;;oBAG1B,IAAIuQ,WAAW0M,kBAAkB;wBAC7BhoB,KAAKgoB,mBAAmB1M,WAAW0M;;oBAGvCic,mBAAmB7lC,KAAK4B;;gBAG5B,OAAOikC;;YAGXlD,oBAAoB,SAASjrB;gBACzB,OAAOgV,QAAQ6P,cAAc7kB,IAAIwlB;;YAGrC5c,aAAa,SAAS5I;gBAClB,SAASlF,YAAYka,QAAQzO,QAAQvG,QAChCgV,QAAQ6P,cAAc7kB,IAAIquB;;YAGnCpH,2BAA2B,SAASjnB,IAAIsuB,eAAeC;gBACnD,IAAI9J,YAAYzP,QAAQ6P,cAAc7kB,WAClCwuB,gBAAiB/J,UAAU3pB,gBAC3ByrB,aAAa+H,iBAAiBE,cAAcjI,YAC5CC,YAAY+H,gBAAgBC,cAAchI;gBAE9C,IAAID,YAAY;oBACZh7B,IAAInG,GAAG8H,OAAO,0DAA0D6J,KAAK8rB,UAAU0D;oBACvFA,WAAWkI;oBACXrpC,GAAG+C,KAAKo+B,YAAY,SAASn+B,KAAKk9B;wBAC9BkB,UAAUC,QAAQnB;;oBAEtBiB,WAAWp7B,SAAS;;;YAI5BuQ,OAAO,SAASsE;gBACZ,IAAIgV,QAAQzO,QAAQvG,KAAK;oBACrBzU,IAAInG,GAAG8H,OAAO,6DAA6D8S,IAAI0F,QAAQ1F;oBACvFgV,QAAQ6P,cAAc7kB,IAAI0uB,SAAS;oBACnC3H,MAAM/mB;oBACN,OAAO;;;YAIfwnB,oBAAoB,SAASxnB;gBACzB,IAAIlF,YAAYka,QAAQzO,QAAQvG,KAAK;oBACjC,IAAInD,QAAQmY,QAAQ6P,cAAc7kB,KAC9B2uB,aACAz4B;2BAEG2G,MAAM/B;oBAEb+B,MAAM/B;oBACN6zB,cAAc3Z,QAAQuS,gBAAgBvnB;oBACtC,IAAI2uB,cAAc,KAAK7zB,SAASojB,WAAW;wBACvCrhB,MAAM/B,SAASmL,UAAU;wBACzBpJ,MAAM/B,SAAS8zB,QAAQD;wBACvB9xB,MAAM/B,SAAS0rB;wBAEf,KAAKtwB,IAAI,GAAGA,IAAIy4B,aAAaz4B,KAAK;4BAC9B2G,MAAM/B,SAAS0rB,UAAUl+B,KAAK4N;;wBAGlC8e,QAAQ0Y,eAAe1tB;2BAEtB;wBACDnD,MAAM/B,SAASmL,UAAU;;;;YAKrCmkB,YAAY,SAASpqB,IAAI6uB;gBACrB,IAAI7Z,QAAQzO,QAAQvG,KAAK;oBACrBgV,QAAQ6P,cAAc7kB,IAAIiB,OAAO4tB;;;YAIzCpF,YAAY,SAASzpB;gBACjB,IAAI6tB,YAAY7Y,QAAQ6P,cAAc7kB,IAAIpK;gBAE1CxQ,GAAG+C,KAAK0lC,UAAUE,gBAAgB,SAASe;2BAChCjB,UAAUE,eAAee;;gBAGpC1pC,GAAG+C,KAAK0lC,UAAUC,MAAM,SAASgB;2BACtBjB,UAAUC,KAAKgB;;;YAW9BC,YAAY,SAAS/uB,IAAIgvB;gBACrB,OAAOha,QAAQia,aAAajvB,IAAIgvB,aAAa5pC,GAAGiK;;YAGpDm+B,mBAAmB,SAASxtB,IAAIgvB;gBAC5B,IAAI1J,WAAW0J,eAAe,QAAQ,IAAIA;gBAC1C,OAAOha,QAAQ6P,cAAc7kB,IAAIpK,KAAKm4B,eAAezI;;YAGzDC,eAAe,SAASvlB,IAAIkvB;gBACxB,IAAI7Q,YAAY8O,aAAantB,KACzBmvB,WAAW/mB,QAAQpI,KACnB7P,aAAa6kB,QAAQ7N,QAAQnH,KAC7BovB,aAAa/Q,YAAY6Q,YACzBG,WAAWD,aAAa/Q,aAAa8Q,WAAWA,WAAWC,aAAa/Q,WACxEsQ,cAAc3Z,QAAQuS,gBAAgBvnB,KACtC4tB,eAAenoC,KAAKo/B,cAAc7kB,IAAIpK,KAAKg4B,cAI3C/8B,OAAO+8B,aAAasB,eAAe9pC,GAAG8K,UAAUC,YAAYi/B,YAAYC;gBAE5EzB,aAAasB,cAAcr+B;gBAE3B;oBACIy+B,MAAMJ;oBACN9+B,OAAOg/B;oBACP/+B,KAAKg/B;oBACLE,OAAOZ;oBACP99B,MAAMA;oBACNmQ,MAAMquB,WAAWD;;;YAIzB1J,0BAA0B,SAAS/T;gBAC/B;oBACIG,WAAWH,UAAU2d;oBACrBE,WAAW7d,UAAUvhB,QAAQ;oBAC7Bq/B,SAAS9d,UAAUthB;oBACnBkuB,YAAY5M,UAAU4d;;;YAQ9BvE,oBAAoB,SAAShrB;gBACzB,IAAI0vB,gBAAgB,OAChBvoC,OAAOue,QAAQ1F,KACfgB,OAAOoH,QAAQpI,KACfqe,YAAY8O,aAAantB,KACzB4D,WAAW+D,YAAY3H,KACvB6e,aAAajjB,OAAOijB,WAAW7e,KAC/B2vB,iBAAiBvqC,GAAG8H,OAAO,4BAA4BsjB,WAAWkf,eAAevoC,MAAM6Z,MAAMqd,WAAWza;gBAE5Gib,WAAW+Q,QAAQ,SAAS36B;oBACxB06B,kBAAkB,MAAM16B;;gBAG5B,OAAO06B;;YAGXE,cAAc,SAAS7vB;gBACnB,OAAOgV,QAAQ7N,QAAQnH,IAAIra;;YAG/BmqC,qBAAqB,SAAS9vB;gBAC1B,OAAOgV,QAAQ6P,cAAc7kB,IAAIlF;;YAOrCysB,iBAAiB,SAASvnB;gBACtB,IAAIlF,UAAU;oBACV,IAAIq0B,WAAW/mB,QAAQpI,KACnBqe,YAAY8O,aAAantB;oBAE7B,OAAOjZ,KAAKgpC,KAAKZ,WAAW9Q;;;YAIpC6P,SAAS,SAASluB,IAAIgvB;gBAClB,IAAI1J,WAAW0J,eAAe,QAAQ,IAAIA;gBAC1C,OAAOha,QAAQ6P,cAAc7kB,IAAIpK,KAAKk4B,KAAKxI;;YAG/CsB,UAAU,SAAS5mB;gBACf,OAAOgV,QAAQ6P,cAAc7kB,IAAIpK,KAAKk4B;;YAK1CM,uBAAuB,SAASv5B;gBAC5B,IAAIw4B,eAAe;oBACfjoC,GAAG+C,KAAKmS,cAAc,SAASrF,KAAKvI;wBAChC,IAAIuI,IAAIlK,QAAQ3F,GAAG8H,OAAO,cAAcsjB,gBAAgB,GAAG;4BACvD,IAAIhL,aAAazO,KAAKC,MAAMtK;4BAC5BmI,SAASI,KAAKuQ;;;;;YAM9BkoB,gBAAgB,SAAS1tB;gBACrBgV,QAAQ6P,cAAc7kB,IAAIpK;oBACtBm4B;oBACAtI;oBACAqI;oBACAF;;;YAIRoC,mBAAmB,SAAShwB;gBACxBgV,QAAQ6P,cAAc7kB,IAAIquB,eAAe;;YAK7CtI,gCAAgC,SAAS/lB;gBACrC,IAAI2vB;gBAEJ,IAAItC,iBAAiBrY,QAAQpM,YAAY5I,KAAK;oBAC1C2vB,iBAAiB3a,QAAQgW,mBAAmBhrB;oBAE5C,IAAI2vB,kBAAkBr1B,aAAapF,QAAQy6B,iBAAiB;wBACxDr1B,aAAa21B,WAAWN;wBACxB,OAAO;;;gBAIf,OAAO;;YAKXhC,wBAAwB,SAAS3tB;gBAC7B,IAAInD,QAAQmY,QAAQ6P,cAAc7kB,KAC9B2vB,gBAAgBO;gBAIpB,IAAI7C,iBAAiBxwB,MAAM5H,QAAQ1L,WAAW;oBAC1ComC,iBAAiB3a,QAAQgW,mBAAmBhrB;oBAC5CkwB,gBAAgB51B,aAAapF,QAAQy6B;oBAGrC,IAAIO,eAAe;wBACfA,gBAAgBn5B,KAAKC,MAAMk5B;wBAI3B,IAAIzd,cAAcyd,cAAc/vB,OAAO;4BACnC6U,QAAQgb,kBAAkBhwB;+BAEzB;4BACDzU,IAAInG,GAAG8H,OAAO,2DAA2D8S,IAAI0F,QAAQ1F;4BAErFsS,cAActS,IAAIkwB,cAAc/vB;4BAEhCtD,MAAM5H,MAAMi7B,cAAcj7B;4BAC1B4H,MAAM/B,WAAWo1B,cAAcp1B;4BAC/B+B,MAAMgU,SAASqf,cAAcrf;4BAC7BhU,MAAMqV,mBAAmBge,cAAche;4BACvCrV,MAAM2oB,mBAAmB;4BAEzBxQ,QAAQiS,0BAA0BjnB;;;;;YAOlDkoB,2BAA2B,SAASloB;gBAChC,IAAInD,QAAQmY,QAAQ6P,cAAc7kB,KAC9B2vB,gBAAgBO;gBAGpB,IAAI7C,iBAAiBrY,QAAQpM,YAAY5I,KAAK;oBAC1C,IAAIkS,mBAAmBU,oBAAoB5S;oBAE3C2vB,iBAAiB3a,QAAQgW,mBAAmBhrB;oBAE5CkwB;wBACI/oC,MAAMue,QAAQ1F;wBACdgB,MAAMoH,QAAQpI;wBACdG,MAAMwI,QAAQ3I;wBACd/K,KAAK4H,MAAM5H;wBACX6F,UAAU+B,MAAM/B;wBAChB+V,QAAQhU,MAAMgU;wBACdsf,aAAa/L,KAAKsG;;oBAGtB,IAAIxY,kBAAkB;wBAClBge,cAAche,mBAAmBA;;oBAGrC;wBACI5X,aAAaC,QAAQo1B,gBAAgB54B,KAAK8rB,UAAUqN;sBAExD,OAAOzgC;wBACHlE,IAAInG,GAAG8H,OAAO,2DAA2D8S,IAAIvQ,MAAM1D,aAAa;;;;YAK5GqkC,0BAA0B,SAASpwB,IAAIslB,UAAUjH;gBAC7C,IAAIvkB,MAAMkb,QAAQkZ,QAAQluB,IAAIslB,WAC1Bn+B,OAAOue,QAAQ1F,KACfqwB;oBACI/G,QAAQ,SAASzY,QAAQC;wBACrB,IAAIqe,WAAW/mB,QAAQpI;wBAEvB,IAAI6Q,WAAWC,OAAO;4BAClBF,WAAW5Q,IAAI7Y,MAAMgoC,UAAUA;+BAE9B;4BACDve,WAAW5Q,IAAI7Y,MAAO0pB,UAAUse,WAAWA,WAAW,IAAIte,QAASse;;;oBAI3E9J,SAAS,SAASxU,QAAQC;wBACtB,IAAI2U,gBAAgBzQ,QAAQ6P,cAAc7kB,IAAIpK,KAAK6vB,eAC/C6K,iCAAiCtb,QAAQ6P,cAAc7kB,IAAI6Q,QAC3D0f,mBAAmB1f,QACnB2f,kBAAkB1f,OAClBwN,gBAAgBlW,QAAQpI,KACxBywB,uBAAuBF,oBAAoBC,kBAAkBnS,YAC7DqS,qBAAqBJ;wBAEzB7K,cAAcH,YAAYmL;wBAE1BrrC,GAAG+C,KAAKs9B,eAAe,SAASH,UAAUqL;4BACtCD,sBAAsBC;;wBAG1B/f,WAAW5Q,IAAI7Y,MAAMupC,oBAAoBpS;;;gBAIrDxkB,IAAIxK,OAAO+xB,aAAa,SAAS/sB;oBAC7B,IAAIA,EAAE0uB,kBAAkB;wBAEpB,IAAIr9B,OAAO04B,aAAa,OAAO,WAAW;wBAC1CgS,mBAAmB1qC,MAAM2O,EAAEuc,QAAQvc,EAAEwc;;;;YAcjDme,cAAc,SAASjvB,IAAIgvB,aAAal1B,KAAK82B;gBACzC,IAAIC,SAAS7B,eAAe,QAAQ,IAAIA,aACpCnB,YAAY7Y,QAAQ6P,cAAc7kB,IAAIpK;gBAE1Ci4B,UAAUC,OAAOD,UAAUC;gBAC3BD,UAAUE,iBAAiBF,UAAUE;gBAErCF,UAAUC,KAAK+C,UAAU/2B;gBAEzB,IAAI82B,kBAAkB;oBAClB/C,UAAUE,eAAe8C,UAAUD;;gBAGvC,OAAO92B;;YAIXkwB,+BAA+B;gBAC3B,IAAI8G,iBAAiBl1B,OAAO+iB;gBAE5B3J,QAAQoZ,sBAAsB,SAASn5B,KAAKuQ;oBACxC,IAAIurB,iBAAiB,IAAI3M,KAAK5e,WAAW2qB;oBAGzCY,eAAeC,QAAQD,eAAeE,YAAYH;oBAElD,IAAIC,eAAe1M,aAAaD,KAAKsG,OAAO;wBACxCn/B,IAAI,6CAA6C0J;wBACjDqF,aAAa21B,WAAWh7B;;;;YAWpC21B,sBAAsB,SAAS5qB;gBAC3B,IAAInD,QAAQmY,QAAQ6P,cAAc7kB;gBAGlC,IAAInD,OAAO;oBACP,KAAKA,MAAM/B,UAAU;wBACjBka,QAAQwS,mBAAmBxnB;;oBAG/B,OAAOnD,MAAM/B,SAASmL;;;;;ICziBtC7gB,GAAGunB,0BAA0B,SAASrP;QAClC;QAEA,IAAI4zB,WACAzzB;YACImP,QAAQ;YACRG,eAAe;YACfK;YACAN,gBAAgB;YAChBI,eAAe,SAASlN;gBAAK;;YAC7BmN;YACAE;gBACI8I,UAAU;gBACV4I,iBAAiB;;YAErBxzB,KAAK,SAAS4B,KAAK1B;YACnB6hB,UAAU,SAAStN;YACnBwN,kBAAkB,SAASxN,IAAIyN,UAAUC;;QAGjDtoB,GAAG6B,OAAOwW,SAASH;QAEnB,SAAS6zB;YACL,IAAI1zB,QAAQmP,OAAOC,kBAAkB,QAAQ;gBACzC;oBACIukB,SAAS;;;YAIjB;;QAGJF,YAAY9rC,GAAG6B,OAAOxB,MAAM,IAAIL,GAAG06B;YAC/BI,cAAc;YACdC,gBAAe,QAAQ;YACvBvT,QAAQnP,QAAQmP;YAChBQ,eAAe3P,QAAQ2P;YACvBD,aAAa1P,QAAQ0P;YACrBkT,gBAAgB8Q;YAChBrkB,gBAAgBrP,QAAQqP;YACxBI,eAAe,SAASlN;gBACpB,OAAOvC,QAAQyP,cAAcrF,IAAI7H;;YAErCzU,KAAKkS,QAAQlS;YACbs1B,QAAQpjB,QAAQ6P;YAChB0D,YAAYvT,QAAQ+P;YACpBH,MAAM5P,QAAQ4P;;QAGlBjoB,GAAG6B,OAAOxB;YACNq0B,YAAY,SAAS9Z,IAAIG,MAAMuZ;gBAC3B,IAAInJ,oBAAoBmJ;gBAExBjc,QAAQlS,IAAI,wCAAwCyU;gBAEpD,IAAIvC,QAAQmP,WAAW,UAAU;oBAC7BskB,UAAU3N,cAAcvjB,IACnB0jB,SAASvjB,MACTyjB,WAAWrT,mBACXqS;uBAEJ;oBACDrS,kBAAkB9S,QAAQsP,iBAAiB5M;oBAC3C+wB,UAAU3N,cAAcvjB,IACnB4jB,WAAWrT,mBACXqS;;;;;KCpDrB;QAMI,SAASyO,kBAAkBC;YACvB,IAAIC,KAAKD,IAAIE,cACTC,KAAKH,IAAII,eACTjoC,SAASwF,SAASC,cAAc,WAChCyiC;YAEJ,IAAIJ,KAAKE,KAAK,OAAO,MAAM;gBACvBhoC,OAAOmoC,QAAQnoC,OAAOoV,SAAS;gBAC/B8yB,MAAMloC,OAAOooC,WAAW;gBACxBF,IAAIG,UAAUR,MAAMC,KAAK,GAAG;gBAI5B,OAAOI,IAAII,aAAa,GAAG,GAAG,GAAG,GAAG7nC,KAAK,OAAO;mBAC7C;gBACH,OAAO;;;QAQf,SAAS8nC,qBAAqBV,KAAKC,IAAIE;YACnC,IAAIhoC,SAASwF,SAASC,cAAc,WAChC+iC,KAAK,GACLC,KAAKT,IACLU,KAAKV,IACLE,KAAKznC,MAAMkoC,OAAOC;YAEtB5oC,OAAOmoC,QAAQ;YACfnoC,OAAOoV,SAAS4yB;YAChBE,MAAMloC,OAAOooC,WAAW;YACxBF,IAAIG,UAAUR,KAAK,GAAG;YACtBpnC,OAAOynC,IAAII,aAAa,GAAG,GAAG,GAAGN,IAAIvnC;YAGrC,OAAOioC,KAAKF,IAAI;gBACZG,QAAQloC,MAAMioC,KAAK,KAAK,IAAI;gBAC5B,IAAIC,UAAU,GAAG;oBACbF,KAAKC;uBACF;oBACHF,KAAKE;;gBAETA,KAAMD,KAAKD,MAAO;;YAGtBI,QAASF,KAAKV;YACd,OAAQY,UAAU,IAAK,IAAIA;;QAM/B,SAASC,qBAAqBhB,KAAKzgC,MAAM4M,SAAS80B;YAC9C,IAAI9oC,SAASwF,SAASC,cAAc,WAChCxF,OAAO+T,QAAQ/T,QAAQ,cACvBwH,UAAU,IAAI9L,GAAG+L;YAErBqhC,oBAAoBlB,KAAKzgC,MAAMpH,QAAQgU,SAAS80B,UAC3Ch2B,KAAK;gBACFrL,QAAQG,QACJ5H,OAAOI,UAAUH,MAAM+T,QAAQ9T,WAAW;;YAItD,OAAOuH;;QAGX,SAASuhC,oCAAoC5xB;YACzC,IAAI6xB,YAAY;YAEhB,KAAKttC,GAAG0O,OAAO;gBACX,MAAM,IAAI1O,GAAGwB,MAAM;;YAGvB,IAAIia,KAAK8xB,aAAa9xB,KAAK+xB,YAAYF,WAAW;gBAC9C;oBACIG,WAAW9rC,KAAKC,MAAMD,KAAK+rC,KAAKJ,aAAa7xB,KAAK8xB,aAAa9xB,KAAK+xB;oBACpEG,UAAUhsC,KAAKC,MAAMD,KAAK+rC,KAAKJ,aAAa7xB,KAAK+xB,YAAY/xB,KAAK8xB;;;;QAQ9E,SAASH,oBAAoBlB,KAAKzgC,MAAMpH,QAAQgU,SAAS80B;YACrD,IAAIhB,KAAKD,IAAIE,cACTC,KAAKH,IAAII,eACTE,QAAQn0B,QAAQm0B,OAChB/yB,SAASpB,QAAQoB,QACjB8yB,MAAMloC,OAAOooC,WAAW,OACxB3gC,UAAU,IAAI9L,GAAG+L,WACjB6hC;YAEJrB,IAAIsB;YAEJ,IAAIx1B,QAAQy1B,QAAQ;gBAChB,OAAOC;oBACHtiC,MAAMA;oBACNpH,QAAQA;oBACRqyB,OAAOwV;oBACP8B,aAAa3B;oBACb4B,YAAY9B;oBACZ+B,aAAa71B,QAAQ61B;oBACrBJ,QAAQz1B,QAAQy1B;oBAChBK,cAAc10B;oBACd20B,aAAa5B;;;YAIrB,KAAKxsC,GAAGkT,kBAAkByD,0BAA0B;gBAChDi3B,qBAAqBP;oBACjBG,WAAWhB;oBACXe,YAAY9zB;;gBAGhB,IAAIm0B,oBAAoB;oBACpB5tC,GAAGmG,IAAInG,GAAG8H,OAAO,kFACb0kC,OAAO/yB,QAAQm0B,mBAAmBD,UAAUC,mBAAmBH,YAC/D;oBAEJjB,QAAQoB,mBAAmBD;oBAC3Bl0B,SAASm0B,mBAAmBH;;;YAIpCY,oBAAoBhqC,QAAQmoC,OAAO/yB,QAAQpB,QAAQ61B;YAInD,IAAIluC,GAAG0O,OAAO;iBACT;oBACG,IAAIu9B,kBAAkBC,MAAM;wBACxBC,MAAM;wBACNE,MAAM;;oBAGV,IAAIiC,IAAI,MACJC,YAAY1kC,SAASC,cAAc,WACnC0kC,kBAAkBrB,WAAWP,qBAAqBV,KAAKC,IAAIE,MAAM,GACjEoC,KAAK9sC,KAAKgpC,KAAK2D,IAAI9B,QAAQL,KAC3BuC,KAAK/sC,KAAKgpC,KAAK2D,IAAI70B,SAAS4yB,KAAKmC,kBACjC3B,KAAK,GACL8B,KAAK,GACLC,QAAQC,IAAIC;oBAEhBP,UAAU/B,QAAQ+B,UAAU90B,SAAS60B;oBACrCM,SAASL,UAAU9B,WAAW;oBAE9B,OAAOI,KAAKR,IAAI;wBACZwC,KAAK;wBACLC,KAAK;wBACL,OAAOD,KAAK1C,IAAI;4BACZyC,OAAOG,UAAU,GAAG,GAAGT,GAAGA;4BAC1BM,OAAOlC,UAAUR,MAAM2C,KAAKhC;4BAC5BN,IAAIG,UAAU6B,WAAW,GAAG,GAAGD,GAAGA,GAAGQ,IAAIH,IAAIF,IAAIC;4BACjDG,MAAMP;4BACNQ,MAAML;;wBAEV5B,MAAMyB;wBACNK,MAAMD;;oBAEVnC,IAAIyC;oBACJT,YAAYK,SAAS;;mBAGxB;gBACDrC,IAAIG,UAAUR,KAAK,GAAG,GAAGM,OAAO/yB;;YAGpCpV,OAAO4qC,mBAAmB5qC,OAAO4qC;YACjCnjC,QAAQG;YAER,OAAOH;;QAGX,SAASiiC,qCAAqCmB;YAC1C,IAAIzjC,OAAOyjC,WAAWzjC,MAClBirB,QAAQwY,WAAWxY,OACnBsX,cAAckB,WAAWlB,aACzBC,aAAaiB,WAAWjB,YACxBC,cAAcgB,WAAWhB,aACzBpiC,UAAU,IAAI9L,GAAG+L,WACjB+hC,SAASoB,WAAWpB,QACpBqB,eAAetlC,SAASC,cAAc,WACtCslC,sBAAsBD,aAAa1C,WAAW,OAC9C4C,eAAeH,WAAW7qC,QAC1B8pC,eAAee,WAAWf,cAC1BC,cAAcc,WAAWd;YAE7BC,oBAAoBc,cAAclB,YAAYD,aAAaE;YAE3DmB,aAAa51B,SAAS00B;YACtBkB,aAAa7C,QAAQ4B;YAErBgB,oBAAoB1C,UAAUhW,OAAO,GAAG;YAExCoX;gBACIriC,MAAMA;gBACNgO,QAAQ00B;gBACRzX,OAAOA;gBACPyY,cAAcA;gBACdE,cAAcA;gBACd7C,OAAO4B;eAENj3B,KACG,SAASlL;gBACLojC,aAAaJ,mBAAmBI,aAAaJ;gBAC7CnjC,QAAQG;eAEZH,QAAQK;YAGhB,OAAOL;;QAOX,SAASuiC,oBAAoBhqC,QAAQmoC,OAAO/yB,QAAQy0B;YAChD,QAAQA;cACJ,KAAK;cACL,KAAK;cACL,KAAK;cACL,KAAK;gBACD7pC,OAAOmoC,QAAQ/yB;gBACfpV,OAAOoV,SAAS+yB;gBAChB;;cACJ;gBACInoC,OAAOmoC,QAAQA;gBACfnoC,OAAOoV,SAASA;;YAExB,IAAI8yB,MAAMloC,OAAOooC,WAAW;YAC5B,QAAQyB;cACJ,KAAK;gBAED3B,IAAI+C,UAAU9C,OAAO;gBACrBD,IAAIzqB,OAAO,GAAG;gBACd;;cACJ,KAAK;gBAEDyqB,IAAI+C,UAAU9C,OAAO/yB;gBACrB8yB,IAAIgD,OAAO5tC,KAAK6tC;gBAChB;;cACJ,KAAK;gBAEDjD,IAAI+C,UAAU,GAAG71B;gBACjB8yB,IAAIzqB,MAAM,IAAI;gBACd;;cACJ,KAAK;gBAEDyqB,IAAIgD,OAAO,KAAM5tC,KAAK6tC;gBACtBjD,IAAIzqB,MAAM,IAAI;gBACd;;cACJ,KAAK;gBAEDyqB,IAAIgD,OAAO,KAAM5tC,KAAK6tC;gBACtBjD,IAAI+C,UAAU,IAAI71B;gBAClB;;cACJ,KAAK;gBAED8yB,IAAIgD,OAAO,KAAM5tC,KAAK6tC;gBACtBjD,IAAI+C,UAAU9C,QAAQ/yB;gBACtB8yB,IAAIzqB,OAAO,GAAG;gBACd;;cACJ,KAAK;gBAEDyqB,IAAIgD,QAAQ,KAAM5tC,KAAK6tC;gBACvBjD,IAAI+C,WAAW9C,OAAO;gBACtB;;cACJ;gBACI;;;QAOZ,SAASiD,aAAaC,UAAUC;YAC5B,IAAIx3B,OAAO9X;YAEX,IAAI2E,OAAOO,QAAQmqC,oBAAoBnqC,MAAM;iBACxC;oBACG,IAAI2mC,MAAM,IAAI0D,SACVC,MAAM7qC,OAAO6qC,OAAO7qC,OAAO6qC,IAAIC,kBAAkB9qC,OAAO6qC,MACpD7qC,OAAO+qC,aAAa/qC,OAAO+qC,UAAUD,kBAAkB9qC,OAAO+qC,YAAY;oBAClF,KAAKF,KAAK;wBAAE,MAAMruC,MAAM;;oBACxB0qC,IAAI8D,MAAMH,IAAIC,gBAAgBJ;oBAC9Bv3B,KAAK1M,OAAOikC;oBACZA,WAAWxD;;;YAGnB,KAAKwD,SAAStD,iBAAiBsD,SAASpD,eAAe;gBACnDoD,SAAS1jC,SAAS;oBACd,IAAIikC,YAAY93B,KAAK+3B;oBACrB,IAAID,WAAW;wBACX93B,KAAK+3B,qBAAqB;wBAG1BjmB,WAAW;4BACP,KAAK,IAAInZ,IAAI,GAAG5D,MAAM+iC,UAAUlqC,QAAQ+K,IAAI5D,KAAK4D,KAAK;gCAClDm/B,UAAUn/B;;2BAEf;;;gBAGX4+B,SAASxjC,UAAUyjC;gBACnBtvC,KAAK6vC;;YAET7vC,KAAKqvC,WAAWA;;QAMpBD,aAAa/oC,UAAUypC,SAAS,SAAS1jC,QAAQ4L;YAC7CA,UAAUA;YAEV,IAAIF,OAAO9X,MACP+vC,WAAW/vC,KAAKqvC,SAAStD,cACzBiE,YAAYhwC,KAAKqvC,SAASpD,eAC1BE,QAAQn0B,QAAQm0B,OAChB/yB,SAASpB,QAAQoB,QACjBme,WAAWvf,QAAQuf,UACnBD,YAAYtf,QAAQsf,WACpBwV,YAAY9sC,KAAKoL,QAAQpL,KAAKoL,KAAKlL,SAAS,cAC5CiJ,UAAUiD,OAAOjD,QAAQF,eACzBgnC;YAEJ,IAAIjwC,KAAK6vC,oBAAoB;gBACzB7vC,KAAK6vC,mBAAmBhtC,KAAK;oBAAaiV,KAAKg4B,OAAO1jC,QAAQ4L;;gBAC9D;;YAGJ,IAAIm0B,UAAU/yB,QAAQ;gBAClBA,SAAU42B,YAAY7D,QAAQ4D,YAAa;mBACxC,IAAI32B,WAAW+yB,OAAO;gBACzBA,QAAS4D,WAAW32B,SAAS42B,aAAc;mBACxC;gBACH7D,QAAQ4D;gBACR32B,SAAS42B;;YAEb,IAAIzY,YAAY4U,QAAQ5U,UAAU;gBAC9B4U,QAAQ5U;gBACRne,SAAU42B,YAAY7D,QAAQ4D,YAAa;;YAE/C,IAAIzY,aAAale,SAASke,WAAW;gBACjCle,SAASke;gBACT6U,QAAS4D,WAAW32B,SAAS42B,aAAc;;YAG/CC;gBAAQ9D,OAAOA;gBAAO/yB,QAAQA;eAC9BzZ,GAAG+C,KAAKsV,SAAS,SAASk4B,YAAYC;gBAClCF,IAAIC,cAAcC;;YAGtB,IAAIhnC,YAAY,OAAO;iBAClB;oBACG,IAAIinC,eAAehkC,OAAOujC;oBAC1B9C,qBAAqB/0B,KAAKu3B,UAAUv3B,KAAK1M,MAAM6kC,KAAKnD,UAC/Ch2B,KAAK,SAASzS;wBACX+H,OAAOujC,MAAMtrC;wBACb+rC,iBAAiBhkC,OAAOujC,OAAOvjC,OAAOT;;;mBAG/C,IAAIxC,YAAY,UAAU;gBAC7B4jC,oBAAoB/sC,KAAKqvC,UAAUrvC,KAAKoL,MAAMgB,QAAQ6jC,KAAKnD;;YAE/D,WAAW9sC,KAAKqwC,aAAa,YAAY;gBACrCrwC,KAAKqwC,SAASjkC;;;QAItBzM,GAAGyvC,eAAeA;;ICtYtBzvC,GAAGq6B,iBAAiB,SAASl0B;QACzB;QAEA,SAASwqC,MAAMC;YACX,OAAOA,GAAGpnC,QAAQF,kBAAkB;;QAGxC,SAASunC,SAASD;YACd,OAAOA,GAAGpnC,QAAQF,kBAAkB;;QAGxC,SAASwnC;YACL,OAAO,IAAIlB,QAAQmB,gBAAgB5sC;;QAGvC,SAAS6sC;YACL,IAAI3sC,SAASwF,SAASC,cAAc;YAEpC,OAAOzF,OAAOooC,cAAcpoC,OAAOooC,WAAW;;QAMlD,SAASwE,wBAAwBC;YAE7B,IAAIC,eAAeD,aAAaxrC,MAAM,MAClC3D,OAAOovC,aAAaA,aAAaprC,SAAS,GAAGL,MAAM,KAAK,IACxDyqB,YAAYnwB,GAAG8R,aAAa/P;YAEhCouB,YAAYA,aAAaA,UAAU7mB;YAEnC,QAAQ6mB;cACJ,KAAK;cACL,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;cACL,KAAK;gBACD,OAAO;;;QASnB,SAASihB,cAActU;YACnB,IAAIuU,eAAexnC,SAASC,cAAc,MACtCwnC,gBAAgBC,gBAAgBC;YAEpCH,aAAaI,OAAO3U;YAEpBwU,iBAAiBD,aAAaK;YAC9BF,aAAaH,aAAaM;YAC1BJ,iBAAiBF,aAAaO;YAE9B,IAAIN,eAAehoC,kBAAkBtE,OAAO6sC,SAASH,SAASpoC,eAAe;gBACzE,OAAO;;YAGX,IAAIioC,eAAejoC,kBAAkBtE,OAAO6sC,SAASD,SAAStoC,eAAe;gBACzE,OAAO;;YAIX,IAAIkoC,eAAexsC,OAAO6sC,SAASF,SAAS3xC,GAAGyN,MAAM;gBACjD,OAAO;;YAGX,OAAO;;QAGX,SAASqkC,yBAAyB5F,KAAKpgC;YACnCogC,IAAIlgC,SAAS;gBACTkgC,IAAIlgC,SAAS;gBACbkgC,IAAIhgC,UAAU;gBACdJ,QAAQG,QAAQigC;;YAGpBA,IAAIhgC,UAAU;gBACVggC,IAAIlgC,SAAS;gBACbkgC,IAAIhgC,UAAU;gBACd/F,IAAI,8BAA8B;gBAClC2F,QAAQK,QAAQ+/B,KAAK;;;QAI7B,SAAS6F,gCAAgC1tC,QAAQyH;YAO7CzH,OAAO4qC,kBAAkB;gBACrBnjC,QAAQG,QAAQ5H;;;QAQxB,SAAS2tC,kCAAkC1wB,aAAaxV;YACpD,IAAImmC,aAAatB,MAAMrvB,gBAAgBuvB,SAASvvB;YAEhD,IAAIqvB,MAAMrvB,cAAc;gBACpBwwB,yBAAyBxwB,aAAaxV;mBAErC,IAAI+kC,SAASvvB,cAAc;gBAC5BywB,gCAAgCzwB,aAAaxV;mBAE5C;gBACDA,QAAQK,QAAQmV;gBAChBnb,IAAInG,GAAG8H,OAAO,kDAAkDwZ,YAAY9X,UAAU;;YAG1F,OAAOyoC;;QAKX,SAASC,KAAKnnC,YAAYiX,WAAW3J;YACjC,IAAI85B,cAAc,IAAInyC,GAAG+L,WACrBgd,aAAa,IAAI/oB,GAAGoyC,SAASrnC,YAAY5E,MACzCob,UAAUlJ,QAAQkJ,SAElBwY,SAAS1hB,QAAQ0hB,UAAU,OAAO,OAAO1hB,QAAQ0hB,QACjDsY,sBAAsB;gBAClBrwB,UAAU9V,UAAU;gBACpB8V,UAAUhW,SAAS;gBACnB7F,IAAI,oDAAoD;gBACxDgsC,YAAYhmC,QAAQ6V,WAAW;;YAGvC+G,WAAWupB,gBAAgBn7B,KACvB,SAAS7S;gBAGL,IAAIiuC;oBACI3gC,OAAO;wBACH,OAAO,IAAI5R,GAAG+L,UAAUE;;mBAGhCumC,OAAOzY,SAAS,IAAI/5B,GAAGyyC,KAAK1nC,YAAY5E,OAAOosC,WAC/CG,QAAQ,IAAI1yC,GAAGyvC,aAAa1kC,YAAYsnC;gBAE5C,IAAIL,kCAAkChwB,WAAWmwB,cAAc;oBAC3DK,KAAK5gC,QAAQuF,KACT,SAASq7B;wBACL,IAAItE,cAAcsE,QAAQA,KAAKG;wBAE/BD,MAAMvC,OAAOnuB;4BACT4V,UAAUrW;4BACVoW,WAAWpW;4BACX2sB,aAAaA;4BACb5pC,MAAMA;4BACNwpC,QAAQz1B,QAAQoJ;;uBAIxB,SAASmxB;wBACLzsC,IAAInG,GAAG8H,OAAO,kEAAkE8qC;wBAEhFF,MAAMvC,OAAOnuB;4BACT4V,UAAUrW;4BACVoW,WAAWpW;4BACXjd,MAAMA;4BACNwpC,QAAQz1B,QAAQoJ;;;;eAOpC;gBACItb,IAAI;gBACJgsC,YAAYhmC,QAAQ6V,WAAW;;YAIvC,OAAOmwB;;QAGX,SAASU,yBAAyB/V,KAAKgW,aAAaZ,MAAM3wB,SAASE;YAC/D,IAAIsxB,UAAU,IAAInD,SACdoD,gBAAgB,IAAIhzC,GAAG+L;YAE3BimC,kCAAkCe,SAASC;YAE3C,IAAI5B,cAActU,MAAM;gBACpBiW,QAAQhC,cAAc;;YAG1BgC,QAAQ/C,MAAMlT;YAEdkW,cAAc77B,KACV,SAAS87B;gBACLjB,kCAAkCc,aAAaZ;gBAE/C,IAAIQ,QAAQ,IAAI1yC,GAAGyvC,aAAasD;gBAChCL,MAAMvC,OAAO2C;oBACTlb,UAAUrW;oBACVoW,WAAWpW;oBACXjd,MAAM2sC,wBAAwBnU;oBAC9BgR,QAAQrsB;;eAIhBywB,KAAK/lC;;QAIb,SAAS+mC,+BAA+BpW,KAAKoP,KAAKgG,MAAM3wB;YACpDywB,kCAAkC9F,KAAKgG;YAKvClyC,GAAGksC,KAAK5qC;gBACJs2B,UAAUrW,UAAU;gBACpBoW,WAAWpW,UAAU;;YAGzB2qB,IAAI8D,MAAMlT;;QAWd,SAASqW,YAAYrW,KAAK9a,WAAW3J;YACjC,IAAI65B,OAAO,IAAIlyC,GAAG+L,WACd+V,QAAQzJ,QAAQyJ,OAChBP,UAAUO,QAAQzJ,QAAQkJ,UAAU;YAGxC,IAAIO,SAAS6uB,MAAM3uB,YAAY;gBAG3B,IAAIgvB,qBAAqB;oBAIrB,IAAII,cAActU,SAASgU,sBAAsB;wBAC7CoC,+BAA+BpW,KAAK9a,WAAWkwB,MAAM3wB;2BAEpD;wBACDsxB,yBAAyB/V,KAAK9a,WAAWkwB,MAAM3wB;;uBAGlD;oBACD2xB,+BAA+BpW,KAAK9a,WAAWkwB,MAAM3wB;;mBAIxD,IAAIsvB,SAAS7uB,YAAY;gBAC1B6wB,yBAAyB/V,KAAK9a,WAAWkwB,MAAM3wB;mBAG9C,IAAIywB,kCAAkChwB,WAAWkwB,OAAO;gBACzDlwB,UAAUguB,MAAMlT;;YAGpB,OAAOoV;;QAGXlyC,GAAG6B,OAAOxB;YAWN4hB,UAAU,SAASmxB,eAAepxB,WAAW3J;gBACzC,IAAIrY,GAAGwH,SAAS4rC,gBAAgB;oBAC5BjtC,IAAI;oBACJ,OAAOgtC,YAAYC,eAAepxB,WAAW3J;uBAE5C;oBACDlS,IAAI;oBACJ,OAAO+rC,KAAKkB,eAAepxB,WAAW3J;;;;QAMlDhY,KAAKgzC;QACLhzC,KAAKgzC,SAAS1C,QAAQA;QACtBtwC,KAAKgzC,SAASxC,WAAWA;QACzBxwC,KAAKgzC,SAASjC,gBAAgBA;QAC9B/wC,KAAKgzC,SAASpC,0BAA0BA;;IChT5CjxC,GAAGyyC,OAAO,SAAS1nC,YAAY5E;QAC3B;QAGA,IAAImtC,YAAW,OACXC;YACIC;gBACIzxC,MAAM;gBACNsJ,OAAO;;;QAKnB,SAASooC,kBAAkBC;YACvB,IAAI/wC,SAAS,GACTgxC,MAAM;YAEV,OAAOD,IAAI3tC,SAAS,GAAG;gBACnBpD,UAAUmhC,SAAS4P,IAAInrC,UAAU,GAAG,IAAI,MAAM5G,KAAKgyC,IAAI,GAAGA;gBAC1DD,MAAMA,IAAInrC,UAAU,GAAGmrC,IAAI3tC;gBAC3B4tC,OAAO;;YAGX,OAAOhxC;;QAKX,SAASixC,WAAWC,QAAQ/nC;YACxB,IAAIgoC,YAAYD,QACZE,aAAajoC;YACjB,IAAIgoC,cAAc3vC,WAAW;gBACzB2vC,YAAY;gBACZC,aAAa,IAAI/zC,GAAG+L;;YAGxB/L,GAAGwL,cAAcT,YAAY+oC,WAAW,GAAG38B,KAAK,SAASu8B;gBACrD,IAAIl/B,QAAQ,cAAcvQ,KAAKyvC,MAC3BM;gBAEJ,IAAIx/B,OAAO;oBACP,IAAIA,MAAM,OAAO,KAAK;wBAClBw/B,gBAAgBlQ,SAAS4P,IAAIxrC,MAAM,GAAG,IAAI;wBAC1C0rC,WAAWE,YAAYE,gBAAgB,GAAGD;2BAEzC;wBACDA,WAAW9nC,QAAQ6nC;;uBAGtB;oBACDC,WAAW5nC,QAAQ;;;YAI3B,OAAO4nC;;QAIX,SAASE;YACL,IAAInoC,UAAU,IAAI9L,GAAG+L;YAErB/L,GAAGwL,cAAcT,YAAY,GAAG,GAAGoM,KAAK,SAASu8B;gBAC7C,IAAIA,IAAI/tC,QAAQ,YAAY,GAAG;oBAC3BmG,QAAQK,QAAQ;uBAEf;oBACDynC,aAAaz8B,KAAK,SAAS08B;wBACvB/nC,QAAQG,QAAQ4nC;uBAEpB,SAASxpC;wBACLyB,QAAQK,QAAQ9B;;;;YAK5B,OAAOyB;;QAIX,SAASooC,eAAeC;YACpB,IAAIroC,UAAU,IAAI9L,GAAG+L;YAErB/L,GAAGwL,cAAcT,YAAYopC,YAAY,IAAI,GAAGh9B,KAAK,SAASu8B;gBAC1D5nC,QAAQG,QAAQynC,QAAQ;;YAG5B,OAAO5nC;;QAIX,SAASsoC,iBAAiBD,WAAWE;YACjC,IAAIvoC,UAAU,IAAI9L,GAAG+L;YAErB/L,GAAGwL,cAAcT,YAAYopC,YAAY,IAAI,GAAGh9B,KAAK,SAASu8B;gBAC1D,IAAIW,cAAc;oBACd,OAAOvoC,QAAQG,QAAQwnC,kBAAkBC;uBAExC;oBACD5nC,QAAQG,QAAQ63B,SAAS4P,KAAK;;;YAItC,OAAO5nC;;QAIX,SAASwoC,OAAOH,WAAWI;YACvB,IAAIV,SAASM,YAAY,IACrB9oC,QAAQkpC,aAAa;YAEzB,OAAOv0C,GAAGwL,cAAcT,YAAY8oC,QAAQxoC;;QAIhD,SAASmpC,cAAcC;YACnB,IAAI95B,cACAk5B,SAAS;YAEb,OAAOA,SAAS,MAAMY,OAAO1uC,QAAQ;gBACjC4U,QAAQzX,KAAKuxC,OAAOvsC,MAAM2rC,QAAQA,SAAS;gBAC3CA,UAAU;;YAGd,OAAOl5B;;QAIX,SAAS+5B,aAAaL,cAAcE;YAChC,IAAII,iBAAiB,IACjBC,aAAa50C,GAAG6B,WAAWyxC,UAC3BuB;YAEJ70C,GAAG+C,KAAKwxC,YAAY,SAASvxC,KAAKy3B;gBAC9B,IAAIqa,QAAQra,MAAMvyB,MAAM,GAAG,IACvB0S,KAAKy5B,eAAeZ,kBAAkBqB,SAAShR,SAASgR,OAAO,KAC/DC,gBAAgBH,WAAWjvC,QAAQiV,KACnCo6B,WAAWxrC,SAASyrC;gBAExB,IAAIF,iBAAiB,GAAG;oBACpBvrC,UAAU+pC,SAAS34B,IAAI7Y;oBACvBkzC,eAAe1B,SAAS34B,IAAIvP;oBAC5B2pC,YAAYva,MAAMvyB,MAAMysC,gBAAgBA,iBAAkBM,eAAe;oBACzEJ,KAAKrrC,WAAW6qC,eAAeZ,kBAAkBuB,aAAalR,SAASkR,WAAW;oBAElFJ,WAAWl4B,OAAOq4B,eAAe;;gBAGrC,IAAIH,WAAW7uC,WAAW,GAAG;oBACzB,OAAO;;;YAIf,OAAO8uC;;QAGX70C,GAAG6B,OAAOxB;YAONuR,OAAO;gBACH,IAAIsjC,SAAS,IAAIl1C,GAAG+L,WAChBopC,iBAAiB,SAAS/uC;oBACtBD,IAAInG,GAAG8H,OAAO,mCAAmC1B;oBACjD8uC,OAAO/oC,QAAQ/F;;gBAGvB6tC,gBAAgB98B,KAAK,SAASi+B;oBAC1BjvC,IAAInG,GAAG8H,OAAO,oDAAoDiD,WAAWhJ,SAASoC,YAAY,SAAS4G,WAAWhJ;oBAEtHmyC,eAAekB,YAAYj+B,KAAK,SAASk9B;wBAErCluC,IAAInG,GAAG8H,OAAO,gCAAgCusC,eAAe,WAAW;wBAExED,iBAAiBgB,YAAYf,cAAcl9B,KAAK,SAASk+B;4BAErDlvC,IAAInG,GAAG8H,OAAO,mCAAmCutC;4BAEjDf,OAAOc,YAAYC,eAAel+B,KAAK,SAASs9B;gCAC5C,IAAIF,aAAaC,cAAcC,SAC3Ba,YAAYZ,aAAaL,cAAcE;gCAE3CpuC,IAAI;gCAEJ+uC,OAAOjpC,QAAQqpC;+BAChBH;2BACJA;uBACJA;mBACJA;gBAEH,OAAOD;;;QAKf70C,KAAKgzC;QACLhzC,KAAKgzC,SAASI,oBAAoBA;;IC7MtCzzC,GAAGoyC,WAAW,SAASrnC,YAAY5E;QAC/B;QAEA,SAASovC,eAAeC,YAAYC;YAChC,IAAIC,eAAe,OACfC,uBAAuBvlC,OAAOolC;YAElCx1C,GAAG+C,KAAK4yC,mBAAmB,SAAS3yC,KAAK4yC;gBACrC,IAAIH,kBAAkB9vC,QAAQiwC,0BAA0B,GAAG;oBACvDF,eAAe;oBACf,OAAO;;;YAIf,OAAOA;;QAGX11C,GAAG6B,OAAOxB;YASNiyC,eAAe;gBACX,IAAIn6B,OAAO9X,MACP0oB,aAAa,IAAI/oB,GAAG+L,WACpB8pC,cAAc,OACd9zC,OAAOgJ,WAAWhJ,SAASoC,YAAY,SAAS4G,WAAWhJ;gBAE/DoE,IAAInG,GAAG8H,OAAO,iEAAiE/F;gBAE/EoE,IAAI;gBAEJ,IAAI9F,KAAKy1C,qBAAqB;oBAC1B3vC,IAAI;oBAEJnG,GAAGwL,cAAcT,YAAY,GAAG,GAAGoM,KAAK,SAASu8B;wBAC7C1zC,GAAG+C,KAAKoV,KAAK49B,wBAAwB,SAASzxC,MAAM+G;4BAChD,IAAIkqC,eAAelqC,OAAOqoC,MAAM;gCAG5B,IAAIpvC,SAAS,gBAAgBtE,GAAGkT,kBAAkBwD,cAAc;oCAC5Dm/B,cAAc;oCACd9sB,WAAW9c,QAAQ3H;;gCAGvB,OAAO;;;wBAIf6B,IAAInG,GAAG8H,OAAO,kDAAkD/F,MAAM8zC,cAAc,KAAK;wBAEzF,KAAKA,aAAa;4BACd9sB,WAAW5c;;uBAGnB;wBACIhG,IAAI,iCAAiCpE,OAAO;wBAC5CgnB,WAAW5c;;uBAGd;oBACD4c,WAAW5c;;gBAGf,OAAO4c;;YAWX+sB,mBAAmB;gBACf,IAAIE,WAAWjrC,WAAWxK,MAEtB01C,oBAAoBj2C,GAAG2F,QAAQc,OAAO86B,KAAKlhC,KAAK01C,yBAAyBC,aAAa,GACtFH,cAAc,OACd9zC,OAAOgJ,WAAWhJ,SAASoC,YAAY,SAAS4G,WAAWhJ;gBAE/D,IAAIk0C,mBAAmB;oBACnB,IAAID,aAAa,cAAc;wBAC3BH,cAAc71C,GAAGkT,kBAAkBwD;2BAElC;wBACDm/B,cAAc;;;iBAIrBA,eAAe1vC,IAAIpE,OAAO;gBAE3B,OAAO8zC;;;;IAKnB71C,GAAGoyC,SAAS1rC,UAAUqvC;QAClBG,cAAc;QACdC,aAAa;QACbC,aAAa;QACbC,aAAa;QACbC,gBAAe,YAAY;;ICpG/Bt2C,GAAGw2B,kBAAkB,SAAS/qB,MAAMtF;QAChC;QAMA,SAASowC,iBAAiBC;YACtB,IAAIC,aAAa;YAEjBz2C,GAAG+C,KAAKyzC,QAAQ,SAASE,OAAO3vC;gBAC5B,IAAIA,QAAQ,GAAG;oBACX0vC,aAAa;oBACb,OAAO;;;YAIf,OAAOA;;QAQX,SAASE;YACL,IAAIC,oBAAoB,IAAI52C,GAAG+L;YAE/B,IAAI/L,GAAGoyC,SAAS3mC,MAAMtF,KAAKmsC,gBAAgBn7B,KAAK;gBAC5C,IAAIuf,QAAQ,IAAIkZ,SACZ9S,MAAM93B,OAAO6qC,OAAO7qC,OAAO6qC,IAAIC,kBAAkB9qC,OAAO6qC,MAClD7qC,OAAO+qC,aAAa/qC,OAAO+qC,UAAUD,kBAAkB9qC,OAAO+qC,YAC9D;gBAEV,IAAIjT,KAAK;oBACLpG,MAAMxqB,UAAU;wBACZ/F,IAAI,6DAA6D;wBACjEywC,kBAAkBzqC;;oBAGtBuqB,MAAM1qB,SAAS;wBACX4qC,kBAAkB3qC;4BACdugC,OAAOnsC,KAAKmsC;4BACZ/yB,QAAQpZ,KAAKoZ;;;oBAIrBid,MAAMsZ,MAAMlT,IAAIgT,gBAAgBrkC;uBAE/B;oBACDtF,IAAI,gEAAgE;oBACpEywC,kBAAkBzqC;;eAEvByqC,kBAAkBzqC;YAErB,OAAOyqC;;QASX,SAASC,gBAAgBL,QAAQM;YAC7B,IAAIC;YAEJ/2C,GAAG+C,KAAKyzC,QAAQ,SAASQ,WAAWC;gBAChC,IAAIA,aAAa,GAAG;oBAChB,IAAIC,eAAe,0BAA0BjzC,KAAK+yC,YAC9CG,oBAAoBD,aAAa,GAAGnnC,OAAO,GAAGzG,gBAAgB4tC,aAAa,GAAGhvC,MAAM,IACpFkvC,cAAcN,WAAWK;oBAG7B,QAAQD,aAAa;sBACjB,KAAK;wBACD,IAAIE,cAAcH,YAAY;4BAC1BF,eAAeC;4BACf,OAAO;;wBAEX;;sBACJ,KAAK;wBACD,IAAII,cAAcH,YAAY;4BAC1BF,eAAeC;4BACf,OAAO;;wBAEX;;;;YAKhB,OAAOD;;QAWX12C,KAAKo2B,WAAW,SAAS+f;YACrB,IAAIa,mBAAmB,IAAIr3C,GAAG+L;YAE9B5F,IAAI;YAEJ,IAAIowC,iBAAiBC,SAAS;gBAC1BG,iBAAiBx/B,KAAK,SAAS2/B;oBAC3B,IAAIC,eAAeF,gBAAgBL,QAAQM;oBAE3C,IAAIC,cAAc;wBACdM,iBAAiBlrC,QAAQ4qC;2BAExB;wBACDM,iBAAiBprC;;mBAEtBorC,iBAAiBprC;mBAEnB;gBACDorC,iBAAiBprC;;YAGrB,OAAOorC;;;IC7Hfr3C,GAAG01B,UAAU,SAASja;QAClB;QAEA,IAAIpD;YACAmG,UAAU;YACVD;YACAuJ;YACAG;YACA2N,eAAe,SAASjP;YACxBxgB,KAAK,SAASC,SAASC;;QAG3BrG,GAAG6B,OAAOwW,SAASoD,MAAM;QAEzB,SAAS67B,oBAAoB7kB;YACzB,IAAIzyB,GAAG8G,QAAQ2rB,WAAW;gBACtB,OAAO;;YAGXpa,QAAQlS,IAAI,qCAAqC;;QAGrD,SAASoxC,gBAAgBC,WAAWvrC,SAASoc,UAAUvc;YACnD,IAAI2rC,mBAAmB;YAEvBxrC,UAAUA,WAAWqrC,oBAAoBE;YAEzC,IAAIvrC,SAAS;gBACTjM,GAAG+C,KAAKy0C,WAAW,SAASx0C,KAAKs8B;oBAE7B,IAAIA,SAASvkB,QAAQ,MAAM;wBACvB08B,mBAAmB;wBACnBp/B,QAAQlS,IAAInG,GAAG8H,OAAO,qEAAqE9E,MAAM;2BAEhG,IAAIs8B,SAASv9B,QAAQ,MAAM;wBAC5B01C,mBAAmB;wBACnBp/B,QAAQlS,IAAInG,GAAG8H,OAAO,qEAAqE9E,MAAM;2BAEhG;wBACD;4BACIqV,QAAQud,cAAc0J;4BACtB,OAAO;0BAEX,OAAOoY;4BACHD,mBAAmB;4BACnBp/B,QAAQlS,IAAIuxC,IAAItxC,SAAS;;;oBAIjC,OAAO;;;YAIf0F,QAAQG,YAAYwrC,mBAAmB,YAAY,WAAWD,WAAWnvB;;QAK7EhoB,KAAKw1B,UAAU;YAEX,IAAI8hB,gBAAgB,IAAI33C,GAAG+L,WACvB6rC,0BAA0B,SAASnlB,UAAUxmB,SAASoc;gBAClDkvB,gBAAgB9kB,UAAUxmB,SAASoc,UAAUsvB;eAEjDE,mBAAmB73C,GAAG6B,WAAWwW,UACjCyzB,YAAY,IAAI9rC,GAAG83C,qBACf93C,GAAG6B,OAAOg2C;gBAAmBjsB,YAAYgsB;;YAGjD9L,UAAUiM;YAEV,OAAOJ;;;ICrEf33C,GAAG83C,uBAAuB,SAASr8B;QAC/B;QAEA,IAAIqwB,WACAzzB;YACImG,UAAU;YACVsJ;YACAvJ;YACA0J;gBACI8I,UAAU;gBACV4I,iBAAiB;;YAErB/N,YAAY,SAAS6G,UAAUxmB,SAASoc;YACxCliB,KAAK,SAAS4B,KAAK1B;;QAG3BrG,GAAG6B,OAAOwW,SAASoD;QAEnB,SAASmQ,WAAWhR,IAAIyN,UAAUC;YAC9B,IAAImK,WAAW;YAGf,IAAIpK,SAAS2vB,gBAAgB,MAAM;gBAC/B;oBACIvlB,WAAWzyB,GAAGyR,UAAU4W,SAAS2vB;kBAErC,OAAON;oBACHr/B,QAAQlS,IAAI,uCAAuCuxC,IAAItxC,SAAS;oBAChEkiB,UAAU;;;YAIlBjQ,QAAQuT,WAAW6G,WAAWnK,SAASD;;QAG3CyjB,YAAY9rC,GAAG6B,OAAOxB,MAAM,IAAIL,GAAG06B;YAC/BI,cAAc;YACdC,gBAAe;YACfvT,QAAQ;YACRQ;gBACIvF,KAAK;oBACD,OAAOpK,QAAQmG;;;YAGvBsJ,eAAezP,QAAQyP;YACvB3hB,KAAKkS,QAAQlS;YACbylB,YAAYA;YACZ3D,MAAM5P,QAAQ4P;;QAGlBjoB,GAAG6B,OAAOxB;YACN03C,aAAa;gBACT,IAAIx5B,SAASve,GAAG6B,WAAWwW,QAAQkG;gBAEnClG,QAAQlS,IAAI;gBAEZ2lC,UAAU3N,cAAc,kBACnBK,WAAWjgB,QACXugB,kBACAtB;;;;ICzDjBx9B,GAAG+kB,SAAS,SAAStJ,MAAMtV;QACvB;QAEA,IAAIgS,OAAO9X,MACPohB,uBAAuBhG,KAAKoe,eAC5Boe,kBAAkBx8B,KAAKqe,cACvBC,SAASte,KAAKse,QACdC,cAAcve,KAAKue,aACnBC,iBAAiBxe,KAAKwe,iBAAiB,KACvCie,oBAAoBz8B,KAAKye,aACzBC,cAAc1e,KAAK0e,aACnBC,QAAQ/5B,KAAK83C,gBAAgB18B,KAAK2e;QAGtCp6B,GAAG6B,OAAOxB;YAGNwgB,SAAS7gB,GAAGkT,kBAAkBuD,WAAW2jB,MAAMr0B,SAAS;YAExDqyC,gBAAgB,SAASC,kBAAkBC,kBAAkBC;gBACzD,IAAIpgC,OAAO9X,MACPm4C,cACAC,eAAeF,uBAAuB9sC,OAAO8sC,uBAAuB9sC,OAAO8sC,wBAC3ExvB,aAAa,IAAI/oB,GAAGoyC,SAASqG,cAActyC;gBAG/C,IAAI4iB,WAAW+sB,qBAAqB;oBAEhC91C,GAAG+C,KAAKq3B,OAAO,SAASp3B,KAAK01C;wBACzB,IAAIC,aAAaxgC,KAAKygC;4BAClB5e,aAAaA;4BACb6e,eAAeH,WAAWn4C;4BAC1Bu4C,SAASL,aAAal4C;;wBAG1Bi4C,QAAQt1C;4BACJ6X,MAAM/a,GAAGoN;4BACTrL,MAAMoW,KAAK4gC,SAAST;gCAChBv2C,MAAM22C,WAAW32C;gCACjBxB,MAAMo4C;gCACNG,SAASL,aAAal4C;;4BAE1BkL,MAAM,IAAIzL,GAAG6X,UAAU4gC,cACvBz4C,GAAGgQ,KAAKmI,KAAK6gC,sBAAsB7gC;gCAC/BsJ,sBAAsBA;gCACtBF,SAASm3B,WAAWn3B;gCACpBwY,QAAQA;gCACRx5B,MAAMo4C;gCACNp0C,SAAS01B;gCACTgf,YAAYf;gCACZ/d,aAAaA;gCACbh0B,KAAKA;;;;oBAKjBqyC,QAAQt1C;wBACJ6X,MAAMs9B;wBACNt2C,MAAMu2C;wBACN18B,MAAM68B,aAAa78B;wBACnBnQ,MAAMwsC,kBAAkBQ,eAAe;;uBAG1C;oBACDD,QAAQt1C;wBACJ6X,MAAMs9B;wBACNt2C,MAAMu2C;wBACN18B,MAAM68B,aAAa78B;wBACnBnQ,MAAMgtC;;;gBAId,OAAOD;;YAGXje,eAAe,SAAS1e,MAAM9Z,MAAMgZ,MAAMa,MAAMqU,UAAUnU,SAAS6L,eAAeuxB;gBAC9E,IAAI/gC,OAAO9X,MACPwY,WAAWgD,KAAKoL,cAAepL,KAAKpQ,QAAQoQ,KAAKpQ,KAAKwb,YACtDkyB,gBACAC,aAAa,MACbrpB,mBAAmBmpB,IAAInpB,kBACvB3P,aAAa84B,IAAI94B,YACjB2H,cAAcmxB,IAAInxB,aAClBhM,eAAe/b,GAAGoN;gBAEtBpN,GAAG+C,KAAKoV,KAAKigC,eAAer9B,MAAMhZ,MAAM8Z,OAAO,SAAS7Y,KAAKqZ;oBACzD,IAAIg9B,WAAWh9B,OAAOT,MAClBhB;oBAEJ,IAAIyB,OAAO5Q,gBAAgBzL,GAAG6X,WAAW;wBACrCwhC,YAAY;;oBAGhBz+B,KAAKwF,WAAW5E;wBACZT,MAAMsB,OAAOtB;wBACbhZ,MAAMsa,OAAOta;wBACb6Z,MAAMy9B;wBACNv9B,SAASA;wBACTC,cAAcA;;oBAGlB,IAAIM,OAAO5Q,gBAAgBzL,GAAG6X,WAAW;wBACrCshC,UAAUj2C,KAAK0X;2BAEd;wBACDw+B,aAAax+B;;oBAGjB,IAAIyB,OAAO5Q,MAAM;wBACbskB,iBAAiBnV,IAAIyB,OAAO5Q;wBAC5BwkB,SAAS/sB;4BAAM0X,IAAIA;4BAAIiB,MAAMQ,OAAO5Q;;2BAEnC;wBACD2U,WAAW9D,UAAU1B,IAAI5a,GAAGib,OAAOuC;;;gBAO3C,IAAI47B,eAAe,MAAM;oBACrBp5C,GAAG+C,KAAKo2C,WAAW,SAASn2C,KAAKs2C;wBAC7B,IAAI/6B;4BACAg7B,cAAcn5B,WAAWlE;gCAAUtB,IAAIw+B;+BAAar+B;4BACpDy+B,cAAcp5B,WAAWlE;gCAAUtB,IAAIw+B;+BAAax9B;;wBAKxD2C,OAAOoJ,iBAAiBvH,WAAWlE;4BAAUtB,IAAI0+B;2BAAWv+B;wBAE5DqF,WAAWlD,YAAYo8B,UAAUF;wBACjCrxB,YAAY8B,YAAYyvB,UAAU/6B;;oBAKtC,IAAI46B,UAAUpzC,QAAQ;yBACjB;4BACG,IAAI0zC;4BACJA,MAAM9xB,iBAAiBvH,WAAWlE;gCAAUtB,IAAIw+B;+BAAar+B;4BAC7DgN,YAAY8B,YAAYuvB,YAAYK;;;;;;;IAQ5Dz5C,GAAG6B,OAAO7B,GAAG+kB,OAAOre;QAChBme,YAAY,SAASjK,IAAIkK,OAAOo0B;YAC5B;YAEA,KAAKl5C,GAAGkT,kBAAkBuD,SAAS;gBAC/B,MAAM,IAAIzW,GAAGwB,MAAM;;YAGvB,IAAIk4C,gBAAgB,IAAI15C,GAAG+L,WACvB5F,MAAM+yC,IAAI/yC,KACV0V,OAAOq9B,IAAIn3B,QAAQnH,KACnBwF,aAAa84B,IAAI94B,WAAWlE;gBAAUtB,IAAIA;gBAC1C7Y,OAAOqe,cAAcA,WAAWre,MAChCgZ,OAAOqF,cAAcA,WAAWrF,MAChC4+B;gBACI9f,eAAe/U,MAAM+U;gBACrBC,cAAc;gBACdC,QAAQjV,MAAMiV;gBACdC,aAAalV,MAAMvkB,QAAQ;gBAC3B05B,gBAAgBnV,MAAMvgB;gBACtB2zC,mBAAmB;gBACnB9d;oBAASr4B,MAAM;oBAAIwf,SAASuD,MAAMvD;;eAEtCq4B,SAAS,IAAI55C,GAAG+kB,OAAO40B,gBAAgBxzC;YAE3C,KAAKnG,GAAG+kB,WAAW/kB,GAAGkT,kBAAkBiD,kBAAkB0F,MAAM;gBAC5D69B,cAAcvtC;gBAEdhG,IAAI,mDAAmDyU,KAAK,QACxD,qFAAqF;mBAExF;gBACA5a,GAAGgQ,KAAK;oBAEL,IAAIqM,SAASu9B,OAAOxB,eAAer9B,MAAMhZ,MAAM8Z,MAAM;oBAErD,IAAIQ,UAAUA,OAAO5Q,gBAAgBzL,GAAG6X,WAAW;wBAC/CwE,OAAO5Q,KAAKuM,SAASb,KAAKuiC,cAAcztC,SAASytC,cAAcvtC;2BAE9D;wBACDhG,IAAIyU,KAAK,6BAA6B;wBACtC8+B,cAAcvtC;;mBAEnB9L;;YAGP,OAAOq5C;;QAKXd,sBAAsB,SAASn9B;YAC3B;YAEA,IAAIo9B,gBAAgBp9B,KAAKo9B,eACrB7e,cAAcve,KAAKue,aACnB6f,gBAAgBp+B,KAAKq9B;YAIzB,KAAK9e,gBAAgB6e,eAAe;gBAChC,IAAIgB,kBAAkB,cAAc;oBAChC,OAAO;;gBAEX,OAAOA;;YAIX,KAAKhB,eAAe;gBAChB,OAAO7e;;YAIX,IAAIh6B,GAAG2F,QAAQc,OAAO86B,KAAKvhC,GAAGoyC,SAAS1rC,UAAUqvC,yBAAyB8C,kBAAkB,GAAG;gBAC3F,IAAIA,kBAAkB,cAAc;oBAChC,OAAO74C,GAAGkT,kBAAkBwD,eAAemiC,gBAAgB7e;;gBAG/D,OAAO6e;;YAGX,OAAO7e;;QAIX+e,UAAU,SAASp9B,cAAcm+B;YAC7B;YAEA,IAAIC,aAAap+B,aAAa1J,YAAY,MACtC+nC,cAAcF,wBAAwBv5C,QAAQ,aAC9Cs5C,gBAAgBC,wBAAwBhB,SACxCmB,aAAa,IACbC,YAAYl6C,GAAG8R,aAAa6J,eAC5Bw+B,gBAAgB;YAEpB,IAAIL,wBAAwB/3C,QAAQ+3C,wBAAwB/3C,KAAK8F,OAAO9B,QAAQ;gBAC5Eo0C,gBAAgB,OAAOL,wBAAwB/3C,OAAO;;YAG1D,IAAIg4C,cAAc,GAAG;gBACjBE,aAAat+B,aAAazJ,OAAO,GAAG6nC;gBAEpC,IAAIF,kBAAkBG,aAAa;oBAC/BE,YAAYF,YAAYt0C,MAAM,KAAK;;gBAGvCu0C,cAAcE,gBAAgB,MAAMD;mBAEnC;gBACDD,aAAat+B,eAAew+B;;YAGhC,OAAOF;;QAIX9B,iBAAiB,SAAS/d;YACtB;YAEAA,QAAQp6B,GAAG6B,WAAWu4B;YAEtB,OAAOA,MAAMggB,KAAK,SAASC,GAAGC;gBAC1B,IAAID,EAAE94B,UAAU+4B,EAAE/4B,SAAS;oBACvB,OAAO;;gBAEX,IAAI84B,EAAE94B,UAAU+4B,EAAE/4B,SAAS;oBACvB,QAAQ;;gBAEZ,OAAO;;;QAIfy3B,sBAAsB,SAASv9B,MAAM8+B;YACjC;YAEA,IAAIpiC,OAAO9X,MACPohB,uBAAuBhG,KAAKgG,sBAC5Btb,MAAMsV,KAAKtV,KACXob,UAAU9F,KAAK8F,SACfwY,SAASte,KAAKse,QACdx5B,OAAOkb,KAAKlb,MACZgE,UAAUkX,KAAKlX,SACf00C,aAAax9B,KAAKw9B,YAClB9e,cAAc1e,KAAK0e,eAAeogB,WAAWh6C,SAAS,gBAAgBA,SAAS,cAC/Em5C,gBAAgB,IAAI15C,GAAG+L,WACvByuC,iBAAiB,IAAIx6C,GAAGq6B,eAAel0B,MACvC9B,SAASwF,SAASC,cAAc;YAEpC3D,IAAI,+CAA+Co0C,WAAWx4C;YAE9Dy4C,eAAev4B,SAASs4B,YAAYl2C;gBAASkd,SAASA;gBAASwY,QAAQA;gBAAQtY,sBAAsBA;eAAuBtK,KAAK;gBAC7H,IAAIsjC,qBAAqBp2C,OAAOI,UAAUlE,MAAMgE,UAC5Cm2C,gBAAgB;oBACZv0C,IAAI,2CAA2Co0C,WAAWx4C;oBAC1D,IAAI0J,OAAOzL,GAAGwE,cAAci2C;oBAC5Bf,cAAcztC,QAAQR;;gBAG9B,IAAI0uB,aAAa;oBACbhiB,KAAKwiC,kBAAkBJ,YAAYE,oBAAoBt0C,KAAKgR,KAAK,SAASyjC;wBACtEH,qBAAqBG;wBACrBF;uBAEJ;wBACIv0C,IAAI,yFAAyF;wBAC7Fu0C;;uBAGH;oBACDA;;eAEL;gBACCv0C,IAAI,mDAAmDo0C,WAAWx4C,MAAM;gBACxE23C,cAAcvtC,QAAQ8sC;;YAG1B,OAAOS;;QAIXiB,mBAAmB,SAASE,eAAeJ,oBAAoBt0C;YAC3D;YAEA,IAAI20C,SAAS,IAAIjvC,cACbkvC,kBAAkB,IAAI/6C,GAAG+L,WACzBivC,uBAAuB;YAE3BF,OAAO9uC,SAAS;gBACZgvC,uBAAuBF,OAAOn4C;gBAC9Bo4C,gBAAgB9uC,QAAQjM,GAAGi7C,aAAajM,QAAQgM,sBAAsBP;;YAG1EK,OAAO5uC,UAAU;gBACb/F,IAAI,qBAAqB00C,cAAc94C,OAAO,4DAA4D;gBAC1Gg5C,gBAAgB5uC;;YAGpB2uC,OAAOI,cAAcL;YAErB,OAAOE;;QAGXI,gBAAgB,SAASz2C;YACrB;YAEA,IAAIE,YAAYa,YAAYd,aAAaa;YAGzC,IAAId,QAAQgB,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cf,aAAagB,KAAKlB,QAAQgB,MAAM,KAAK;mBAEpC;gBACDd,aAAaiB,UAAUnB,QAAQgB,MAAM,KAAK;;YAI9CD,aAAaf,QAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBf,cAAc,IAAImB,YAAYlB,WAAWmB;YACzCP,WAAW,IAAIQ,WAAWrB;YAC1B3E,GAAG+C,KAAK6B,YAAY,SAAS5B,KAAKiD;gBAC9BT,SAASxC,OAAOiD,UAAUC,WAAW;;YAGzC,OAAO7F,KAAK+6C,YAAYz2C,aAAac;;QAGzC21C,aAAa,SAASt2C,MAAMR;YACxB;YAEA,IAAIS,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;YAErC,IAAIK,aAAa;gBACbA,YAAYC,OAAOP;gBACnB,OAAOM,YAAYE,QAAQhB;mBAE1B;gBACD,OAAO,IAAIiB,OAAMT;oBAAQvE,MAAM+D;;;;;IChZ3CtE,GAAGi7C,eAAe;QAGjB,IAAIA;QAEDA,aAAaI,UAAU,qBACF,qBACA,qBACA,qBACA;QAErBJ,aAAaK,WAAW,SAAS1xC;YAE7B,IAAI2xC,SAAS,IACTC,MAAMC,MAAMC,OAAO,IACnBC,MAAMC,MAAMC,MAAMC,OAAO,IACzBhrC,IAAI;YAER,GAAG;gBACC0qC,OAAO5xC,MAAMkH;gBACb2qC,OAAO7xC,MAAMkH;gBACb4qC,OAAO9xC,MAAMkH;gBAEb6qC,OAAOH,QAAQ;gBACfI,QAASJ,OAAO,MAAM,IAAMC,QAAQ;gBACpCI,QAASJ,OAAO,OAAO,IAAMC,QAAQ;gBACrCI,OAAOJ,OAAO;gBAEd,IAAIK,MAAMN,OAAO;oBACdI,OAAOC,OAAO;uBACV,IAAIC,MAAML,OAAO;oBACrBI,OAAO;;gBAGVP,SAASA,SACNl7C,KAAKg7C,QAAQtrC,OAAO4rC,QACpBt7C,KAAKg7C,QAAQtrC,OAAO6rC,QACpBv7C,KAAKg7C,QAAQtrC,OAAO8rC,QACpBx7C,KAAKg7C,QAAQtrC,OAAO+rC;gBACvBN,OAAOC,OAAOC,OAAO;gBACrBC,OAAOC,OAAOC,OAAOC,OAAO;qBACvBhrC,IAAIlH,MAAM7D;YAEnB,OAAOw1C;;QAGXN,aAAajM,UAAU,SAASgN,gBAAgBC;YAE5C,IAAIC,uBAAuB;YAE3B,KAAKF,eAAexnC,MAAM0nC,uBAC1B;gBACC,OAAOD;;YAGR,IAAIE,WAAW97C,KAAK+7C,SAASJ,eAAez5C,QAAQ25C,sBAAsB;YAC1E,IAAIG,WAAWh8C,KAAKi8C,eAAeH;YAEnC,IAAIzlB,QAAQr2B,KAAKk8C,iBAAiBN,mBAAmBI;YAErD,OAAOH,uBAAuB77C,KAAKi7C,SAAS5kB;;QAKhDukB,aAAasB,mBAAmB,SAASN,mBAAmBI;YAEpD,IAAIG,YAAYn8C,KAAKo8C,aAAaJ,WAC9BK,gBAAgBr8C,KAAKs8C,WAAWV,mBAAmBO,YACnDI,UAAU,IAAI52C,WAAW02C;YAE7B,OAAOE;;QAIf3B,aAAawB,eAAe,SAASJ;YAE7B,IAAIQ;YACJ,KAAK,IAAIC,IAAI,GAAGA,IAAIT,SAASt2C,QAAQ+2C,KACrC;gBACID,MAAMR,SAASS;gBACf,IAAID,IAAI,MAAM,MAAMA,IAAI,MAAM,KAC9B;oBACI,OAAOA;;;YAGf;;QAIR5B,aAAa0B,aAAa,SAASV,mBAAmBO;YAE9C,IAAIO,YAAYd,kBAAkB15C,QAAQ,2BAA2B,KACjEy6C,MAAM38C,KAAK+7C,SAASW,YACpBE,gBAAgBD,IAAIr3C,QAAQ,KAAI,IAChCu3C,MAAMF,IAAI90C,MAAM,GAAG+0C,gBACnBE,MAAMH,IAAI90C,MAAM+0C,gBAChBG,QAAQF;YAEZE,QAAQA,MAAMhtC,OAAOosC;YACrBY,QAAQA,MAAMhtC,OAAO+sC;YACtB,OAAOC;;QAKdnC,aAAaqB,iBAAiB,SAASe;YAEnC,IAAIC,OAAO,GACPjB;YAEJ,OAAO,GACP;gBACI,IAAIgB,cAAcC,SAAS,MAAMD,cAAcC,OAAO,MAAM,KAAI;oBAAC;;gBACjE,IAAID,cAAcC,SAAS,MAAMD,cAAcC,OAAO,MAAM,KAC5D;oBACIA,QAAQ;uBAGZ;oBACI,IAAIv3C,SAASs3C,cAAcC,OAAO,KAAK,MAAMD,cAAcC,OAAO,IAC9DC,WAAWD,OAAOv3C,SAAS,GAC3B82C,MAAMQ,cAAcn1C,MAAMo1C,MAAMC;oBACpClB,SAASn5C,KAAK25C;oBACdS,OAAOC;;gBAEX,IAAID,OAAOD,cAAct3C,QAAO;oBAAC;;;YAGrC,OAAOs2C;;QAKXpB,aAAamB,WAAW,SAASxyC;YAE7B,IAAI2xC,SAAS,IACTC,MAAMC,MAAMC,OAAO,IACnBC,MAAMC,MAAMC,MAAMC,OAAO,IACzBhrC,IAAI,GACJksC;YAGJ,IAAIQ,aAAa;YACjB,IAAIA,WAAWv5C,KAAK2F,QAAQ;gBACxB,MAAM,IAAIpI,MAAM,8DACZ;;YAERoI,QAAQA,MAAMrH,QAAQ,uBAAuB;YAE7C,GAAG;gBACCo5C,OAAOt7C,KAAKg7C,QAAQ11C,QAAQiE,MAAMmG,OAAOe;gBACzC8qC,OAAOv7C,KAAKg7C,QAAQ11C,QAAQiE,MAAMmG,OAAOe;gBACzC+qC,OAAOx7C,KAAKg7C,QAAQ11C,QAAQiE,MAAMmG,OAAOe;gBACzCgrC,OAAOz7C,KAAKg7C,QAAQ11C,QAAQiE,MAAMmG,OAAOe;gBAEzC0qC,OAAQG,QAAQ,IAAMC,QAAQ;gBAC9BH,QAASG,OAAO,OAAO,IAAMC,QAAQ;gBACrCH,QAASG,OAAO,MAAM,IAAKC;gBAE3BkB,IAAI95C,KAAKs4C;gBAET,IAAIK,QAAQ,IAAI;oBACbmB,IAAI95C,KAAKu4C;;gBAEZ,IAAIK,QAAQ,IAAI;oBACbkB,IAAI95C,KAAKw4C;;gBAGZF,OAAOC,OAAOC,OAAO;gBACrBC,OAAOC,OAAOC,OAAOC,OAAO;qBAEvBhrC,IAAIlH,MAAM7D;YAEnB,OAAOi3C;;QAIX,OAAO/B;;IC7KXj7C,GAAGw6B,gBAAgB,SAAS/qB,UAAUuT;QAClC;QAEA,IAAIy6B,sBACAC,cAAc,GACdC,YAAY,GAEZC,kBAAkB,GAClBC,iBAAiB,GACjBC,gBAAgB,SAASryB,QAAQC;YAC7B,IAAID,WAAWmyB,kBAAkBlyB,UAAUmyB,eAAe;gBACtDpuC,SAASgc,QAAQC;;YAGrBkyB,iBAAiBnyB;YACjBoyB,gBAAgBnyB;WAQpBqyB,mBAAmB,SAAS3qB,QAAQ4qB;YAChC,IAAIC,OAAO;YAEXj+C,GAAG+C,KAAKqwB,QAAQ,SAASpwB,KAAKk7C;gBAC1B,IAAIl+C,GAAG2F,QAAQq4C,WAAWE,aAAa,GAAG;oBACtCD,OAAO;oBACP,OAAO;;;YAIf,OAAOA;WAGXnyB,WAAW,SAASlR;YAChBujC,oBAAoBvjC,KAAK,IAAI;mBACtB6iC,gBAAgB7iC;WAG3ByY,gBAAgB,SAASF,YAAYC,QAAQ4qB;YACzC,IAAI5qB,OAAOrtB,WAAW,KAAKg4C,iBAAiB3qB,QAAQ4qB,YAAY;gBAC5DF,cAAcH,WAAWA;gBACzBt9C,KAAK6Z;;WAIbkkC,QAAQ,SAASxjC;YACb,IAAIgB,OAAOoH,QAAQpI;YAGnB,IAAIgB,OAAO,GAAG;gBACVuiC,oBAAoBvjC,IAAI,GAAGgB;gBAC3B6hC,gBAAgB7iC;oBAAO6Q,QAAQ;oBAAGC,OAAO9P;;;WAYjDuiC,sBAAsB,SAASvjC,IAAIyjC,WAAWC;YAC1C,IAAIC,YAAYd,gBAAgB7iC,MAAM6iC,gBAAgB7iC,IAAI6Q,SAAS,GAC/D+yB,WAAWf,gBAAgB7iC,MAAM6iC,gBAAgB7iC,IAAI8Q,QAAQ;YAEjE,IAAI2yB,eAAe,KAAKC,cAAc,GAAG;gBACrCZ,eAAea;gBACfZ,aAAaa;mBAEZ;gBACD,IAAIH,WAAW;oBACXX,eAAeW,YAAYE;;gBAE/B,IAAID,UAAU;oBACVX,aAAaW,WAAWE;;;YAIhCV,cAAcJ,aAAaC;;QAGnC39C,GAAG6B,OAAOxB;YAENgzB,eAAeA;YAGfpX,gBAAgB,SAASrB,IAAI4B,WAAWD;gBACpC,IAAIA,cAAcvc,GAAGib,OAAOyC,YAAYnB,cAAcvc,GAAGib,OAAOuC,UAAU;oBACtEsO,SAASlR;uBAER,IAAI2B,cAAcvc,GAAGib,OAAOS,YAAY;oBACzC0iC,MAAMxjC;;;YAKdmZ,sBAAsB,SAASnZ,IAAI6Q,QAAQC;gBACvCyyB,oBAAoBvjC,IAAI6Q,QAAQC;gBAChC+xB,gBAAgB7iC;oBAAO6Q,QAAQA;oBAAQC,OAAOA;;;YAIlDsK,WAAW,SAASpb;gBAChBwjC,MAAMxjC;;YAGVV,OAAO;gBACHujC;gBACAC,cAAc;gBACdC,YAAY;;;;ICzHxB39C,GAAGwoB,eAAe,SAAStQ;QACvB;QAEA,IAAIG,SAASomC;QAEbpmC;YACIoQ,eAAe;YACfrB;gBACIjhB,KAAK,SAASC,SAASC;gBACvBsiB,eAAe,SAASld;;;QAIhC,SAASizC,QAAQp3C;YACb,OAAOA,KAAK/G,QACR+G,KAAK/G,KAAKoF,QAAQ,cAAc;;QAGxC,SAASg5C;YACLF,qBAAqBz+C,GAAGqY,QAAQoQ,eAAenoB,OAAO,SAAS,SAASk1B;gBACpE,IAAIopB,gBAAgBppB,MAAMopB;gBAE1B,IAAIA,eAAe;oBACf5+C,GAAG+C,KAAK67C,cAAcp0C,OAAO,SAASxH,KAAKsE;wBACvC,IAAIo3C,QAAQp3C,OAAO;4BACf,IAAImE,OAAOnE,KAAKu3C;4BAChBxmC,QAAQ+O,UAAUuB,cAAcld;;;;;;QAOpD,SAASqzC;YACL,IAAIL,oBAAoB;gBACpBA;;;QAIRz+C,GAAG6B,OAAOwW,SAASH;QACnBymC;QAEA3+C,GAAG6B,OAAOxB;YACN6Z,OAAO;gBACH4kC;;;;ICpCZ9+C,GAAGwwB,cAAc,SAASnY,SAAS0mC,aAAa54C;QAC5C;QACA,IAAIgS,OAAQ9X,MACRu5B,kBAAkBvhB,QAAQuhB,iBAC1BolB,SAAS3mC,QAAQpY,SACjB0wB,aAAatY,QAAQsY;QAGzB3wB,GAAG6B,OAAOxB;YAINwwB,aAAa;YAIbD,eAAeD;YAGfF,gBAAgB;YAGhBC,uBAAuB;gBAEnB,IAAIsuB,UAAU,MAAM;oBAChB,OAAO;;gBAGX,OAAO7mC,KAAK8mC,UAAUD;;;QAK9B,SAASE,qBAAqBF;YAC1B,IAAIA,OAAO96C,aAAa,WAAW;gBAC/BiU,KAAK0Y,cAAcmuB,OAAO96C,aAAa;;;QAM/C,SAASi7C,aAAaH,QAAQI;YAC1B,IAAIJ,OAAOK,kBAAkBL,OAAOK,iBAAiB;gBACjDl5C,IAAI,0DAA0D;gBAC9Di5C;mBAEC;gBACD,OAAO;;;QAKf,SAASE,oBAAoBN;YACzB,IAAII,eAAeJ,OAAOO;YAG1Bv/C,GAAGg/C,QAAQ1+C,OAAO,UAAU,SAASk1B;gBACjCA,QAAQA,SAASxwB,OAAOwwB;gBAExB,IAAIA,MAAMvmB,gBAAgB;oBACtBumB,MAAMvmB;uBAEL;oBACDumB,MAAMrmB,cAAc;;gBAGxBgwC,aAAaH,QAAQI,iBAAiBL;;YAK1CC,OAAOO,SAAS;gBACZJ,aAAaH,QAAQI,iBAAiBL;;;QAM9C,SAASS,gBAAgBR;YACrB,IAAIA,QAAQ;gBACR,IAAIh/C,GAAGwH,SAASw3C,SAAS;oBACrBA,SAASn1C,SAASg9B,eAAemY;;gBAGrC,IAAIA,QAAQ;oBACR74C,IAAI;oBACJ+4C,qBAAqBF;oBACrBplB,mBAAmB0lB,oBAAoBN;;;YAI/C,OAAOA;;QAGXA,SAASQ,gBAAgBR;QACzB3+C,KAAKowB,mBAAmBuuB;;IAG5Bh/C,GAAG6B,OAAO7B,GAAGwwB,YAAY9pB;QAGrBu4C,WAAW,SAAS3tC;YAChB;YACA,IAAIf,UACAkvC,oBAAoB,SAASl/C;gBACzB,IAAIm/C,oBACA,UACA,SACA,SACA;gBAGJ,OAAO1/C,GAAG2F,QAAQ+5C,iBAAiBn/C,KAAK+I,iBAAiB;eAE7Dq2C,kBAAkB,SAASp/C;gBACvB,OAAOP,GAAG2F,UAAS,YAAY,WAAUpF,KAAK+I,kBAAkB;eAEpEs2C,cAAc,SAAShP;gBACnB,IAAI+O,gBAAgB/O,GAAGrwC,UAAUqwC,GAAGiP,SAAS;oBACzC,OAAO;;gBAGX,OAAOjP,GAAGv8B,YAAYu8B,GAAGrwC,KAAK+I,kBAAkB;eAEpDw2C,cAAc,SAASC;gBACnB,IAAIh5C,QAAQ;gBAEZ/G,GAAG+C,KAAK/C,GAAG+/C,QAAQ38C,YAAY,SAASJ,KAAKK;oBACzC,IAAIA,MAAMmG,QAAQF,kBAAkB,YAAYjG,MAAM28C,UAAU;wBAC5Dj5C,QAAQ1D,MAAM0D;wBACd,OAAO;;;gBAIf,OAAOA;;YAGf/G,GAAG+C,KAAKuO,KAAK2uC,UAAU,SAASj9C,KAAK4tC;gBACjC,KAAK5wC,GAAGiJ,QAAQ2nC,IAAI,SAASA,GAAGpnC,QAAQF,kBAAkB,eACtDm2C,kBAAkB7O,GAAGrwC,UACpBq/C,YAAYhP,KAAK;oBAElBrgC,IAAIqgC,GAAG7uC,QAAQ6uC,GAAG7pC;uBAEjB,IAAI6pC,GAAGpnC,QAAQF,kBAAkB,aAAas2C,YAAYhP,KAAK;oBAChE,IAAI7pC,QAAQ+4C,YAAYlP;oBAExB,IAAI7pC,UAAU,MAAM;wBAChBwJ,IAAIqgC,GAAG7uC,QAAQgF;;;;YAK3B,OAAOwJ;;;ICzJfvQ,GAAGykC,cAAczkC,GAAGykC;IACpBzkC,GAAGykC,YAAY2B,oBAAoB,SAAS/tB,SAAS+mB;QACjD;QAEA,IAAIxP,UAAUvvB,MACVigB,UAAU8e,MAAM9e,SAChBiD,UAAU6b,MAAM7b,SAChBpd,MAAMi5B,MAAMj5B;QAKhB,SAAS+5C,qBAAqBtlC,IAAIgsB;YAG9B,IAAInU,UAAU0tB,KAAKC;YAGnB;gBAEID,MAAMvZ,OAAOa,mBAAmBb,OAAOyZ,cAAcx2C;gBACrDu2C,YAAYD,IAAIjZ,KAAK33B;gBAErBpJ,IAAI;gBACJA,IAAI,iBAAiBi6C;gBAErB,IAAIA,aAAaA,UAAU5rC,MAAM,WAAW;oBACxC4rC,YAAYD,IAAIjZ,KAAK5jC,WAAWA,WAAWg9C;;gBAG/C7tB,WAAW7C,QAAQwX,mBAAmBgZ;cAE1C,OAAO/1C;gBACHlE,IAAI,0DAA0DkE,MAAMjE,UAAU,KAAK;gBACnFqsB;oBAAYxmB,SAAS;;;YAGzB,OAAOwmB;;QAMX,SAAS8tB,WAAW3lC,IAAIgsB;YACpB,IAAIroB,SAASlG,QAAQ0P,YAAYtF,IAAI7H,KACjC4M,SAASnP,QAAQmP,OAAOle,kBAAkB,QAAQ,QAAQ,QAC1DkV,WAAWnG,QAAQ2P,cAAcvF,IAAI7H,KACrC7Y,OAAOue,QAAQ1F;YAEnB2D,OAAOlG,QAAQwP,YAAYtE,QAAQ3I;YACnC2D,OAAOlG,QAAQgf,iBAAiBt1B;YAEhC,OAAO6tB,QAAQ+X;gBACXngB,QAAQA;gBACRhJ,UAAUA;gBACVD,QAAQA;gBACRiZ,cAAcnf,QAAQmf;gBACtBoQ,YAAYhB,OAAO7kC;;;QAI3B1B,KAAK8jC,aAAa,SAASvpB;YACvB,IAAIhR,QAAQgmB,QAAQhW,SAASgB,KACzBgsB,SAAShX,QAAQ8X,cAAc9sB,KAC/B9O,UAAU,IAAI9L,GAAG+L,WACjBuF;YAEJA,OAAOivC,WAAW3lC,IAAIgsB;YACtBt1B,KAAKE,YAAY5H;YAEjBgmB,QAAQ2X,iBAAiBX,QAAQ,SAAS4Z;gBACtCr6C,IAAI;gBAEJ,IAAIssB,WAAW+tB,sBAAsBA,sBAAsBN,qBAAqBtlC,IAAIgsB;gBAEpFhX,QAAQ0X,iBAAiB1sB;gBAGzB,KAAKvC,QAAQ4P,KAAK8I,UAAU;oBACxB/wB,GAAG4mC,QAAQxlC;;gBAGf,IAAIqxB,SAASxmB,SAAS;oBAClBH,QAAQG,QAAQwmB;uBAEf;oBACD3mB,QAAQK,QAAQsmB;;;YAIxBtsB,IAAI,gCAAgCyU;YACpCtJ,KAAKiuC;YACLv/C,GAAGsR,MAAMlQ;YAET,OAAO0K;;QAGX9L,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGomC;YACnB/tB;gBACIouB,QAAQpuB,QAAQ4P,KAAK8I;gBACrBjG,WAAWzS,QAAQyS;;YAGvBsU;gBACItT,UAAUzT,QAAQyT;gBAClBxL,SAASA;gBACTiD,SAASA;gBACTpd,KAAKA;;;;IC5GjBnG,GAAGykC,cAAczkC,GAAGykC;IACpBzkC,GAAGykC,YAAYqD,mBAAmB,SAASrsB,MAAM2jB;QAC7C;QAEA,IAAIxP,UAAUvvB,MACVigB,UAAU8e,MAAM9e,SAChB0C,UAAUoc,MAAMpc,SAChBO,UAAU6b,MAAM7b,SAChBpd,MAAMi5B,MAAMj5B,KACZs6C,YAAYhlC,KAAK6b,kBAAkB7b,KAAK+b,cAExCkpB,4BAA4B,SAAS9lC,IAAI2D,QAAQgO;YAC7C,IAAI3Q,OAAOoH,QAAQpI,KACf7Y,OAAOue,QAAQ1F;YAEnB,KAAKa,KAAK8b,mBAAmB;gBACzBhZ,OAAO9C,KAAK/F,SAASqjB,WAAWrM,aAAaH,UAAU2d;gBACvD3rB,OAAO9C,KAAK/F,SAASqjB,WAAWC,kBAAkBzM,UAAUvhB;gBAC5DuT,OAAO9C,KAAK/F,SAASqjB,WAAWE,aAAa1M,UAAU3Q;gBACvD2C,OAAO9C,KAAK/F,SAASqjB,WAAWI,cAAc5M,UAAU4d;gBACxD5rB,OAAO9C,KAAKic,qBAAqB9b;;YAOrC,IAAI6kC,cAAchlC,KAAK8b,mBAAmB;gBACtChZ,OAAO9C,KAAK4b,iBAAiBt1B;;WAIrC4+C,yBAAyB,IAAI3gD,GAAGykC,YAAYmc;YACxC34B,MAAMxM,KAAKwM;YACXzJ,UAAU/C,KAAK/F,SAASzJ,QAAQuS;YAChCyG,SAASxJ,KAAK/F,SAASzJ,QAAQgZ;YAC/BoU,aAAa5d,KAAK/F,SAASzJ,QAAQotB;YACnClzB,KAAKA;YACLqhB,QAAQ/L,KAAK/F,SAASzJ,QAAQub;YAC9BjJ,QAAQ9C,KAAK/F,SAASzJ,QAAQsS;YAGlCsiC,iCAAiC,SAASjmC,IAAIlG;YAC1C,IAAI5I,UAAU,IAAI9L,GAAG+L;YAErB2I,IAAIyoB,qBAAqB;gBACrB,IAAIzoB,IAAIipB,eAAe,GAAG;oBACtB,IAAIh7B,SAASm+C,wBAAwBlmC,IAAIlG;oBAEzC,IAAI/R,OAAOsJ,SAAS;wBAChBH,QAAQG,QAAQtJ,OAAO8vB,UAAU/d;2BAEhC;wBACD5I,QAAQK,QAAQxJ,OAAO8vB,UAAU/d;;;;YAK7C,OAAO5I;WAGXi1C,0BAA0B,SAASnmC;YAC/B,IAAI2D,SAAS9C,KAAKsM,YAAYtF,IAAI7H,KAC9B7Y,OAAOue,QAAQ1F,KACfgB,OAAOoH,QAAQpI;YAEnB2D,OAAO9C,KAAKoM,YAAYtE,QAAQ3I;YAChC2D,OAAO9C,KAAK4b,iBAAiBt1B;YAC7Bwc,OAAO9C,KAAKic,qBAAqB9b;YACjC2C,OAAO9C,KAAK/F,SAASqjB,WAAWI,cAAcvJ,QAAQuS,gBAAgBvnB;YAEtE,OAAO2D;WAGXyiC,wBAAwB,SAAStsC,KAAK+d;YAClC,OAAOzyB,GAAG2F,UAAS,KAAK,KAAK,KAAK,KAAK,OAAM+O,IAAIuG,UAAU,KACtDQ,KAAKgc,uBAAuBhF,SAASxmB,WACtCwmB,SAASvY;WAGjB4mC,0BAA0B,SAASlmC,IAAIlG;YACnC,IAAI+d;YAEJtsB,IAAI,wCAAwCyU;YAC5CzU,IAAI,oBAAoBuO,IAAIsjC;YAE5BvlB,WAAWwuB,cAAc,MAAMvsC;YAE/B;gBACIzI,UAAU+0C,sBAAsBtsC,KAAK+d;gBACrCA,UAAUA;;WAKlBwuB,gBAAgB,SAAS/2C,QAAQwK;YAC7B,IAAI+d;YAEJ;gBACItsB,IAAInG,GAAG8H,OAAO,6CAA6C4M,IAAIuG,QAAQvG,IAAIsjC;gBAC3EvlB,WAAWzyB,GAAGyR,UAAUiD,IAAIsjC;cAEhC,OAAO3tC;gBACHH,UAAUuR,KAAKgc,sBAAsBtxB,IAAI,uDAAuDkE,MAAMjE,UAAU,KAAK;;YAGzH,OAAOqsB;WAGXyuB,4BAA4B,SAAStmC;YACjC,IAAI9O,UAAU,IAAI9L,GAAG+L;YAErB40C,uBAAuBQ,SACfvmC,IACAgV,QAAQ+Z,WAAW/uB,KACnBmmC,wBAAwBnmC,KACxBa,KAAKqM,cAAcrF,IAAI7H,KAE1BzD,KAAK,SAASzC;gBACX5I,QAAQG,QAAQg1C,cAAc,OAAOvsC,MAAMA;eAC5C,SAASA;gBACR5I,QAAQK,QAAQ80C,cAAc,OAAOvsC,MAAMA;;YAGnD,OAAO5I;WAGXs1C,8BAA8B,SAASC;YACnC,IAAIt2C,aAAas2C,mBAAmBt2C;YACpC,IAAI6P,KAAKymC,mBAAmBzmC;YAC5B,IAAIlG,MAAM2sC,mBAAmB3sC;YAC7B,IAAI4sC,eAAeD,mBAAmBC;YACtC,IAAIC,eAAeF,mBAAmBE;YACtC,IAAIC,gBAAgBH,mBAAmB9iC;YACvC,IAAIkjC,oBAAoBH,aAAa/iC;YACrC,IAAIA;YAEJ,IAAIpN,WAAWsvC,YAAY,IAAIz2C,aAAa,MACxCwd,SAAS85B,aAAa95B,UAAU/L,KAAK+L,QACrChJ,WAAW8iC,aAAa9iC,YAAY/C,KAAKuM,cAAcvF,IAAI7H,KAC3D7Y,OAAOue,QAAQ1F,KACfgB,OAAOoH,QAAQpI;YAEnB,IAAIa,KAAK8b,mBAAmB;gBACxBhZ,SAASve,GAAG6B,WAAW0/C;gBACvBvhD,GAAG6B,OAAO0c,QAAQkjC;mBAEjB;gBACDljC,SAASve,GAAG6B,WAAW0/C;gBACvBvhD,GAAG6B,OAAO0c,QAAQkjC;gBAClBzhD,GAAG6B,OAAO0c,QAAQijC;gBAElBjjC,OAAO9C,KAAKoM,YAAYtE,QAAQ3I;gBAChC2D,OAAO9C,KAAK4b,iBAAiBt1B;gBAE7B,IAAI0+C,WAAW;oBACXliC,OAAO9C,KAAKic,qBAAqB9b;uBAEhC,KAAKH,KAAK+b,cAAc;oBACzBjZ,OAAO9C,KAAKqP,aAAa/oB;;;YAKjC,KAAK0Z,KAAK+b,cAAc;gBACpBhZ,WAAWxe,GAAGsQ,QAAQiO,QAAQC;;YAGlC9J,IAAI4oB,KAAK9V,QAAQhJ,UAAU;YAE3B,IAAI/C,KAAKwM,KAAK8I,YAAYtV,KAAKwM,KAAK0R,iBAAiB;gBACjDjlB,IAAIC,kBAAkB;;YAG1B,IAAI8rC,WAAW;gBACX,IAAIhlC,KAAK+b,cAAc;oBACnBx3B,GAAGkR,aAAaqN,QAAQpN;;gBAG5BA,SAAS9L,OAAOoW,KAAKqP,WAAW/f;gBAChC,OAAOoG;;YAGX,OAAOpG;WAGX22C,mBAAmB,SAASC;YACxB,IAAIC,kBAAkBD,eAAeC;YACrC,IAAIhnC,KAAK+mC,eAAe/mC;YACxB,IAAIlG,MAAMitC,eAAejtC;YAEzB,IAAIktC,iBAAiB;gBACjB5hD,GAAG+C,KAAK6+C,iBAAiB,SAASC,YAAYC;oBAC1CptC,IAAIspB,iBAAiB6jB,YAAYC;;mBAGpC;gBACD,IAAIC,eAAetmC,KAAKqM,cAAcrF,IAAI7H,KACtC7P,aAAa6kB,QAAQ7N,QAAQnH;gBAEjClG,IAAIspB,iBAAiB,UAAU;gBAC/BtpB,IAAIspB,iBAAiB,oBAAoB;gBACzCtpB,IAAIspB,iBAAiB,iBAAiB;gBAEtC,KAAKyiB,WAAW;oBACZ/rC,IAAIspB,iBAAiB,gBAAgB;oBAErCtpB,IAAIspB,iBAAiB,eAAejzB,WAAWxK;;gBAGnDP,GAAG+C,KAAKg/C,cAAc,SAAShgD,MAAMkB;oBACjCyR,IAAIspB,iBAAiBj8B,MAAMkB;;;;QAK3CjD,GAAG6B,OAAOxB;YACNuiC,aAAa,SAASof;gBAClB,IAAIpnC,KAAKonC,kBAAkBpnC;gBAC3B,IAAIslB,WAAW8hB,kBAAkB9hB;gBACjC,IAAIyC,YAAYqf,kBAAkBrf;gBAClC,IAAInJ,WAAWwoB,kBAAkBxoB;gBAEjC,IAAIjN,YAAYqD,QAAQuQ,cAAcvlB,IAAIslB,WACtCxrB,MAAMkb,QAAQ+Z,WAAW/uB,IAAIslB,WAC7Bp0B,SAASm2C,QAAQV,cAAchjC;gBAEnCzS,UAAU+0C,+BAA+BjmC,IAAIlG;gBAC7Ckb,QAAQob,yBAAyBpwB,IAAIslB,UAAU3T,UAAU3Q;gBACzD2lC,eAAe9lC,KAAKsM,YAAYtF,IAAI7H;gBACpC8lC,0BAA0B9lC,IAAI2D,QAAQgO;gBAEtC,IAAIiN,UAAU;oBACVjb,OAAO9C,KAAKjF,OAAOuiB,WAAWS,YAAY;;gBAG9CyoB,SAASb;oBACLr2C,YAAYwhB,UAAU9gB;oBACtBmP,IAAIA;oBACJ2mC,cAAcA;oBACdhjC,QAAQA;oBACR7J,KAAKA;oBACL4sC,cAAc3e;;gBAGlB+e;oBACIE,iBAAiBjf,UAAU1d;oBAC3BrK,IAAIA;oBACJlG,KAAKA;;gBAGTA,IAAI8oB,KAAKykB;gBAET,OAAOn2C;;YAGXq4B,YAAY,SAASvpB;gBACjB,IAAI7P,aAAa6kB,QAAQ7N,QAAQnH,KAC7B9O,SAAS4I,KAAK6sC,cAAcU;gBAEhCvtC,MAAMkb,QAAQ+Z,WAAW/uB;gBACzBgV,QAAQob,yBAAyBpwB;gBACjC9O,UAAU+0C,+BAA+BjmC,IAAIlG;gBAC7C6sC,eAAe9lC,KAAKsM,YAAYtF,IAAI7H;gBAEpCqnC,SAASb;oBACLr2C,YAAYA;oBACZ6P,IAAIA;oBACJ2mC,cAAcA;oBACd7sC,KAAKA;;gBAGTgtC;oBACI9mC,IAAIA;oBACJlG,KAAKA;;gBAGTA,IAAI8oB,KAAKykB;gBAET,OAAOn2C;;;QAIf9L,GAAG6B,OAAOxB,MAAM,IAAIL,GAAG8nC;YACnBzvB,SAASrY,GAAG6B;gBAAQupB,WAAW;eAAgB3P;YAC/C2jB,OAAOp/B,GAAG6B;gBAAQ0gB,aAAa9G,KAAKuM,cAAcvF;eAAM2c;;QAG5Dp/B,GAAGwM,SAASnM,MAAM,SAASsM;YACvB;gBACI6zB,gBAAgB,SAAS5lB;oBACrBwkB,MAAMuF,aAAa/pB;oBAEnB,IAAIa,KAAK/F,SAASzJ,QAAQuS,UAAU;wBAChC,OAAO0iC,0BAA0BtmC;2BAEhC;wBACD,OAAOjO,OAAO6zB,eAAe5lB,IAAI5a,GAAGgQ,KAAKixC,eAAe5gD,MAAM;;;;;;ICzSlFL,GAAGykC,YAAYmc,6BAA6B,SAAS1oC;QACjD;QAEA,IAAI4zB,WACAzzB;YACI4P;gBACI+I,UAAU;gBACVD,UAAU;gBACV4I,iBAAiB;;YAErBnb,UAAU;YACVrY,KAAK,SAAS4B,KAAK1B;YACnBmhB,QAAQ;WAEZ06B,eACAC;YACI1/B,KAAK,SAAS7H;gBACV,IAAI5a,GAAG6G,WAAWwR,QAAQmG,WAAW;oBACjC,OAAOnG,QAAQmG,SAAS5D;;gBAG5B,OAAOvC,QAAQmG;;;QAI3Bxe,GAAG6B,OAAOwW,SAASH;QAEnB4zB,YAAY9rC,GAAG6B,OAAOxB,MAAM,IAAIL,GAAG06B;YAC/BI,cAAc;YACdE,aAAa3iB,QAAQghB,cAAc,qBAAqB;YACxD0B,gBAAe1iB,QAAQmP;YACvBA,QAAQnP,QAAQmP;YAChBQ,eAAem6B;YACfjnB,oCAAoC;YACpCjT,MAAM5P,QAAQ4P;YACd9hB,KAAKkS,QAAQlS;YACbylB,YAAY,SAAShR,IAAIlG,KAAK4T;gBAC1B,IAAIxc,UAAUo2C,SAAStnC;uBAEhBsnC,SAAStnC;gBAEhB,IAAI0N,SAAS;oBACTxc,QAAQK,QAAQuI;uBAEf;oBACD5I,QAAQG,QAAQyI;;;;QAK5B1U,GAAG6B,OAAOxB;YACN8gD,UAAU,SAASvmC,IAAIlG,KAAK6J,QAAQ0G;gBAChC,IAAInZ,UAAU,IAAI9L,GAAG+L;gBAErBsM,QAAQlS,IAAI,4CAA4CyU;gBAExDsnC,SAAStnC,MAAM9O;gBAEfggC,UAAU3N,cAAcvjB,IACnB4jB,WAAWnmB,QAAQkG,OAAO3D,OAAO2D,QACjCogB,YAAYtmB,QAAQ4M,QAAQrK,OAAOqK,SACnCuY,KAAK9oB;gBAEV,OAAO5I;;;;ICtEnB9L,GAAGoiD,cAAc,SAASlqC;QACtB;QAEA,IAAIG,SACAgqC,wBAAwB,gBACxBC,yBAAyB,oBACzBC,sBACAC,mBACApqC,iBAAiB,IAAIpY,GAAGsS;QAE5B+F;YACIoqC;YACAC,oBAAoB;YACpBh4B;gBACIi4B,YAAY;;YAEhBv7B,WAAW,IAAIpnB,GAAGoiD,YAAYh7B;;QAGlCpnB,GAAG6B,OAAOwW,SAASH,GAAG;QAEtB,SAAS0qC,mBAAmB7iC,OAAO8iC;YAE/B,IAAIC,eAAe76C,MAAMvB,UAAUwB,MAAMtB,KAAKmZ;YAE9C1H,QAAQ+O,UAAU27B,QAAQ,aAAahjC,MAAMha,SAAS;YACtD88C,eAAeG,aAAa;YAC5B3qC,QAAQ+O,UAAU67B,+BAA+BH,cAAcD,eAAeK;;QAGlF,SAASC,iBAAiB1oB;YACtB,IAAI2oB,oBAAoB,IAAIpjD,GAAG+L;YAE/B,IAAI0uB,MAAMhyB,QAAQ;gBACdgyB,MAAM5e,KAAK,SAASA;oBAChBA,KAAKwnC,SAASC,qBAAqB7oB;oBACnC+nB,aAAat/C,KAAK2Y;oBAClBunC,kBAAkBn3C;mBAEtB,SAASs3C;oBACLlrC,QAAQ+O,UAAU27B,QAAQ,sBAAsBtoB,MAAM+oB,WAAW,wBAAwBD,UAAUlyB,OAAO,KAAK;oBAC/G+xB,kBAAkBj3C;;mBAGrB,IAAIsuB,MAAMgpB,aAAa;gBACxBC,oBAAoBjpB,OAAOtjB,KACvB,SAASwsC,eAAehpC;oBACpB,IAAIipC,cAAcjpC,QAAQ5U;oBAE1B/F,GAAG+C,KAAK4X,SAAS,SAAS3X,KAAKy3B;wBAC3B0oB,iBAAiB1oB,OAAO7iB,KAAK;4BACzBgsC,eAAe;4BAEf,IAAIA,gBAAgB,GAAG;gCACnBR,kBAAkBn3C;;;;oBAK9B,KAAK0O,QAAQ5U,QAAQ;wBACjBq9C,kBAAkBn3C;;mBAI1B,SAAS43C,YAAYN;oBACjBlrC,QAAQ+O,UAAU27B,QAAQ,sBAAsBtoB,MAAM+oB,WAAW,wBAAwBD,UAAUlyB,OAAO,KAAK;oBAC/G+xB,kBAAkBj3C;;;YAK9B,OAAOi3C;;QAGX,SAASE,qBAAqB7oB;YAC1B,IAAI14B,OAAO04B,MAAM14B,MACbyhD,WAAW/oB,MAAM+oB,UACjBM,wBAAwBN,SAASvxC,YAAYlQ;YAGjDyhD,WAAWA,SAAStxC,OAAO,GAAG4xC;YAG9B,IAAIN,SAASzzC,OAAO,OAAO,KAAK;gBAC5ByzC,WAAWA,SAAStxC,OAAO;;YAG/B,OAAOsxC;;QAIX,SAASE,oBAAoBjpB,OAAOqgB,QAAQiJ,cAAcC;YACtD,IAAIl4C,UAAUk4C,mBAAmB,IAAIhkD,GAAG+L,WACpCk4C,YAAYnJ,UAAUrgB,MAAMypB;YAEhCD,UAAUE,YACN,SAASC,YAAYzpC;gBACjB,IAAI0pC,aAAaN,eAAeA,aAAa3zC,OAAOuK,WAAWA;gBAE/D,IAAIA,QAAQ5U,QAAQ;oBAChBkkB,WAAW;wBACPy5B,oBAAoBjpB,OAAOwpB,WAAWI,YAAYv4C;uBACnD;uBAEF;oBACDA,QAAQG,QAAQo4C;;eAIxBv4C,QAAQK;YAGZ,OAAOL;;QAGX,SAASw4C,mBAAmB/5C,cAAcs4C;YACtC,IAAI0B,4BACAC,4BAA4B,IAAIxkD,GAAG+L;YAEvCsM,QAAQ+O,UAAUq9B;YAClB5B,eAAeG,aAAa;YAE5B,IAAIz4C,aAAawV,MAAMha,SAAS,MAAMsS,QAAQqqC,oBAAoB;gBAC9DrqC,QAAQ+O,UAAU67B;gBAClB5qC,QAAQ+O,UAAUs9B,UAAU,qBAAqB;gBACjD7B,eAAeG,aAAa;gBAC5BwB,0BAA0Br4C;mBAEzB;gBACDq2C;gBAEA,IAAIxiD,GAAGsK,sBAAsBC,eAAe;oBACxCvK,GAAG+C,KAAKwH,aAAaC,OAAO,SAASxH,KAAKsE;wBACtC,IAAImzB,QAAQnzB,KAAKmD;wBAEjB,IAAIgwB,OAAO;4BAEP,IAAIA,MAAMhyB,QAAQ;gCACd+5C,aAAat/C,KAAKoE,KAAKu3C;mCAGtB;gCACD0F,sBAAsBrhD,KAAKigD,iBAAiB1oB,OAAO7iB,KAAK;oCACpD2sC,sBAAsBvgB;oCACtB,IAAIugB,sBAAsBx+C,WAAW,GAAG;wCACpCy+C,0BAA0Bv4C;;;;;;uBAO7C;oBACDu2C,eAAej4C,aAAawV;;gBAGhC,IAAIwkC,sBAAsBx+C,WAAW,GAAG;oBACpCy+C,0BAA0Bv4C;;;YAIlC,OAAOu4C;;QAGX,SAASG,cAAcC;YACnB,IAAIC,WAAW,IAAI7kD,GAAG8kD;gBAClBzC,uBAAuBA;gBACvBpiD,SAAS2kD;gBACTG,SAAS,SAAS71C;oBACdlP,GAAG4kD,UAAUviD,SAASgW,QAAQqS,QAAQi4B;oBACtCzzC,EAAE81C;;gBAENC,uBAAuB,SAAS/1C;oBAC5BlP,GAAG4kD,UAAUtiD,YAAY+V,QAAQqS,QAAQi4B;;gBAE7CuC,QAAQ,SAASh2C;oBACbo1C,mBAAmBp1C,EAAE3E,cAAcs6C,UAAU1tC,KACzC;wBACIyrC,mBAAmBJ,cAAcqC;uBAErC;wBACIxsC,QAAQ+O,UAAU27B,QAAQ,uEAAuE;;;;YAMjH3qC,eAAezF,YAAY;gBACvBkyC,SAASryC;;YAGbxS,GAAG4kD,UAAU9gD,aAAaw+C,2BAA2BtiD,GAAG4kD,UAAU1kD;YAElEqiD,gBAAgBr/C,KAAK2hD;YAErB,OAAOA;;QAGX,SAASM,WAAWC;YAChB,IAAIC;YAEJrlD,GAAG+C,KAAKqiD,UAAU76C,aAAa+6C,OAAO,SAASz1C,KAAK5M;gBAChD,IAAIA,QAAQ,SAAS;oBACjBoiD,WAAW;oBACX,OAAO;;;YAIf,OAAOA;;QAWX,SAASE,mBAAmBr2C;YACxB,IAAIlP,GAAGiO,UAAU;gBACb,OAAOiB,EAAE4tC,IAAI,KAAK5tC,EAAEs2C,IAAI;;YAG5B,OAAOt2C,EAAE4tC,MAAM,KAAK5tC,EAAEs2C,MAAM;;QAGhC,SAASC;YACL,IAAIC,YAAYrtC,QAAQoqC,kBAEpBkD,qBAAqB;gBACjB17B,WAAW;oBACPjqB,GAAG+C,KAAK2iD,WAAW,SAAS1iD,KAAK6hD;wBAC7B7kD,GAAG6kD,UAAU/gD,aAAaw+C,2BAA2BtiD,GAAG6kD,UAAU3kD;wBAClEF,GAAG6kD,UAAUviD,YAAY+V,QAAQqS,QAAQi4B;;mBAE9C;;YAGX3iD,GAAG+C,KAAK2iD,WAAW,SAAS1iD,KAAK6hD;gBAC7B,IAAIhC,iBAAiB8B,cAAcE;gBAGnC,IAAIa,UAAU3/C,UAAU/F,GAAGkT,kBAAkB8C,UAAU;oBACnDoC,eAAe9X,OAAOuJ,UAAU,aAAa,SAASqF;wBAClD,KAAK2zC,eAAeG,kBAAkBmC,WAAWj2C,IAAI;4BACjDlP,GAAG+C,KAAK2iD,WAAW,SAAS1iD,KAAK6hD;gCAG7B,IAAIA,oBAAoBe,eACpB5lD,GAAG6kD,UAAU/gD,aAAaw+C,yBAAyB;oCAEnDtiD,GAAG6kD,UAAUvjD;wCAAKlB,SAAS;;;;;;;;YAQnDgY,eAAe9X,OAAOuJ,UAAU,aAAa,SAASqF;gBAClD,IAAIq2C,mBAAmBr2C,IAAI;oBACvBy2C;;;YAORvtC,eAAe9X,OAAON,GAAG6J,UAAUzG,WAAW,IAAI,cAAc,SAAS8L;gBACrEy2C;;YAGJvtC,eAAe9X,OAAOuJ,UAAU,QAAQ,SAASqF;gBAC7C,IAAIi2C,WAAWj2C,IAAI;oBACfA,EAAED;oBACF02C;;;YAIRvtC,eAAe9X,OAAOuJ,UAAUw4C,uBAAuBsD;;QAG3DF;QAEAzlD,GAAG6B,OAAOxB;YACNwlD,oBAAoB,SAAS5lD;gBACzBoY,QAAQoqC,iBAAiBv/C,KAAKjD;gBAC9B0kD,cAAc1kD;;YAGlB6lD,gBAAgB,SAAS7lD;gBACrB,IAAI6Q,GACAi1C,MAAM1tC,QAAQoqC;gBAElB,KAAK3xC,KAAKi1C,KAAK;oBACX,IAAIA,IAAIj1C,OAAO7Q,SAAS;wBACpB,OAAO8lD,IAAIrpC,OAAO5L,GAAG;;;;YAKjC0B,SAAS;gBACL4F,eAAe5F;gBACfxS,GAAG+C,KAAKw/C,iBAAiB,SAASv/C,KAAK6hD;oBACnCA,SAASryC;;;;QAKrBnS,KAAKgzC;QACLhzC,KAAKgzC,SAASiQ,uBAAuBA;;IAGzCtjD,GAAGoiD,YAAYh7B,YAAY;QACvB;QAEA;YACIq9B,wBAAwB;YACxBxB,gCAAgC,SAASljC,OAAOimC;YAChDtB,WAAW,SAASrzB,MAAM40B;gBACtBjmD,GAAGmG,IAAI,6BAA6BkrB,OAAO,6BAA6B40B,iBAAiB,KAAK;;YAElGlD,SAAS,SAAS38C,SAASC;gBACvBrG,GAAGmG,IAAIC,SAASC;;;;IAK5BrG,GAAG8kD,iBAAiB,SAAS5sC;QACzB;QAEA,IAAIE,iBAAiB,IAAIpY,GAAGsS,kBACxB+F,SAASpY,SAASimD,aAAaC;QAEnC9tC;YACIpY,SAAS;YACT8kD,SAAS,SAAS71C;YAClBumB,SAAS,SAASvmB;YAElB+1C,uBAAuB,SAAS/1C;YAChCg2C,QAAQ,SAASh2C;;QAGrBlP,GAAG6B,OAAOwW,SAASH;QACnBjY,UAAUoY,QAAQpY;QAElB,SAASmmD;YACL,OAAOpmD,GAAGiO,YAAajO,GAAGqO,aAAarO,GAAGsO;;QAG9C,SAAS+3C,mBAAmBn3C;YAExB,KAAKi3C,qBAAqB;gBAGtB,IAAIC,0BAA0B;oBAC1BhuC,eAAe9X,OAAOuJ,UAAU,YAAY,SAASqF;wBACjDA,EAAED;;uBAEH;oBACHmJ,eAAe9X,OAAOuJ,UAAU,YAAY,SAASqF;wBACjD,IAAIA,EAAE3E,cAAc;4BAChB2E,EAAE3E,aAAa+7C,aAAa;4BAC5Bp3C,EAAED;;;;gBAKdk3C,sBAAsB;;;QAI9B,SAASI,gBAAgBr3C;YAGrB,KAAKlP,GAAGkT,kBAAkB8C,UAAU;gBAChC,OAAO;;YAGX,IAAIwwC,YAAYC,KAAKv3C,EAAE3E,cAEvBm8C,WAAW1mD,GAAGiO;YAMdu4C,aAAaxmD,GAAGyN,QAAQzN,GAAGkT,kBAAkB8C,WAAW,OAAOywC,GAAGE,kBAAkB;YACpF,OAAOF,MAAMD,eAEAC,GAAG1mC,SAAS0mC,GAAG1mC,MAAMha,WACpB2gD,YAAYD,GAAGnB,MAAMxkD,YAAY2lD,GAAGnB,MAAMxkD,SAAS,YACpD2lD,GAAGnB,MAAMsB,YAAYH,GAAGnB,MAAMsB,SAAS;;QAIxD,SAASC,oBAAoBC;YACzB,IAAIA,eAAe3iD,WAAW;gBAC1B+hD,cAAcY;;YAElB,OAAOZ;;QAGX,SAASa;YACL,IAAIC;YAEJ,SAASC;gBACLD,iBAAiBn9C,SAASq9C,YAAY;gBACtCF,eAAeG,UAAU9uC,QAAQgqC,uBAAuB,MAAM;;YAGlE,IAAIr9C,OAAOoiD,aAAa;gBACpB;oBACIJ,iBAAiB,IAAII,YAAY/uC,QAAQgqC;kBAE7C,OAAO3K;oBACHuP;;mBAGH;gBACDA;;YAGJp9C,SAASw9C,cAAcL;;QAG3B,SAASM;YACLlvC,eAAe9X,OAAOL,SAAS,YAAY,SAASiP;gBAChD,KAAKq3C,gBAAgBr3C,IAAI;oBACrB;;gBAKJ,IAAIq4C,SAASvnD,GAAGyN,QAAQzN,GAAGkT,kBAAkB8C,WAAW,OAAO9G,EAAE3E,aAAao8C;gBAC9E,IAAIY,WAAW,UAAUA,WAAW,YAAY;oBAC5Cr4C,EAAE3E,aAAa+7C,aAAa;uBACzB;oBACHp3C,EAAE3E,aAAa+7C,aAAa;;gBAGhCp3C,EAAE81C;gBACF91C,EAAED;;YAGNmJ,eAAe9X,OAAOL,SAAS,aAAa,SAASiP;gBACjD,KAAK23C,uBAAuB;oBACxB,KAAKN,gBAAgBr3C,IAAI;wBACrB;;oBAEJmJ,QAAQ0sC,QAAQ71C;;;YAIxBkJ,eAAe9X,OAAOL,SAAS,aAAa,SAASiP;gBACjD,KAAKq3C,gBAAgBr3C,IAAI;oBACrB;;gBAGJmJ,QAAQod,QAAQvmB;gBAEhB,IAAIs4C,gBAAgB39C,SAAS49C,iBAAiBv4C,EAAEw4C,SAASx4C,EAAEy4C;gBAE3D,IAAI3nD,GAAGK,MAAMS,SAAS0mD,gBAAgB;oBAClC;;gBAGJnvC,QAAQ4sC,sBAAsB/1C;;YAGlCkJ,eAAe9X,OAAOL,SAAS,QAAQ,SAASiP;gBAC5C,KAAK23C,uBAAuB;oBACxB,KAAKN,gBAAgBr3C,IAAI;wBACrB;;oBAGJA,EAAED;oBACFC,EAAE81C;oBACF3sC,QAAQ6sC,OAAOh2C;oBAEf63C;;;;QAKZV;QACAiB;QAEAtnD,GAAG6B,OAAOxB;YACN2iD,cAAc,SAAS8D;gBACnB,OAAOD,oBAAoBC;;YAG/Bt0C,SAAS;gBACL4F,eAAe5F;;YAGnB0wC,YAAY;gBACR,OAAOjjD;;;QAIfI,KAAKgzC;QACLhzC,KAAKgzC,SAASkT,kBAAkBA;;KCrfnC;QACG;QAEAvmD,GAAG4nD;YACClpC,iBAAiB,SAASC;gBACtBte,KAAKwnD,QAAQnhD,UAAUgY,gBAAgBrO,MAAMhQ,MAAM8H;gBACnD9H,KAAKynD,YAAYC;;YAGrBpnC,kBAAkB;gBACdtgB,KAAKwnD,QAAQnhD,UAAUia,iBAAiBtQ,MAAMhQ,MAAM8H;gBACpD9H,KAAKynD,YAAYE;;YAGrBC,kBAAkB,SAAShoD;gBACvBI,KAAK6nD,QAAQ7nD,KAAK6nD,KAAKrC,mBAAmB5lD;;YAG9CkoD,qBAAqB,SAASloD;gBAC1B,IAAII,KAAK6nD,MAAM;oBACX,OAAO7nD,KAAK6nD,KAAKpC,eAAe7lD;;;YAIxCmoD,iBAAiB,SAASxtC;gBACtB,KAAKva,KAAKynD,YAAYO,gBAAgBztC,KAAK;oBACvC,OAAOva,KAAKynD,YAAYQ,iBAAiB1tC;;;YAIjDV,OAAO;gBACH7Z,KAAKwnD,QAAQnhD,UAAUwT,MAAM7J,MAAMhQ,MAAM8H;gBACzC9H,KAAKynD,YAAY5tC;gBAEjB,KAAK7Z,KAAK8e,SAAS8E,UAAU5jB,KAAKynD,YAAY1lC,aAAa;oBACvD/hB,KAAKkuB,mBAAmBluB,KAAK6pB;wBACzBjqB,SAASI,KAAKynD,YAAY1lC;wBAC1BxJ,OAAOvY,KAAK8e,SAASzb,KAAKsnB;uBAC3BnR;;gBAGP,IAAIxZ,KAAK6nD,MAAM;oBACX7nD,KAAK6nD,KAAK11C;oBACVnS,KAAK6nD,OAAO7nD,KAAKkoD;;gBAGrBloD,KAAKmoD,qBAAqB;gBAC1BnoD,KAAKooD,yBAAyB;gBAE9BpoD,KAAKqoD;;YAGTziC,SAAS,SAASrL,IAAImC;gBAClB,IAAI4rC,oBAAoBtoD,KAAK8e,SAAS2S,eAAe/U;gBAErD1c,KAAKwnD,QAAQnhD,UAAUuf,QAAQ5V,MAAMhQ,MAAM8H;gBAC3C9H,KAAKynD,YAAYc,eAAehuC,IAAI+tC;;YAGxChlC,aAAa,SAAS/I;gBAClB,IAAI0uB,SAASjpC,KAAKwnD,QAAQnhD,UAAUid,YAAYtT,MAAMhQ,MAAM8H;gBAE5DmhC,UAAUjpC,KAAKynD,YAAYe,aAAajuC;gBACxC,OAAO0uB;;YAGX1oB,gBAAgB,SAAShG;gBACrB,IAAIkuC,YAAYzoD,KAAKwnD,QAAQnhD,UAAUka,eAAevQ,MAAMhQ,MAAM8H;gBAElE2gD,aAAazoD,KAAKynD,YAAYiB,gBAAgBnuC;gBAC9C,OAAOkuC;;YAGXE,OAAO,SAASC;gBACZ,OAAO5oD,KAAKynD,YAAYoB,UAAUD;;YAGtCE,eAAe,SAAS9nC;gBACpB,IAAIxF,OAAOxb,KAAK0hB,QAAQV;gBAExB,OAAOxF,KAAKutC;;;QAOpBppD,GAAGqpD;YACChnC,YAAY,SAASxJ;gBACjB,IAAIoL,SAAS5jB,KAAKwnD,QAAQnhD,UAAU2b,WAAWhS,MAAMhQ,MAAM8H;gBAE3D,KAAK8b,QAAQ;oBACT,IAAIpL,aAAaxY,KAAKkuB,kBAAkB;wBACpCtK,SAAS5jB,KAAKynD,YAAY1lC;;;gBAIlC,OAAO6B;;YAGXqlC,iBAAiB,SAASjoC;gBACtBhhB,KAAKynD,YAAYyB,WAAWloC;;YAGhCqnC,iCAAiC;gBAC7BroD,KAAKmpD,2BAA2BxpD,GAAGypD,2BAA2BppD,KAAKqpD;gBAInErpD,KAAKspD,0BAA0B3pD,GAAGqO;gBAElC,IAAIhO,KAAKupD,0BACT;oBACIvpD,KAAKwpD,wBAAwBxpD,KAAKypD;oBAClCzpD,KAAK0pD,+BAA+B1pD,KAAK2pD;oBACzC3pD,KAAK4pD,6BAA6B5pD,KAAK6pD;;;YAI/C3B,mBAAmB;gBACf,IAAIpwC,OAAO9X,MACPoiD,mBAAmBpiD,KAAK8e,SAASgrC,YAAYC,gBAC7CC,aAAahqD,KAAKynD,aAClBwC,kBAAkBD,WAAWE;gBAEjCD,mBAAmB7H,iBAAiBv/C,KAAKonD;gBAEzC,OAAO,IAAItqD,GAAGoiD;oBACVK,kBAAkBA;oBAClBC,oBAAoBriD,KAAK8e,SAASpV;oBAClC2gB;wBACIi4B,YAAYtiD,KAAK8e,SAASuL,QAAQi4B;;oBAEtCv7B;wBACIq9B,wBAAwB;4BACpB4F,WAAWG;;wBAEfvH,gCAAgC,SAASljC,OAAOimC;4BAC5CqE,WAAWI;4BAEXzqD,GAAG+C,KAAKgd,OAAO,SAAS/c,KAAK6Y;gCACzBA,KAAKutC,eAAepD;;4BAGxB,IAAIjmC,MAAMha,QAAQ;gCACdoS,KAAKsG,SAASsB,OAAO,MAAM;;;wBAGnC2kC,WAAW,SAASrzB,MAAMq5B;4BACtBvyC,KAAKqO,WAAW6K,MAAMq5B;;wBAE1B3H,SAAS,SAAS38C,SAASC;4BACvB8R,KAAKhS,IAAIC,SAASC;;;;;YAMlCqjD,4BAA4B;gBACxB,IAAIvxC,OAAO9X;gBAEX,OAAO,IAAIL,GAAGypD;oBACVY,YAAYhqD,KAAKynD;oBAEjB3hD,KAAK,SAASC,SAASukD;wBACnBxyC,KAAKhS,IAAIC,SAASukD;;oBAGtBC,cAAc,SAASvpC;wBACnBlJ,KAAK4I,WAAWM;;oBAGpByK,UAAU,SAASzK;wBACflJ,KAAKgI,OAAOkB;;oBAGhBwpC,SAAS,SAASxpC;wBACdlJ,KAAKwM,MAAMtD;;oBAGfypC,SAAS,SAASzpC;wBACdlJ,KAAKwL,YAAYtC;;oBAGrB0pC,YAAY,SAAS1pC;wBACjBlJ,KAAKyI,eAAeS;;oBAGxB2pC,WAAW,SAAS3pC;wBAChB,OAAOlJ,KAAKmI,QAAQe;;;;YAKhCuoC,wBAAwB;gBAEpB,OAAOvpD,KAAKynD,YAAYmD,6BAChB5qD,KAAK8e,SAASwR,cACf3wB,GAAGkrD,wBACHlrD,GAAGmrD,6BACHnrD,GAAGmrD;;YAGdC,sBAAsB;gBAClB,IAAIjzC,OAAO9X,MACPgqD,aAAahqD,KAAKynD;gBAEtB;oBACIuC,YAAYA;oBACZlkD,KAAK,SAASC,SAASukD;wBACnBxyC,KAAKhS,IAAIC,SAASukD;;oBAEtBU,mBAAmB,SAAShqC;wBACxB,OAAOlJ,KAAK2K;4BAAYlI,IAAIyG;2BAASpG;;oBAEzC+vC,WAAW,SAAS3pC;wBAChB,OAAOlJ,KAAKmI,QAAQe;;oBAExBiqC,WAAW,SAAS1wC,IAAImC;wBACpB5E,KAAK8N,QAAQrL,IAAImC;;oBAErBwuC,uBAAuB,SAAS3wC,IAAI4wC;wBAChC,IAAIC,UAAUzrD,GAAGqqD,WAAWqB,aAAa9wC,MACrC+wC,kBAAkB3rD,GAAGqqD,WAAW/B,iBAAiB1tC;wBAErD,IAAI4wC,WAAW;4BACXC,QAAQppD,SAAS;4BACjBgoD,WAAWuB,aAAahxC;4BACxByvC,WAAWwB,aAAajxC;+BAEvB;4BACD6wC,QAAQnpD,YAAY;4BACpB+nD,WAAWyB,aAAalxC;4BACxByvC,WAAW0B,aAAanxC;;wBAI5B+wC,gBAAgBtpD,SAAS,WAAWC,YAAY;;;;YAK5DynB,uBAAuB,SAASnP,IAAI4B,WAAWD;gBAC3Clc,KAAKwnD,QAAQnhD,UAAUqjB,sBAAsB1Z,MAAMhQ,MAAM8H;gBAEzD,IAAI9H,KAAKupD,0BAA0B;oBAE/B,IAAIvpD,KAAKynD,YAAYQ,iBAAiB1tC,OAAO2B,cAAcvc,GAAGib,OAAOsC,WAAW;wBAC5Eld,KAAKynD,YAAYkE,qBAAqBpxC;wBACtCva,KAAKynD,YAAY+D,aAAajxC;;;gBAItC,IAAI4B,cAAcxc,GAAGib,OAAO6C,mBAAmBvB,cAAcvc,GAAGib,OAAO2C,WAAW;oBAC9Evd,KAAKynD,YAAYmE,UAAUrxC;oBAC3Bva,KAAKynD,YAAYoE,cAActxC;oBAC/B5a,GAAGK,KAAKynD,YAAYQ,iBAAiB1tC,KAAKtY,YAAYjC,KAAK8rD,SAASC;uBAEnE,IAAI7vC,cAAcvc,GAAGib,OAAO+C,eAAe;oBAC5C3d,KAAKynD,YAAYuE,UAAUzxC;;;YAInCovC,gCAAgC;gBAC5B,IAAIvuC,OAAOzb,GAAG6B,WAAWxB,KAAK+qD;gBAE9B,OAAO,IAAIprD,GAAGssD,4BAA4B7wC;;YAG9CyuC,8BAA8B;gBAC1B,IAAIzuC,OAAOzb,GAAG6B,WAAWxB,KAAK+qD;gBAE9B,OAAO,IAAIprD,GAAGmrD,0BAA0B1vC;;YAG5CquC,yBAAyB;gBACrB,IAAIruC,OAAOzb,GAAG6B,WAAWxB,KAAK+qD;gBAE9B,OAAO,IAAIprD,GAAGkrD,qBAAqBzvC;;YAGvC2Y,gBAAgB,SAASxZ;gBACrBva,KAAKwnD,QAAQnhD,UAAU0tB,eAAe/jB,MAAMhQ,MAAM8H;gBAClD9H,KAAKynD,YAAYyE,YAAY3xC;;YAGjCwX,gBAAgB,SAASe,YAAYC;gBACjC/yB,KAAKwnD,QAAQnhD,UAAU0rB,eAAe/hB,MAAMhQ,MAAM8H;gBAClD9H,KAAKynD,YAAY0E;;YAGrBx4B,WAAW,SAASpZ,IAAI7Y;gBACpB,IAAI8Z,OAAOxb,KAAK0hB,QAAQnH;gBAExB,IAAIiB,QAAQA,KAAKwnC,UAAUhjD,KAAK8e,SAASgrC,YAAYsC,sBAAsB;oBACvEpsD,KAAK6jB,aAAa2F,YAAYjP;wBAC1B8xC,QAAQ7wC,KAAKwnC;;;gBAIrBhjD,KAAKwnD,QAAQnhD,UAAUstB,UAAU3jB,MAAMhQ,MAAM8H;gBAC7C9H,KAAKssD,WAAW/xC,IAAI7Y;;YAIxBmyB,cAAc,SAAStZ;gBAEnB,IAAIva,KAAKupD,0BAA0B;oBAC/BvpD,KAAKynD,YAAYkE,qBAAqBpxC;oBACtCva,KAAKynD,YAAYiE,aAAanxC;oBAG9B,KAAKva,KAAKspD,wBAAwB;wBAC9BtpD,KAAK4pD,2BAA2B2C,WAAWvsD,KAAKynD,YAAY4D,aAAa9wC;;;;YAMrF+Q,aAAa,SAAS/Q,IAAI7Y,MAAM0pB,QAAQC;gBACpCrrB,KAAKwnD,QAAQnhD,UAAUilB,YAAYtb,MAAMhQ,MAAM8H;gBAE/C9H,KAAKynD,YAAY+E,eAAejyC,IAAI6Q,QAAQC;gBAE5C,IAAIA,UAAU,KAAK/pB,KAAKC,MAAM6pB,SAASC,QAAQ,SAAS,KAAK;oBACzDrrB,KAAKynD,YAAYgF,WAAWlyC;oBAC5Bva,KAAKynD,YAAYuE,UAAUzxC;oBAC3Bva,KAAKynD,YAAYiF,aAAanyC;oBAC9Bva,KAAKynD,YAAYoE,cAActxC,IAAIva,KAAK8e,SAASzb,KAAKspD;oBAGtD3sD,KAAK4sD,iBAAiBryC;uBAErB;oBAEDva,KAAK4sD,iBAAiBryC,IAAI6Q,QAAQC;;;YAI1CiJ,kBAAkB,SAASlJ,QAAQC;gBAC/BrrB,KAAKwnD,QAAQnhD,UAAUiuB,iBAAiBtkB,MAAMhQ,MAAM8H;gBACpD9H,KAAKynD,YAAY3J,oBAAoB1yB,QAAQC;;YAGjDG,aAAa,SAASjR,IAAI7Y,MAAMY,QAAQ+R;gBACpC,IAAIw4C,eAAe7sD,KAAKwnD,QAAQnhD,UAAUmlB,YAAYxb,MAAMhQ,MAAM8H,YAC9DkiD,aAAahqD,KAAKynD,aAClB7nC,gBAAgBoqC,WAAW/B,iBAAiB1tC,KAC5CzC,OAAO9X;gBAEX,SAAS8sD,eAAexqD;oBAGpB,KAAKsd,eAAe;wBAChB;;oBAGJoqC,WAAW6B,cAActxC;oBAEzB5a,GAAGigB,eAAe3d,YAAY6V,KAAKg0C,SAASC;oBAC5C/B,WAAW0C,aAAanyC;oBAExB,IAAIzC,KAAK2K;wBAAYlI,IAAIA;uBAAKK,WAAWjb,GAAGib,OAAO+C,eAAe;wBAC9DqsC,WAAWyC,WAAWlyC;;oBAE1ByvC,WAAWkC,YAAY3xC;oBAEvB,IAAIjY,OAAOsJ,SAAS;wBAChBkM,KAAKi1C,sBAAsBxyC;2BAE1B;wBACD5a,GAAGigB,eAAe5d,SAAS8V,KAAKg0C,SAASkB;wBACzChD,WAAWiD,WAAW1yC;wBAEtB,IAAIyvC,WAAWkD,sBAAsBp1C,KAAK4L,gBAAgBnJ,KAAK;4BAC3D5a,GAAGigB,eAAe5d,SAAS8V,KAAKg0C,SAASnO;4BACzCqM,WAAWmD,UAAU5yC;;wBAEzBzC,KAAKs1C,2BAA2B7yC,IAAIjY;;;gBAK5C,IAAIuqD,wBAAwBltD,GAAG+L,SAAS;oBACpCmhD,aAAat1C,KAAK,SAAS81C;wBACvBP,eAAeO;;uBAIlB;oBACDP,eAAexqD;;gBAGnB,OAAOuqD;;YAGXE,uBAAuB,SAASxyC;gBAC5B,IAAIyvC,aAAahqD,KAAKynD;gBAEtB,IAAIznD,KAAKywB,qBAAqB;oBAC1Bu5B,WAAWsD,iBAAiB/yC;;gBAGhC5a,GAAGqqD,WAAW/B,iBAAiB1tC,KAAKvY,SAAShC,KAAK8rD,SAASlgD;gBAE3D5L,KAAKutD,sBAAsBhzC;;YAG/BsR,eAAe,SAAStR;gBACpBva,KAAKwnD,QAAQnhD,UAAUwlB,cAAc7b,MAAMhQ,MAAM8H;gBACjD9H,KAAKynD,YAAY+F,YAAYjzC;;YAGjCwR,WAAW,SAASxR,IAAI7Y;gBACpB,IAAImrD,eAAe7sD,KAAKwnD,QAAQnhD,UAAU0lB,UAAU/b,MAAMhQ,MAAM8H;gBAEhE9H,KAAKynD,YAAY+F,YAAYjzC;gBAE7B,OAAOsyC;;YAGX1gC,gBAAgB,SAAS5R,IAAI2R;gBACzBlsB,KAAKwnD,QAAQnhD,UAAU8lB,eAAenc,MAAMhQ,MAAM8H;gBAIlD,IAAIokB,UAAUG,YAAY,KAAKrsB,KAAKkgB,SAASiD,YAAY5I,KAAK;oBAC1Dva,KAAKynD,YAAYgG,WAAWlzC;;;YAIpCoR,WAAW,SAASpR,IAAI7Y;gBACpB1B,KAAKwnD,QAAQnhD,UAAUslB,UAAU3b,MAAMhQ,MAAM8H;gBAC7C9H,KAAKipD,gBAAgB1uC;gBAErB,IAAIva,KAAKuuB,sBAAsB,GAAG;oBAC9BvuB,KAAKynD,YAAY0E;;;YAIzB/4B,oBAAoB,SAAS7Y;gBACzB,IAAImzC,oBAAoBC,SAASC;gBAEjC5tD,KAAKwnD,QAAQnhD,UAAU+sB,mBAAmBpjB,MAAMhQ,MAAM8H;gBAEtD9H,KAAK6tD,gBAAgBtzC;gBAErB,IAAIva,KAAK8e,SAASwF,MAAMwpC,mBAAmB;oBACvCJ,qBAAqB1tD,KAAKwjB,aAAajJ;oBACvCozC,UAAU3tD,KAAK8e,SAASwF,MAAMsR;oBAE9Bg4B,YAAY5tD,KAAK8e,SAASwF,MAAMypC,cAAc7rD,QAAQ,iBAAiBwrD;oBACvEE,YAAYA,UAAU1rD,QAAQ,gBAAgByrD;oBAE9C3tD,KAAKynD,YAAYoE,cAActxC,IAAIqzC;oBACnCjuD,GAAGK,KAAKynD,YAAYQ,iBAAiB1tC,KAAKvY,SAAShC,KAAK8rD,SAASC;;;YAKzEl6B,sBAAsB,SAAStX;gBAC3B,IAAIva,KAAKwnD,QAAQnhD,UAAUwrB,qBAAqB7hB,MAAMhQ,MAAM8H,YAAY;oBACpE9H,KAAKynD,YAAYuG,cAAczzC;oBAC/B5a,GAAGK,KAAKynD,YAAYQ,iBAAiB1tC,KAAKtY,YAAYjC,KAAK8rD,SAASkB;oBACpEhtD,KAAKynD,YAAYoE,cAActxC;oBAC/Bva,KAAKynD,YAAY+F,YAAYjzC;oBAC7Bva,KAAK6tD,gBAAgBtzC;oBACrB,OAAO;uBAEN;oBACD5a,GAAGK,KAAKynD,YAAYQ,iBAAiB1tC,KAAKvY,SAAShC,KAAK8rD,SAASnO;oBACjE39C,KAAKynD,YAAY0F,UAAU5yC;oBAC3B,OAAO;;;YAIfoG,iBAAiB,SAASpG;gBACtB,IAAIyZ,oBAAoBr0B,GAAGgQ,KAAK3P,KAAKiuD,wBAAwBjuD;gBAE7DA,KAAKwnD,QAAQnhD,UAAUsa,gBAAgBpa,KAAKvG,MAAMua,IAAIyZ;;YAG1Di6B,wBAAwB,SAAS1zC,IAAIG,MAAMuZ;gBACvC,IAAIj0B,KAAK8e,SAAS4B,WAAWwtC,cAAc;oBACvCluD,KAAKmuD,mBAAmBn+C,MAAMhQ,MAAM8H;uBAEnC;oBACD9H,KAAKouD,mBAAmBp+C,MAAMhQ,MAAM8H;;;YAI5Cke,mBAAmB,SAASzL,IAAIlG,KAAK4T;gBACjCjoB,KAAKwnD,QAAQnhD,UAAU2f,kBAAkBhW,MAAMhQ,MAAM8H;gBAErD9H,KAAKynD,YAAYyE,YAAY3xC;gBAE7B,IAAI0N,SAAS;oBACTjoB,KAAKynD,YAAYoE,cAActxC,IAAIva,KAAK8e,SAAS4B,WAAW2tC;oBAC5DruD,KAAKynD,YAAY6F,iBAAiB/yC;uBAEjC;oBACDva,KAAKipD,gBAAgB1uC;;;YAI7B6zC,oBAAoB,SAAS7zC,IAAIG,MAAMuZ;gBACnCj0B,KAAKynD,YAAY6G,iBAAiB/zC;gBAClCva,KAAKynD,YAAY+F,YAAYjzC;gBAC7Bva,KAAKynD,YAAYoE,cAActxC,IAAIva,KAAK8e,SAAS4B,WAAW6tC;gBAC5DvuD,KAAKo0B,eAAeC,WAAWrkB,MAAMhQ,MAAM8H;;YAG/CqmD,oBAAoB,SAAS5zC,IAAIG,MAAMkgB;gBAEnC,IAAI5oB,WAAWhS,KAAKigB,QAAQ1F,KACxBi0C,iBAAiBxuD,KAAK8e,SAAS4B,WAAW8tC,eAAetsD,QAAQ,iBAAiB8P,WAClF0I,OAAO1a,KAAKkjB,QAAQ3I,KACpBk0C,oBAAoB3mD,WACpBgQ,OAAO9X,MACPsP;gBAEJA,SAAStP,KAAK8e,SAAS4vC,YAAYF;gBAEnC,IAAI7uD,GAAGiX,iBAAiBtH,SAAS;oBAC7BA,OAAOwH,KAAK;wBACRgB,KAAKs2C,mBAAmBp+C,MAAM8H,MAAM22C;;uBAGvC,IAAIn/C,WAAW,OAAO;oBACvBwI,KAAKs2C,mBAAmBp+C,MAAM8H,MAAM22C;;;YAI5CnC,YAAY,SAAS/xC,IAAI7Y,MAAMitD;gBAC3B,IAAIC,aACAC,eAAe,GACfC,cAAc9uD,KAAKkgB,SAASolB,UAAU/qB,OAAOva,KAAK8e,SAAS1I,QAAQ24C,YACnE/yC;gBAEJ,IAAIhc,KAAK8e,SAAS/e,QAAQivD,cAAc;oBACpC,IAAIhvD,KAAKmoD,qBAAqB,KAAKnoD,KAAKooD,yBAAyB,GAAG;wBAChEyG,eAAe7uD,KAAKooD,yBAAyB;;oBAGjDwG;wBACI7zC,OAAO8zC;;;gBAIf,KAAKF,QAAQ;oBACT,IAAI3uD,KAAK8e,SAASgY,gCAAgCn3B,GAAGkT,kBAAkBqC,eAAe;wBAClFlV,KAAKynD,YAAYwH;;oBAMrB,KAAKjvD,KAAK8e,SAASpV,UAAU;wBACzBsS,SAAShc,KAAKyiB;4BAAYlI,IAAIA;;wBAE9Bva,KAAKkvD,qBAAqBlvD,KAAKkvD,sBAAsBlzC,OAAON;wBAE5D,IAAIM,OAAON,iBAAiB1b,KAAKkvD,uBAAuBlzC,OAAON,cAAc;4BACzE1b,KAAKkgB,SAASC;4BACdngB,KAAKmvD;4BACLnvD,KAAKkvD,qBAAqB;;;;gBAKtC,IAAIP,QAAQ;oBACR3uD,KAAKynD,YAAY2H,eAAe70C,IAAIva,KAAK8e,SAAS2S,eAAe/vB,OAAOktD,aAAaE;oBACrF9uD,KAAKynD,YAAY4H,gBAAgB90C,IAAIva,KAAKwhB,eAAejH,KAAK,MAAMva,KAAK8e,SAASwwC,WAAW91B;uBAE5F;oBACDx5B,KAAKynD,YAAYtsC,QAAQZ,IAAIva,KAAK8e,SAAS2S,eAAe/vB,OAAOktD,aAAaE;oBAC9E9uD,KAAKynD,YAAY8H,gBAAgBh1C,IAAIva,KAAK0hB,QAAQnH,KAAKva,KAAK8e,SAASwwC,WAAW91B;;gBAGpFx5B,KAAKooD,0BAA0B;gBAE/B,IAAIuG,UACC3uD,KAAK8e,SAAS/e,QAAQyvD,oBAAoB7vD,GAAGkT,kBAAkBqC,eAAgB;oBAEhFlV,KAAK4sD,iBAAiBryC;;;YAI9B40C,YAAY;gBACRnvD,KAAKynD,YAAYE;gBACjB3nD,KAAKsgB;;YAGTssC,kBAAkB,SAASryC,IAAIk1C,YAAYnS;gBACvC,IAAI/hC,OAAOvb,KAAK2iB,QAAQpI,KACpBm1C,iBAAiB1vD,KAAKutB,YAAYhS;gBAEtC,IAAIA,QAAQ,GAAG;oBACX,IAAIk0C,eAAe3rD,aAAaw5C,cAAcx5C,WAAW;wBACrD4rD,iBAAiB1vD,KAAK2vD,gBAAgBF,YAAYnS;;oBAGtDt9C,KAAKynD,YAAY9qC,WAAWpC,IAAIm1C;;;YAIxCC,iBAAiB,SAASC,cAActS;gBACpC,IAAIv3C,UAAU/F,KAAK8e,SAASzb,KAAKwsD;gBACjC,SAAS5iD,EAAEvL,MAAM6vB;oBAAexrB,UAAUA,QAAQ7D,QAAQR,MAAM6vB;;gBAEhEtkB,EAAE,aAAa3L,KAAKC,MAAMquD,eAAetS,YAAY;gBACrDrwC,EAAE,gBAAgBjN,KAAKutB,YAAY+vB;gBACnC,OAAOv3C;;YAGXqnD,4BAA4B,SAAS7yC,IAAI6X;gBACrC,IAAI09B,MAAMC,kBAAkBC;gBAE5BF,OAAO9vD,KAAK8e,SAASmxC,wBAAwBH;gBAC7CC,mBAAmB/vD,KAAK8e,SAASmxC,wBAAwBF;gBAEzD,IAAID,SAAS,UAAU;oBACnBE,gBAAgB59B,SAAS29B;oBACzB,KAAKC,eAAe;wBAChBA,gBAAgBhwD,KAAK8e,SAASzb,KAAK6sD;;oBAGvClwD,KAAKynD,YAAYoE,cAActxC,IAAIy1C;oBAEnC,IAAIhwD,KAAK8e,SAASmxC,wBAAwBE,eAAe;wBACrDnwD,KAAKowD,aAAa71C,IAAIy1C;;uBAGzB,IAAIF,SAAS,WAAW;oBACzB9vD,KAAKynD,YAAYoE,cAActxC,IAAIva,KAAK8e,SAASzb,KAAK6sD;uBAErD,IAAIJ,SAAS,QAAQ;oBACtB9vD,KAAK8F,IAAI,4CAA4CgqD,OAAO,kBAAkB;;;YAItFM,cAAc,SAAS71C,IAAIlX;gBACvBrD,KAAKynD,YAAYQ,iBAAiB1tC,IAAIhC,QAAQlV;;YAGlDwqD,iBAAiB,SAAStzC;gBACtB,KAAKva,KAAK8e,SAASgY,+BAA+Bn3B,GAAGkT,kBAAkBqC,eAAe;oBAClFlV,KAAKynD,YAAYwF,WAAW1yC;;;YAIpC4L,YAAY,SAAS6K,MAAMtvB,MAAMuF;gBAC7B,IAAIlB,UAAU/F,KAAKwnD,QAAQnhD,UAAU8f,WAAWnW,MAAMhQ,MAAM8H;gBAC5D9H,KAAK8e,SAASuxC,YAAYtqD;;YAG9B+gB,aAAa,SAAS/gB;gBAClB/F,KAAKwnD,QAAQnhD,UAAUygB,YAAY9W,MAAMhQ,MAAM8H;gBAC/C9H,KAAK8e,SAASuxC,YAAYtqD;;YAG9BuqD,mBAAmB;gBACf,IAAIx4C,OAAO9X;gBAEXA,KAAK8e,SAASiI,UAAUyB,kBAAkB;oBACtC,IAAIziB,UAAU+R,KAAKgH,SAASuJ,MAAMkoC,mBAC9BC,aAAa14C,KAAKgH,SAASuJ,MAAMrJ;oBAErC,OAAOlH,KAAKgH,SAAS2xC,WAAW1qD,SAASyqD;;;YAIjDljC,qBAAqB,SAAS/S,IAAI7Y;gBAC9B1B,KAAKmoD,sBAAsB;gBAC3BnoD,KAAKwnD,QAAQnhD,UAAUinB,oBAAoBtd,MAAMhQ,MAAM8H;;YAG3D+X,wBAAwB,SAAS1V,OAAO+T,QAAQC;gBAC5Cne,KAAKmoD,qBAAqBh+C,MAAMzE;gBAChC1F,KAAKooD,yBAAyB;gBAC9BpoD,KAAKwnD,QAAQnhD,UAAUwZ,uBAAuB7P,MAAMhQ,MAAM8H;;YAG9DylD,uBAAuB,SAASvsC;gBAC5B,IAAIyF,eAAezmB,KAAKwhB,eAAeR,SACnC0vC,aAAa1wD,KAAKyiB;oBAAYlI,IAAIyG;mBAASpG;gBAE/C,IAAI81C,eAAe/wD,GAAGib,OAAOkD,YACxB2I,gBACDzmB,KAAK8e,SAASwwC,WAAWqB,aAAaC,sBACrCjxD,GAAGkT,kBAAkBiD,gBAAgB;oBAItC9V,KAAKynD,YAAY4H,gBAAgBruC,QAAQyF,cAAczmB,KAAK8e,SAASwwC,WAAW91B;;;YAIxFhb,gBAAgB,SAAS8H;gBACrB,IAAI/L,KAAKva,KAAKwnD,QAAQnhD,UAAUmY,eAAexO,MAAMhQ,MAAM8H;gBAE3D9H,KAAKssD,WAAW/xC,IAAIva,KAAKigB,QAAQ1F,KAAK;gBACtCva,KAAKynD,YAAYyE,YAAY3xC;gBAC7Bva,KAAKynD,YAAYgF,WAAWlyC;gBAC5Bva,KAAK+sD,sBAAsBxyC;gBAE3B,OAAOA;;YAGXwS,UAAU,SAASxS,IAAIqC;gBACnB5c,KAAKwnD,QAAQnhD,UAAU0mB,SAAS/c,MAAMhQ,MAAM8H;gBAE5C9H,KAAKynD,YAAY9qC,WAAWpC,IAAIva,KAAKutB,YAAY3Q;;YAGrD6Y,yBAAyB;gBACrBz1B,KAAKynD,YAAYC;gBACjB1nD,KAAKwnD,QAAQnhD,UAAUovB,wBAAwBzlB,MAAMhQ,MAAM8H;;;;IC7sBvEnI,GAAGkxD,eAAe,SAASh5C,GAAGkT;QAC1B;QAEA,IAAIjT,OAAO9X;QAKXA,KAAKwnD,UAAUz8B,YAAYprB,GAAGorB,WAAW8L,oBAAoBl3B,GAAGk3B;QAChE72B,KAAKwnD,QAAQx3C,MAAMhQ,MAAM8H;QAGzBnI,GAAG6B,OAAOxB,KAAK8e;YACXlf,SAAS;YAETgkB,QAAQ;YAERktC,aAAa;YAEbhH;gBACIC;gBACAqC,sBAAsB;;YAG1B/oD;gBACIwsD,gBAAgB;gBAChBK,YAAY;gBACZvD,oBAAoB;gBACpB1jB,QAAQ;;YAGZ8nB,UAAU;YAEV1mC;gBACI0hC,UAAU;gBACVpO,WAAW;gBACX/xC,SAAS;gBACTohD,MAAM;gBACNgE,UAAU;gBACVnxD,MAAM;gBACNyiD,YAAY;;YAGhB2N;gBACIH,MAAM;gBACNC,kBAAkB;gBAClBI,eAAe;;YAGnBj/B;gBACI+/B,mBAAmB;gBACnBC,oBAAoB;;YAGxB5sC;gBACIwpC,mBAAmB;gBACnBC,eAAe;;YAGnBrtC;gBACIwtC,cAAc;gBACdM,gBAAgB;gBAChBD,oBAAoB;gBACpBF,oBAAoB;;YAIxBtuD;gBACIyvD,kBAAkB;gBAClBR,cAAc;;YAGlB3mC;gBACI8oC,eAAe;gBACfZ,mBAAmB;;YAGvBjB;gBACI91B,eAAe;gBACf43B,UAAU;gBACVT;oBACIC,mBAAmB;oBACnBS,kBAAkB;oBAClBC,aAAa;;gBAEjBC,mBAAmB;;YAGvBn7C;gBACI24C,YAAY;;YAGhBsB,aAAa,SAAStqD;gBAClB,IAAI+R,KAAK2vC,YAAY+J,UAAU,UAAU;oBACrC,OAAO15C,KAAK2vC,YAAYgK,WAAW,SAAS1rD;uBAE3C;oBACD6jB,WAAW;wBACPjlB,OAAOstB,MAAMlsB;uBACd;;;YAIX2oD,aAAa,SAAS3oD;gBAClB,IAAI+R,KAAK2vC,YAAY+J,UAAU,YAAY;oBACvC,OAAO15C,KAAK2vC,YAAYgK,WAAW,WAAW1rD;uBAE7C;oBACD,OAAOpB,OAAO+sD,QAAQ3rD;;;YAI9B0qD,YAAY,SAAS1qD,SAAS4rD;gBAC1B,IAAI75C,KAAK2vC,YAAY+J,UAAU,WAAW;oBACtC,OAAO15C,KAAK2vC,YAAYgK,WAAW,UAAU1rD,SAAS4rD;uBAErD;oBACD,OAAOhtD,OAAOitD,OAAO7rD,SAAS4rD;;;WAGvC;QAGHhyD,GAAG6B,OAAOxB,KAAK8e,UAAUjH,GAAG;QAE5B7X,KAAKynD,cAAc,IAAI9nD,GAAGkyD;YACtB/rD,KAAKnG,GAAGgQ,KAAK3P,KAAK8F,KAAK9F;YACvB8xD,gBAAgB9xD,KAAK8e,SAASiyC;YAC9BgB,aAAa/xD,KAAK8e,SAASlf;YAC3BoyD,iBAAiBhyD,KAAK8e,SAASgyC;YAC/BltC,QAAQ5jB,KAAK8e,SAAS8E;YACtBu2B,gBAAgBn6C,KAAKuhB;YACrB8I;gBACIxqB,MAAMG,KAAK8e,SAASuL,QAAQxqB;gBAC5BmxD,UAAUhxD,KAAK8e,SAASuL,QAAQ2mC;;YAEpC7a;gBACI8b,WAAWjyD,KAAK8e,SAASwwC,WAAW8B;gBACpCG,mBAAmBvxD,KAAK8e,SAASwwC,WAAWiC;;YAEhDZ;gBACIuB,iBAAiBlyD,KAAK8e,SAASwwC,WAAWqB,aAAaC;gBACvDuB,uBAAuBnyD,KAAK8e,SAASwwC,WAAWqB,aAAaU;gBAC7De,qBAAqBpyD,KAAK8e,SAASwwC,WAAWqB,aAAaW;;YAE/DjuD,MAAMrD,KAAK8e,SAASzb;;QAGxB,IAAIrD,KAAK8e,SAASoL,YAAY8H,qBAAqBryB,GAAG6O,YAAY7O,GAAG+O,aAAa;YAC9E1O,KAAKynD,YAAY4K,cAAcryD,KAAK8e,SAASoS,SAASgB;eAErD,KAAKvyB,GAAGkT,kBAAkB0D,aAAcvW,KAAK8e,SAAS8I,KAAK8I,aAAa/wB,GAAGkT,kBAAkB2D,YAAa;YAC3GxW,KAAKynD,YAAY4K,cAAcryD,KAAK8e,SAASoS,SAASggC;eAErD;YACDlxD,KAAKu2B;YAELv2B,KAAKynD,YAAY3X;YAEjB9vC,KAAK8rD,WAAW9rD,KAAK8e,SAASuL;YAE9B,KAAKrqB,KAAK8e,SAAS8E,UAAU5jB,KAAKynD,YAAY1lC,aAAa;gBACvD/hB,KAAKkuB,mBAAmBluB,KAAK6pB;oBACzBjqB,SAASI,KAAKynD,YAAY1lC;oBAC1BxJ,OAAOvY,KAAK8e,SAASzb,KAAKsnB;mBAC3BnR;;YAGPxZ,KAAKqoD;YAEL,IAAI1oD,GAAGoiD,eAAepiD,GAAGkT,kBAAkB8C,UAAU;gBACjD3V,KAAK6nD,OAAO7nD,KAAKkoD;;YAGrB,IAAIloD,KAAK8e,SAASuJ,MAAMD,iBAAiBpoB,KAAK8e,SAASuJ,MAAM8oC,eAAe;gBACxE,IAAIxxD,GAAGwoB,cAAc;oBACjBnoB,KAAKswD;uBAEJ;oBACDtwD,KAAK8F,IAAI,mCAAmC;;;YAIpD9F,KAAKmoD,qBAAqB;YAC1BnoD,KAAKooD,yBAAyB;;;IAKtCzoD,GAAG6B,OAAO7B,GAAGkxD,aAAaxqD,WAAW1G,GAAGoe;IACxCpe,GAAG6B,OAAO7B,GAAGkxD,aAAaxqD,WAAW1G,GAAG0mB;IAGxC1mB,GAAG6B,OAAO7B,GAAGkxD,aAAaxqD,WAAW1G,GAAG4nD;IACxC5nD,GAAG6B,OAAO7B,GAAGkxD,aAAaxqD,WAAW1G,GAAGqpD;IC5LxCrpD,GAAGkyD,aAAa,SAASz2C;QACrB;QAEA,IAAIk3C,eAAe,cACfC,oBAAoB,eACpBC,0BAA0B,eAC1BC,8BAA8B,mBAE9BC,qBAAqB,oBACrBC,sBAAsB,qBACtBC,oBAAoB,kBACpBC,uBAAuB,qBACvBC;YACIC,SAASvpD,SAASwpD;YAClBC;WAEJC,mBAAmB,OACnBC,sBAAsB,GACtBC,+BAA+B,OAC/BC,2BACAC,oBAAoB,GACpBt7C;YACIlS,KAAK;YACLqwC;gBACI8b,WAAW;gBACXV,mBAAmB;;YAEvBO,gBAAgB;YAChBC,aAAa;YACbC,iBAAiB;YACjBpuC,QAAQ;YACRu2B,gBAAgB;YAChB9vB;gBACIxqB,MAAM;gBACNmxD,UAAU;;YAEdL;gBACIuB,iBAAiB;gBACjBC,uBAAuB;gBACvBC,qBAAqB;;YAEzB/uD;gBACI4lC,QAAQ;;WAGhBsqB;YACI3vC,QAAQ;YACR4vC,aAAa;YACbC,oBAAoB;YACpBC,eAAe;YACfC,eAAe;YACfC,gBAAgB;YAChBC,cAAc;YACdC,UAAU;YACVC,MAAM;YACNC,MAAM;YACNC,sBAAsB;YACtB/9C,aAAa;YACbg+C,2BAA2B;YAC3BC,kBAAkB;YAClB34C,MAAM;YACN44C,SAAS;YACT74C,MAAM;YACNuE,QAAQ;YACR7J,OAAO;YACPo+C,gBAAgB;YAChBC,cAAc;YACdhwC,OAAO;YACPiwC,YAAY;YACZC,mBAAmB;YACnBC,cAAc;YACdC,UAAU;YACVC,gBAAgB;YAChBC,uBAAuB;YACvBC,WAAW;WAEfC,wBACAC,iCAAiC,IAAIp1D,GAAG+L,WACxCspD,+BAA+B,IAAIr1D,GAAG+L,WACtC5F,KACAmvD,qBACAC,qBACAC,aACAxzC,WACAiO,UACAwlC,gBACAC,aAKAC,6BAA6B;YACzB,IAAIC,kBAAmBv9C,QAAQ24C,aAAawB,uBACxCqD,aAAax9C,QAAQ24C,aAAayB,qBAClCh3C;gBACI8F,SAASoyC;gBACT7xC,OAAO4zC;;YAGf,IAAID,gBAAgB;gBAChB,IAAIG,iBAAiB;oBACjBv9C,QAAQmiC,eAAev4B,SAAS2zC,iBAAiB,IAAIhmB,SAASn0B,MAAMtE,KAChE,SAAS2+C;wBACLV,+BAA+BnpD,QAAQ6pD;uBAE3C;wBACIV,+BAA+BjpD;wBAC/BhG,IAAI,0DAA0DyvD,iBAAiB;;uBAItF;oBACDR,+BAA+BjpD;;gBAGnC,IAAI0pD,YAAY;oBACZx9C,QAAQmiC,eAAev4B,SAAS4zC,YAAY,IAAIjmB,SAASn0B,MAAMtE,KAC3D,SAAS2+C;wBACLT,6BAA6BppD,QAAQ6pD;uBAEzC;wBACIT,6BAA6BlpD;wBAC7BhG,IAAI,kEAAkE0vD,YAAY;;uBAIzF;oBACDR,6BAA6BlpD;;;WAOzC4pD,oBAAoB,SAASb;YACzB,IAAIc,sBAAsB,IAAIh2D,GAAG+L;YAEjCspD,6BAA6Bl+C,KAAK,SAAS+0B;gBACvC+pB,4BAA4B/pB,KAAKgpB;gBAEjC,KAAKA,UAAUllB,KAAK;oBAChBklB,UAAUllB,MAAM9D,IAAI8D;oBACpBklB,UAAUlpD,SAAS;wBACfkpD,UAAUlpD,SAAS;wBACnBkqD,KAAKhB;wBACLc,oBAAoB/pD;;uBAGvB;oBACD+pD,oBAAoB/pD;;eAEzB;gBAIC/L,KAAKg1D;gBACLc,oBAAoB/pD;;YAGxB,OAAO+pD;WAGXG,qBAAqB,SAASv7C,IAAInP,MAAMgQ;YACpC,IAAIy5C,YAAYkB,aAAax7C;YAE7BzU,IAAI,kCAAkCyU;YACtCnP,KAAK4qD,gBAAgBz7C;YAErB,OAAOvC,QAAQmiC,eAAev4B,SAASxW,MAAMypD,WAAWz5C,MAAMtE,KAC1D;gBACIq8C;gBACA0C,KAAKhB;gBACLC,kBAAkBv6C,IAAI3O;eAE1B;gBACIkpD,kBAAkBv6C,IAAIzO;gBAItB,KAAKkM,QAAQ24C,aAAauB,iBAAiB;oBACvC+D,+BAA+B17C,IAAIs6C;;;WAKnDqB,4BAA4B;YACxB,IAAI7C,qBAAqB3tD,QAAQ;gBAC7B0tD,+BAA+B;gBAE/B,IAAI+C,qBAAqB9C,qBAAqBhhD;gBAE9C,IAAI8jD,mBAAmBC,QAAQ;oBAC3BC,kCAAkCF;uBAEjC;oBACDG,+BAA+BH;;mBAGlC;gBACD/C,+BAA+B;;WAIvCmD,YAAY,SAASh8C;YACjB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBzzC;WAGtD22C,cAAc,SAASl8C;YACnB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBc;WAGtDqC,YAAY,SAASx2D;YACjB,OAAOs2D,cAAc70C,WAAW4xC,gBAAgBrzD,OAAO;WAG3Dy2D,YAAY,SAASp8C;YACjB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBe;WAGtDsC,oBAAoB;YAChB,OAAOJ,cAAc70C,WAAW4xC,gBAAgBoB;WAGpDkC,cAAc,SAASt8C;YACnB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBkB;WAGtD/yC,UAAU,SAASnH;YACf,OAAOu4C,UAAUG,IAAI14C,OAAO5a,GAAGiwB,UAAU9sB,gBAAgByvD,oBAAoBh4C;WAGjFzI,cAAc,SAASyI;YACnB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgB/3C;WAGtDs7C,WAAW,SAASv8C;YAChB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBt9C;WAGtD8gD,cAAc,SAASx8C;YAGnB,IAAIA,MAAM,MAAM;gBACZ,OAAOi8C,cAAc70C,WAAW4xC,gBAAgBW,8BAC5CsC,cAAc70C,WAAW4xC,gBAAgBY;;YAIjD,OAAOqC,cAAc90C,QAAQnH,KAAKg5C,gBAAgBU,yBAC9CuC,cAAc90C,QAAQnH,KAAKg5C,gBAAgBr9C;WAGnD8gD,WAAW,SAASz8C;YAChB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBjvC;WAGtD3B,UAAU,SAASpI;YACf,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBh4C;WAGtD07C,aAAa,SAAS18C;YAClB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBa;WAGtDoC,gBAAgB,SAAS3mD,SAASqnD;YAC9B,OAAOrnD,WAAWlQ,GAAGkQ,SAAS/M,gBAAgBo0D;WAGlDnB,eAAe,SAASx7C;YACpB,OAAO66C,kBAAkBoB,cAAc90C,QAAQnH,KAAKg5C,gBAAgBsB;WAGxEh1D,OAAO,SAAS0wC;YACZA,MAAM5wC,GAAG4wC,IAAIvuC,SAASgW,QAAQqS,QAAQxqB;WAM1C+1D,8BAA8B,SAAShkC,aAAaijC;YAChD,IAAIt9B,WAAW3F,YAAY9xB,MAAMy3B,UAC7BD,YAAY1F,YAAY9xB,MAAMw3B;YAElC,IAAIA,aAAaC,aAAas9B,UAAU/0D,MAAMy3B,aAAas9B,UAAU/0D,MAAMw3B,WAAW;gBAClF33B,GAAGk1D,WAAW5zD;oBACVs2B,UAAUA;oBACVD,WAAWA;;;WAQvB2+B,iCAAiC,SAAS17C,IAAIs6C;YAC1C,IAAIsC,aAAarC,kBAAkBv6C,OAAO,IAAI5a,GAAG+L,UAAUI,WACvDsrD,2BAA2B,IAAIz3D,GAAG+L;YAEtCqpD,+BAA+Bj+C,KAAK,SAAS+0B;gBACzCsrB,WAAWrgD,KACP;oBACIsgD,yBAAyBxrD;mBAE7B;oBACIgqD,4BAA4B/pB,KAAKgpB;oBAEjCA,UAAUlpD,SAAS;wBACfkpD,UAAUlpD,SAAS;wBACnByrD,yBAAyBxrD;;oBAG7BipD,UAAUllB,MAAM9D,IAAI8D;oBACpBkmB,KAAKhB;;;YAKjB,OAAOuC;WAWXC,sBAAsB;YAClB,IAAIC,UACAC,YACAC,cACAC,gBACAC,YACAC,eACApT,UACAsQ,WACAF,gBACAiD,YACAC;YAEJ/xD,IAAI;YAGJ,IAAIkS,QAAQ85C,kBAAkB,MAAM;gBAChC,MAAM,IAAI3wD,MAAM;;YAIpB,IAAIxB,GAAGwH,SAAS6Q,QAAQ85C,iBAAiB;gBACrCwF,WAAW9tD,SAASg9B,eAAexuB,QAAQ85C;gBAE3C,IAAIwF,aAAa,MAAM;oBACnB,MAAM,IAAIn2D,MAAMxB,GAAG8H,OAAO,2CAA2CuQ,QAAQ85C;;gBAGjFyF,aAAaD,SAASpoD;mBAErB;gBACD,IAAI8I,QAAQ85C,eAAe5iD,cAAcpL,WAAW;oBAChD,MAAM,IAAI3C,MAAM,mEACZ;;gBAGRo2D,aAAav/C,QAAQ85C,eAAe5iD;;YAGxCqoD,aAAa53D,GAAG0H,QAAQkwD;YACxBE,iBAAiBjuD,SAASC,cAAc;YACxCguD,eAAetmD,YAAYxR,GAAGoP,UAAUwoD;YACxCM,aAAal4D,GAAG83D,gBAAgB30D,gBAAgBywD,gBAAgBO;YAIhE,IAAI97C,QAAQ4L,QAAQ;gBAChB+zC,gBAAgBh4D,GAAG83D,gBAAgB30D,gBAAgBywD,gBAAgB3vC;gBACnE,IAAI+zC,eAAe;oBACfh4D,GAAGg4D,eAAe52D;;;YAS1B,KAAKpB,GAAGoiD,gBAAgBpiD,GAAGkT,kBAAkB8C,UAAU;gBACnDg/C,iBAAiBh1D,GAAG83D,gBAAgB30D,gBAAgBywD,gBAAgBoB;gBACpE,IAAIA,gBAAgB;oBAChBh1D,GAAGg1D,gBAAgB5zD;;;YAI3BwjD,WAAW5kD,GAAG83D,gBAAgB30D,gBAAgBywD,gBAAgBQ;YAI9D,IAAIxP,aAAa5kD,GAAGoiD,aAAa;gBAC7Bj8C,IAAI,2BAA2B;gBAC/BnG,GAAG4kD,UAAUxjD;;YAGjB,KAAKpB,GAAGkT,kBAAkB8C,UAAU;gBAEhCkiD,WAAWl+C,gBAAgBg5C;gBAE3B,IAAIpO,YAAY5kD,GAAG4kD,UAAU9gD,aAAaivD,qBAAqB;oBAI3D/yD,GAAG4kD,UAAUtjD;wBACTlB,SAAS;;;mBAIhB,IAAIJ,GAAGk4D,YAAYp0D,aAAakvD,wBAAwBpO,UAAU;gBACnEqT,aAAaj4D,GAAG4kD,UAAUzhD,gBAAgBywD,gBAAgBmB;gBAC1DkD,cAAcj4D,GAAGi4D,YAAY72D;;YAKjC8zD,YAAYl1D,GAAG83D,gBAAgB30D,gBAAgBywD,gBAAgBsB;YAC/D,KAAKO,gBAAgB;gBACjBP,aAAal1D,GAAGk1D,WAAW9zD;mBAE1B,IAAI8zD,WAAW;gBAChBvB,mBAAmB7vB,SAASoxB,UAAUhxD,aAAa2uD;gBAEnDc,mBAAmBA,mBAAmB,IAAIA,mBAAmB;gBAE7D+B,cAAc11D,GAAGk1D,WAAWpxD,aAAagvD;;YAE7C2C,iBAAiBA,kBAAkBP;YAEnCI,sBAAsBt1D,GAAG83D,gBAAgBt1D,WAAWoxD,gBAAgBiB,mBAAmB9uD,SAAS;YAChGwvD,sBAAsBv1D,GAAG83D,gBAAgBt1D,WAAWoxD,gBAAgBjvC,OAAO5e,SAAS;YAEpF8xD,eAAe73D,GAAG83D,gBAAgB30D,gBAAgBywD,gBAAgBS;YAElE,IAAIwD,gBAAgB,MAAM;gBACtB,MAAM,IAAIr2D,MAAM;;YAGpBu2D,aAAaF,aAAaz0D,SAAS,GAAG+0D,UAAU;YAChDN,aAAatoD,YAAY;YAGzB,IAAIuoD,eAAeh1D,qBAAqB,UAAUiD,QAAQ;gBACtD8D,SAASC,cAAc;;YAG3B3D,IAAI;YAEJ;gBACIirD,UAAU0G;gBACVM,cAAcL;;WAItBM,cAAc,SAASznB,IAAIx1B,OAAO6U;YAC9B,IAAIqoC,WAAWroC,UACXsoC,WAAWD,SAASh1D;YAExB,IAAI8X,QAAQ,GAAG;gBACXm9C,WAAWv4D,GAAGs4D,UAAUl1D,WAAWgY,OAAO5X;;YAI9C80D,SAASr3D,aAAa2vC,IAAI2nB;WAG9B5B,iCAAiC,SAASH;YACtC,IAAI57C,KAAK47C,mBAAmB57C,IACxB49C,gBAAgBhC,mBAAmBgC,eACnCC,qBAAqBD,iBAAiBA,cAAcnC,eACpDnB,YAAYkB,aAAax7C,KACzBa;gBACIgG,sBAAsB+0C,mBAAmB/0C;gBACzCF,SAASoyC;gBACT55B,QAAQ;gBACRjY,OAAO;;YAGf,IAAI9hB,GAAGkT,kBAAkBiD,eAAe;gBACpC,IAAI++C,WAAW;oBACX,IAAI78C,QAAQm+B,OAAO8b,aAAaj6C,QAAQm+B,OAAO8b,aAAakB,qBAAqB;wBAC7E8C,+BAA+B17C,IAAIs6C;wBACnCqB;2BAEC;wBACDR,kBAAkBb,WAAWt9C,KAAK;4BAC9Bu9C,kBAAkBv6C,MAAM,IAAI5a,GAAG+L;4BAE/BopD,kBAAkBv6C,IAAIhD,KAAK;gCACvBqS,WAAWssC,2BAA2Bl+C,QAAQm+B,OAAOob;;4BAMzD,IAAI6G,sBAAsB,MAAM;gCAC5BC,iBAAiB99C,IAAI69C;mCAEpB;gCACDtC,mBAAmBv7C,IAAI49C,eAAe/8C;;;;uBAMjD;oBACD86C;;mBAGH,IAAIrB,WAAW;gBAChBa,kBAAkBb;gBAClBqB;;WAIRG,oCAAoC,SAASF;YACzC,IAAI57C,KAAK47C,mBAAmB57C,IACxBkM,eAAe0vC,mBAAmB1vC,cAClC6xC,iBAAiBnC,mBAAmBmC,gBACpCzD,YAAYkB,aAAax7C,KACzBa;gBACIgG,sBAAsB+0C,mBAAmB/0C;gBACzCK,OAAO4zC;gBACPn0C,SAASoyC;;YAGjB,IAAIuB,WAAW;gBACX,IAAIpuC,cAAc;oBACd,IAAIzO,QAAQm+B,OAAO8b,aAAaj6C,QAAQm+B,OAAO8b,aAAakB,qBAAqB;wBAC7E8C,+BAA+B17C,IAAIs6C;wBACnCqB;2BAEC;wBACD,IAAIoC,gBAAgB;4BAChB5C,kBAAkBb;;wBAGtB,OAAO78C,QAAQmiC,eAAev4B,SAAS6E,cAAcouC,WAAWz5C,MAAMtE,KAClE;4BACI++C,KAAKhB;4BACL1B;4BACAvpC,WAAWssC,2BAA2Bl+C,QAAQm+B,OAAOob;2BAGzD;4BACI0E,+BAA+B17C,IAAIs6C;4BACnCjrC,WAAWssC,2BAA2Bl+C,QAAQm+B,OAAOob;;;uBAKhE;oBACD0E,+BAA+B17C,IAAIs6C;oBACnCqB;;;WAKZqC,sBAAsB,SAASh+C,IAAIi+C;YAC/B,IAAIC,MAAM1B,YAAYx8C,KAElBm+C,sBAAsBn+C,MAAM,OAAOg5C,gBAAgBY,mBAAmBZ,gBAAgBr9C;YAE1F,IAAIuiD,QAAQ94D,GAAG84D,KAAKh3D,SAASi3D,sBAAsB;gBAC/CD,MAAM94D,GAAG84D,KAAK31D,gBAAgB41D;;YAGlC,IAAID,KAAK;gBACL94D,GAAG84D,KAAKx3D;oBAAKkrC,OAAOqsB,UAAU;;gBAC9BC,IAAIvnD,aAAa,iBAAiBsnD;;WAI1C3C,OAAO,SAAStlB;YACZA,MAAM5wC,GAAG4wC,IAAItuC,YAAY+V,QAAQqS,QAAQxqB;WAG7Cw4D,mBAAmB,SAASM,mBAAmBC;YAC3C,IAAIC,kBAAkB9C,aAAa4C,oBAC/BG,kBAAkB/C,aAAa6C;YAEnC9yD,IAAInG,GAAG8H,OAAO,sFAAsFkxD,mBAAmBC,mBAAmBA;YAG1I9D,kBAAkB8D,mBAAmB9hD,KAAK;gBACtCq8C;gBACA2B,kBAAkB6D,mBAAmB/sD;gBACrC9F,IAAInG,GAAG8H,OAAO,wEAAwEmxD,mBAAmBD;gBACzGE,gBAAgBlpB,MAAMmpB,gBAAgBnpB;gBACtCkmB,KAAKgD;eAET;gBACI/D,kBAAkB6D,mBAAmB7sD;gBACrC,KAAKkM,QAAQ24C,aAAauB,iBAAiB;oBACvC+D,+BAA+B0C,mBAAmBE;;;;QAKlEl5D,GAAG6B,OAAOwW,SAASoD;QACnBtV,MAAMkS,QAAQlS;QAId,KAAKnG,GAAGkT,kBAAkBiD,eAAe;YACrCkC,QAAQm+B,OAAOob,oBAAoB;YACnCv5C,QAAQm+B,OAAO8b,YAAY;;QAG/BtwC,YAAY3J,QAAQ+5C;QACpBqD,iBAAiBp9C,QAAQmiC,mBAAmBr2C;QAC5CqxD,cAAckC;QAEd/B;QAEA31D,GAAG6B,OAAOxB;YACN8vC,QAAQ;gBACJhqC,IAAI;gBAEJqtD,sBAAsB;gBAEtBxxC,UAAUxQ,YAAYgkD,YAAYpE,SAAS+G,UAAU;gBACrDj4D,KAAK+2D;gBACL52D,KAAK+4D;gBACLnpC,WAAW5X,QAAQg6C,mBAAmBwE,cAAc70C,WAAW4xC,gBAAgBS;gBAE/EluD,IAAI;;YAGRusD,eAAe,SAAStsD;gBACpB,IAAIizD,eAAer5D,GAAGoP,UAAUhJ;gBAChC4b,UAAUzS,YAAY;gBACtByS,UAAUxQ,YAAY6nD;;YAG1Bn/C,OAAO;gBACH8H,UAAUzS,YAAY;gBACtBlP,KAAK8vC;;YAGT6X,YAAY;gBACR/3B,SAAS1gB,YAAY;;YAGzB+/C,eAAe;gBACXiE,mBAAmB;;YAGvB/3C,SAAS,SAASZ,IAAI7Y,MAAMu3D,aAAaC,aAAaC;gBAClD,IAAIC,SAASjE,YAAY4C,aAAaD,UAAU,OAC5CuB,aAAa7C,cAAc4C,QAAQ7F,gBAAgB/3C,OACnDq8C,aAAarB,cAAc70C,WAAW4xC,gBAAgBO,WACtDl0C,gBAAgBu5C,QAAQrG,UAAUC,UAAUnjC,UAC5C0pC;gBAEJ,IAAIH,OAAO;oBACPrG,UAAUG,IAAI14C,MAAM6+C;;gBAGxBz5D,GAAGy5D,QAAQp3D,SAASuwD,oBAAoBh4C;gBACxCs9C,WAAWl+C,gBAAgBg5C;gBAE3B,IAAI0G,YAAY;oBACZ15D,GAAG05D,YAAYj2D,QAAQ1B;oBACvB23D,WAAWnoD,aAAa,SAASxP;;gBAGrC03D,OAAOloD,aAAaohD,cAAc/3C;gBAElC,IAAI0+C,aAAa;oBACbjB,YAAYoB,QAAQH,YAAYl+C,OAAO6E;uBAEtC;oBACDA,cAAczO,YAAYioD;;gBAG9B,IAAIF,aAAa;oBACbE,OAAOt5D,MAAMC,UAAU;oBACvBJ,GAAGy5D,QAAQp3D,SAAS6wD;uBAEnB;oBACDhzD,KAAKk3D,YAAYx8C;oBACjB1a,KAAK8iB,QAAQpI;oBACb1a,KAAK82D,UAAUp8C;oBACf1a,KAAKm3D,SAASz8C;oBACd1a,KAAKi3D,SAASv8C;oBACd1a,KAAK42D,YAAYl8C;oBAEjB,IAAI24C,kBAAkB;wBAClBlzD,KAAKysD,WAAWlyC;;oBAGpB++C,QAAQvD,aAAax7C;oBACrB,IAAI++C,UAAUA,MAAM3pB,KAAK;wBACrBqlB,6BAA6Bl+C,KAAK,SAASyiD;4BACvCD,MAAM3pB,MAAM4pB,WAAW5pB;4BACvB,IAAI4pB,WAAWz5D,MAAMw3B,aAAaiiC,WAAWz5D,MAAMy3B,UAAU;gCACzD53B,GAAG25D,OAAOr4D;oCACNq2B,WAAWiiC,WAAWz5D,MAAMw3B;oCAC5BC,UAAUgiC,WAAWz5D,MAAMy3B;;;4BAInCs+B,KAAKyD;;;;;YAMrBlK,gBAAgB,SAAS70C,IAAI7Y,MAAMu3D,aAAaC;gBAC5Cl5D,KAAKmb,QAAQZ,IAAI7Y,MAAMu3D,aAAaC,aAAa;;YAGrDxR,eAAe;gBACX93B,SAASze,YAAY2hD,UAAUC;gBAC/BD,UAAUC,UAAUvpD,SAASwpD;gBAC7BF,UAAUG;;YAGd/J,YAAY,SAAS3uC;gBACjB5a,GAAG+hB,QAAQnH,KAAKxZ;;YAGpB8nD,WAAW,SAAStY;gBAChB,IAAIipB,cAAcjpB;gBAElB,IAAIipB,aAAa;oBAEb,OAAOA,YAAY31D,aAAayuD,iBAAiB,MAAM;wBACnDkH,cAAcA,YAAY14D;;oBAG9B,OAAO2iC,SAAS+1B,YAAY31D,aAAayuD;;;YAIjDmH,aAAa;gBACT,OAAO7pC;;YAGX+7B,sBAAsB,SAASpxC;gBAC3B,IAAI7I,WAAWI,YAAYyI;gBAE3B7I,YAAY/R,GAAG+R,UAAU1P,SAASgW,QAAQqS,QAAQ2mC;;YAGtDzI,gBAAgB,SAAShuC,IAAI7Y;gBACzB,IAAIg4D,aAAa5nD,YAAYyI;gBAE7B,IAAIm/C,YAAY;oBACZ/5D,GAAG+5D,YAAYt2D,QAAQ1B;oBACvBg4D,WAAWxoD,aAAa,SAASxP;;;YAIzC6pD,cAAc,SAAShxC;gBACnB1a,KAAKiS,YAAYyI;;YAGrBkxC,cAAc,SAASlxC;gBACnBs7C,KAAK/jD,YAAYyI;;YAGrBo/C,YAAY,SAASppB;gBACjB,OAAO5wC,GAAG4wC,IAAI9uC,SAAS8xD,gBAAgB/3C;;YAG3CuG,WAAW;gBACP,OAAO/J,QAAQ4L,UAAU4yC,cAAc70C,WAAW4xC,gBAAgB3vC;;YAGtEwmC,oBAAoB;gBAChBvqD,KAAK+2D;;YAGTzM,oBAAoB;gBAChB0L,KAAKe;;YAGT1M,aAAa;gBACT,OAAOsM,cAAc70C,WAAW4xC,gBAAgBQ;;YAGpDnJ,wBAAwB;gBACpB,OAAOqK;;YAGXrJ,WAAW,SAASrxC;gBAChB1a,KAAKm3D,SAASz8C;;YAGlB2yC,iBAAiB;gBACb,OAAOgI;;YAGX/H,WAAW,SAAS5yC;gBAChBs7C,KAAKmB,SAASz8C;;YAGlB0tC,kBAAkB,SAAS1tC;gBACvB,OAAOmH,QAAQnH;;YAGnBmxC,cAAc,SAASnxC;gBACnB,IAAIq/C,OAAO/C,YAAYt8C;gBAEvBq/C,QAAQj6D,GAAGi6D,MAAM53D,SAASgW,QAAQqS,QAAQ2mC;;YAG9ChJ,iBAAiB,SAASztC;gBACtB,OAAO5a,GAAG+hB,QAAQnH,KAAK9Y,SAASoxD;;YAGpCrH,cAAc,SAASjxC;gBACnB,IAAIq/C,OAAO/C,YAAYt8C;gBAEvBq/C,QAAQj6D,GAAGi6D,MAAM33D,YAAY+V,QAAQqS,QAAQ2mC;;YAGjD6I,YAAY,SAAStpB;gBACjB,OAAO5wC,GAAG4wC,IAAI9uC,SAAS8xD,gBAAgBkB,cAAc;;YAGzDpJ,cAAc,SAAS9wC;gBACnB,OAAOi8C,cAAc90C,QAAQnH,KAAKg5C,gBAAgBiB;;YAGtDsF,aAAa,SAASvpB;gBAClB,OAAO5wC,GAAG4wC,IAAI9uC,SAAS8xD,gBAAgBiB,mBAAmB;;YAG9DhI,gBAAgB,SAASjyC,IAAI6Q,QAAQC;gBACjC,IAAIotC,MAAM1B,YAAYx8C,KAClBi+C;gBAEJ,IAAIC,OAAOptC,QAAQ,GAAG;oBAClBmtC,UAAUl3D,KAAKC,MAAM6pB,SAASC,QAAQ;oBAEtC,IAAImtC,YAAY,KAAK;wBACjB34D,KAAK44D;2BAEJ;wBACD5C,KAAK4C;;oBAGTF,oBAAoBh+C,IAAIi+C;;;YAIhC1a,qBAAqB,SAAS1yB,QAAQC;gBAClCrrB,KAAKwsD,eAAe,MAAMphC,QAAQC;;YAGtCqhC,cAAc,SAASnyC;gBACnB,IAAIk+C,MAAM1B,YAAYx8C;gBAEtBk+C,OAAO54D,KAAK44D;;YAGhBM,mBAAmB;gBACf/4D,KAAK0sD;;YAGTsB,eAAe,SAASzzC;gBACpBg+C,oBAAoBh+C,IAAI;gBACxBva,KAAK+4D,kBAAkBx+C;;YAG3B4xC,oBAAoB;gBAChBnsD,KAAKguD;;YAGTf,YAAY,SAAS1yC;gBACjB,KAAK24C,kBAAkB;oBACnB,IAAIpzC,SAASy2C,UAAUh8C;oBAEvBuF,UAAUngB,GAAGmgB,QAAQ7d,YAAY+V,QAAQqS,QAAQxqB;;;YAIzD4sD,YAAY,SAASlyC;gBACjB1a,KAAK02D,UAAUh8C;;YAGnBw/C,UAAU,SAASxpB;gBACf,OAAO5wC,GAAG4wC,IAAI9uC,SAAS8xD,gBAAgBzzC,QAAQ;;YAGnD2tC,YAAY,SAASlzC;gBACjBs7C,KAAKiB,SAASv8C;gBACd1a,KAAK42D,YAAYl8C;;YAGrBiuC,cAAc,SAASjuC;gBACnBva,KAAK6rD,cAActxC,IAAIvC,QAAQ3U,KAAK4lC;gBACpCjpC,KAAKg6D,oBAAoBz/C;gBACzB1a,KAAKo3D,WAAW18C;;YAGpByxC,WAAW,SAASzxC;gBAChB1a,KAAKi3D,SAASv8C;;YAGlB0/C,SAAS,SAAS1pB;gBACd,OAAO5wC,GAAG4wC,IAAI9uC,SAAS8xD,gBAAgBt9C,OAAO;;YAGlDikD,kBAAkB,SAAS3pB;gBACvB,OAAO5wC,GAAG4wC,IAAI9uC,SAAS8xD,gBAAgBc,gBAAgB;;YAG3D2F,qBAAqB,SAASz/C;gBAC1Bs7C,KAAKY,YAAYl8C;gBACjB1a,KAAKi3D,SAASv8C;;YAGlBmuC,iBAAiB,SAASnuC;gBACtBva,KAAK6rD,cAActxC,IAAI;gBACvBva,KAAKytD,WAAWlzC;gBAChBs7C,KAAKoB,WAAW18C;;YAGpB+yC,kBAAkB,SAAS/yC;gBACvBs7C,KAAKc,UAAUp8C;;YAGnB+zC,kBAAkB,SAAS/zC;gBACvB1a,KAAK82D,UAAUp8C;;YAGnB4/C,gBAAgB,SAAS5pB;gBACrB,OAAO5wC,GAAG4wC,IAAI9uC,SAAS8xD,gBAAgBe,cAAc;;YAGzD8F,SAAS,SAAS7pB;gBACd,OAAO5wC,GAAG4wC,IAAI9uC,SAAS8xD,gBAAgBjvC,OAAO;;YAGlD3H,YAAY,SAASpC,IAAIlX;gBACrB,IAAIkY,OAAOoH,QAAQpI;gBAEnB,IAAIgB,MAAM;oBACNs6C,KAAKt6C;oBACL5b,GAAG4b,MAAMnY,QAAQC;;;YAIzBwoD,eAAe,SAAStxC,IAAIlX;gBACxB,IAAIg3D,SAAS7D,cAAc90C,QAAQnH,KAAKg5C,gBAAgBgB;gBAExD,IAAI8F,QAAQ;oBAER,IAAIh3D,QAAQ,MAAM;wBACd1D,GAAG06D,QAAQ72D;2BAEV;wBACD7D,GAAG06D,QAAQj3D,QAAQC;;;;YAK/B6oD,aAAa,SAAS3xC;gBAClB5a,GAAG+hB,QAAQnH,KAAKtY,YAAY2wD;gBAC5B/yD,KAAKo3D,WAAW18C;;YAGpBizC,aAAa,SAASjzC;gBAClB5a,GAAG+hB,QAAQnH,KAAKvY,SAAS4wD;gBACzBiD,KAAKoB,WAAW18C;;YAGpBg1C,iBAAiB,SAASh1C,IAAI49C,eAAe/2C;gBACzC,KAAKphB,KAAKgoD,gBAAgBztC,KAAK;oBAC3B84C,qBAAqBxwD;wBAAM0X,IAAIA;wBAAI6G,sBAAsBA;wBAAsB+2C,eAAeA;;qBAC7F/E,gCAAgC8C;;;YAIzC7G,iBAAiB,SAAS90C,IAAIkM,cAAc6xC,gBAAgBl3C;gBACxD,KAAKphB,KAAKgoD,gBAAgBztC,KAAK;oBAC3B84C,qBAAqBxwD;wBAAMue,sBAAsBA;wBAAsBg1C,QAAQ;wBAAM77C,IAAIA;wBAAIkM,cAAcA;wBAAc6xC,gBAAgBA;;qBACxIlF,gCAAgC8C;;;YAIzC1E,WAAW,SAAStxD;gBAChB,OAAOP,GAAGkT,kBAAkB4C,mBAAmBihD,UAAUx2D;;YAG7DuxD,YAAY,SAASvxD,MAAM6F,SAAS4rD;gBAChC,IAAI2I,SAAS5D,UAAUx2D,OACnBq6D,YAAY/D,cAAc8D,QAAQ/G,gBAAgBI,gBAClD6G,UAAUF,OAAO73D,qBAAqB,SAAS,IAC/Cg4D,YAAYjE,cAAc8D,QAAQ/G,gBAAgBE,qBAClDiH,QAAQlE,cAAc8D,QAAQ/G,gBAAgBK,iBAC9CnoD,UAAU,IAAI9L,GAAG+L,WAEjBivD,eAAe;oBACXF,UAAUl6D,oBAAoB,SAASq6D;oBACvCF,SAASA,MAAMn6D,oBAAoB,SAASs6D;oBAC5CpvD,QAAQK;mBAGZ8uD,qBAAqB;oBACjBH,UAAUl6D,oBAAoB,SAASq6D;oBACvCN,OAAOQ;mBAGXD,iBAAiB;oBACbP,OAAO/5D,oBAAoB,SAASo6D;oBACpCD,MAAMn6D,oBAAoB,SAASs6D;oBACnCP,OAAOQ;oBAEPrvD,QAAQG,QAAQ4uD,WAAWA,QAAQ9zD;;gBAG3C4zD,OAAOl6D,iBAAiB,SAASu6D;gBACjCF,UAAUr6D,iBAAiB,SAASw6D;gBACpCF,SAASA,MAAMt6D,iBAAiB,SAASy6D;gBAEzC,IAAIL,SAAS;oBACTA,QAAQ9zD,QAAQirD;;gBAEpB4I,UAAUh3D,cAAcwC;gBAExBu0D,OAAOS;gBAEP,OAAOtvD;;;;IChhCnB9L,GAAGq7D,iBAAiB,SAASC,GAAGC;QAC5B;QAEA,IAAI9oD,WAAW,IAAIzS,GAAGsS,kBAClBmJ;YACI+/C,WAAW;YACXC,UAAU;YACVC,WAAW,SAASjvD,QAAQ+oB;;QAKpCx1B,GAAG6B,OAAOxB;YACNusD,YAAY,SAAS3sD;gBACjB2sD,WAAW3sD;;YAGfuS,SAAS;gBACLC,SAASD;;;QAIjB,SAASo6C,WAAW3sD;YAChBwS,SAASnS,OAAOL,SAASwb,KAAK+/C,WAAW,SAAShmC;gBAE9CA,QAAQA,SAASxwB,OAAOwwB;gBAGxB,IAAI/oB,SAAS+oB,MAAM/oB,UAAU+oB,MAAMmmC;gBAEnClgD,KAAKigD,UAAUjvD,QAAQ+oB;;;QAK/Bx1B,GAAG6B,OAAO05D;YACNK,mBAAmB,SAASt0D;gBACxB,OAAOA,KAAKu0D;;YAGhBC,mBAAmB;gBACf,OAAOrpD;;;QAIfzS,GAAG6B,OAAO4Z,MAAM6/C;QAEhB,IAAI7/C,KAAKggD,UAAU;YACf7O,WAAWnxC,KAAKggD;;;IClDxBz7D,GAAGypD,0BAA0B,SAAS6R;QAClC;QAEA,IAAIS,2BACAtgD;YACI4uC,YAAY;YACZlkD,KAAK,SAASC,SAASukD;YACvBC,cAAc,SAASvpC;YACvByK,UAAU,SAASzK;YACnBwpC,SAAS,SAASxpC;YAClBypC,SAAS,SAASzpC;YAClB0pC,YAAY,SAAS1pC;YACrB2pC,WAAW,SAAS3pC;WAExB26C;YACI77C,QAAQ,SAASvF;gBAAMa,KAAKqQ,SAASlR;;YACrC+J,OAAQ,SAAS/J;gBAAMa,KAAKovC,QAAQjwC;;YACpC+5C,cAAc,SAAS/5C;gBAAMa,KAAKmvC,aAAahwC;;YAC/CtE,OAAO,SAASsE;gBAAMa,KAAKqvC,QAAQlwC;;YACnC85C,gBAAgB,SAAS95C;gBAAMa,KAAKsvC,WAAWnwC;;;QAGvD,SAASqhD,aAAaxvD,QAAQ+oB;YAC1Bx1B,GAAG+C,KAAKi5D,gBAAgB,SAASE,YAAYtsC;gBACzC,IAAIusC,2BAA2BD,WAAWnsD,OAAO,GAAG0X,gBAAgBy0C,WAAWh0D,MAAM,IACjFmZ;gBAEJ,IAAI5F,KAAK4uC,WAAW,OAAO8R,0BAA0B1vD,SAAS;oBAC1D4U,SAAS5F,KAAK4uC,WAAWnB,UAAUz8C;oBACnCzM,GAAGiP,eAAeumB;oBAClB/Z,KAAKtV,IAAInG,GAAG8H,OAAO,gEAAgE2T,KAAKuvC,UAAU3pC,SAASA;oBAC3GuO,QAAQvO;oBACR,OAAO;;;;QAKnBrhB,GAAG6B,OAAO4Z,MAAM6/C;QAEhB7/C,KAAK+/C,YAAY;QACjB//C,KAAKigD,YAAYO;QACjBxgD,KAAKggD,WAAWhgD,KAAK4uC,WAAWyP;QAEhC95D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGq7D,eAAe5/C,MAAMsgD;;IC1ChD/7D,GAAGkrD,uBAAuB,SAASoQ;QAC/B;QAEA,IAAIS,2BACAtgD;YACI4uC,YAAY;YACZlkD,KAAK,SAASC,SAASukD;YACvBjgC;gBACI7O,MAAM;gBACNi5C,cAAc;;YAElBzJ,mBAAmB,SAAShqC;YAC5B2pC,WAAW,SAAS3pC;;QAG5BrhB,GAAG6B,OAAO4Z,MAAM6/C;QAGhB,SAASW,aAAaxvD,QAAQ+oB;YAC1B,IAAI/Z,KAAK4uC,WAAW2P,WAAWvtD,WAAWgP,KAAK4uC,WAAW6P,WAAWztD,SAAS;gBAC1E,IAAI4U,SAAS5F,KAAK4uC,WAAWnB,UAAUz8C,SACnCwO,SAASQ,KAAK4vC,kBAAkBhqC;gBAGpC,IAAIpG,WAAWjb,GAAGib,OAAOsC,WAAW;oBAChC9B,KAAKtV,IAAInG,GAAG8H,OAAO,6DAA6D2T,KAAKuvC,UAAU3pC,SAASA;oBACxGrhB,GAAGiP,eAAeumB;oBAElBumC,qBAAqBK,mBAAmB/6C,QAAQ5U,QAAQ;;;;QAKpEgP,KAAK+/C,YAAY;QACjB//C,KAAKigD,YAAYO;QAEjBj8D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGq8D,oBAAoB5gD,MAAMsgD;;ICpCrD/7D,GAAGssD,8BAA8B,SAASgP,GAAGS;QACzC;QAEA,IAAItgD;YACI4uC,YAAY;YACZgB,mBAAmB,SAAShqC;YAC5Blb,KAAK,SAASC,SAASukD;;QAG/B,KAAKoR,sBAAsB;YACvBA;;QAIJ,SAASO,iBAAiB7vD,QAAQ+oB;YAC9B,IAAI/Z,KAAK4uC,WAAW8P,YAAY1tD,SAAS;gBACrC,IAAI4U,SAAS5F,KAAK4uC,WAAWnB,UAAUz8C,SACnCwO,SAASQ,KAAK4vC,kBAAkBhqC;gBAEpC,IAAIpG,WAAWjb,GAAGib,OAAOsC,WAAW;oBAChC9B,KAAKtV,IAAInG,GAAG8H,OAAO,mEAAmE2T,KAAKuvC,UAAU3pC,SAASA;oBAC9G06C,qBAAqBK,mBAAmB/6C,QAAQ5U;;;;QAK5DgP,KAAK+/C,YAAY;QACjB//C,KAAKigD,YAAYY;QAEjBt8D,GAAG6B,OAAO4Z,MAAM6/C;QAChBt7D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGq8D,oBAAoB5gD,MAAMsgD;;ICzBrD/7D,GAAGmrD,4BAA4B,SAAS1vC;QACpC;QAEAA,KAAK+/C,YAAY;QACjB//C,KAAKggD,WAAW;QAEhBz7D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGssD,4BAA4B7wC;;ICVvDzb,GAAGq8D,sBAAsB,SAASf,GAAGS;QACjC;QAEA,IAAItgD;YACI4uC,YAAY;YACZlkD,KAAK,SAASC,SAASukD;YACvBU,mBAAmB,SAAShqC;YAC5B2pC,WAAW,SAAS3pC;YACpBiqC,WAAW,SAASjqC,QAAQtE;YAC5BwuC,uBAAuB,SAASlqC,QAAQmqC;;QAGhD,SAAS+Q,yBAAyBl7C;YAC9B,IAAIm7C,kBAAkB/gD,KAAKuvC,UAAU3pC,SACjCrP,SAASwqD,gBAAgBvqD,YAAY;YAEzC,IAAID,SAAS,GAAG;gBACZwqD,kBAAkBA,gBAAgBtqD,OAAO,GAAGF;;YAGhD,OAAOwqD;;QAGX,SAASC,qBAAqBp7C;YAC1B,IAAIq7C,WAAWjhD,KAAKuvC,UAAU3pC;YAC9B,OAAOrhB,GAAG8R,aAAa4qD;;QAI3B,SAASC,iBAAiBC,oBAAoBv7C;YAC1C,IAAItE,UAAU6/C,mBAAmB71D,OAC7B81D;YAEJ,IAAI9/C,YAAY5Y,aAAanE,GAAG0H,QAAQqV,SAAShX,SAAS,GAAG;gBACzD82D,gBAAgBJ,qBAAqBp7C;gBAErC,IAAIw7C,kBAAkB14D,WAAW;oBAC7B4Y,UAAUA,UAAU,MAAM8/C;;gBAG9BphD,KAAK6vC,UAAUjqC,QAAQtE;;YAG3BtB,KAAK8vC,sBAAsBlqC,QAAQ;;QAIvC,SAASy7C,yBAAyBjC,SAASx5C;YACvC06C,qBAAqBD,oBAAoBx7D,OAAOu6D,SAAS,QAAQ;gBAC7D8B,iBAAiB9B,SAASx5C;;;QAKlC,SAAS07C,6BAA6BlC,SAASx5C;YAC3C06C,qBAAqBD,oBAAoBx7D,OAAOu6D,SAAS,SAAS,SAASrlC;gBAEvE,IAAInE,OAAOmE,MAAMwnC,WAAWxnC,MAAMynC;gBAElC,IAAI5rC,SAAS,IAAI;oBACbsrC,iBAAiB9B,SAASx5C;;;;QAKtCrhB,GAAG6B,OAAO4Z,MAAM6/C;QAEhB7/C,KAAKggD,WAAWhgD,KAAK4uC,WAAWyP;QAEhC95D,GAAG6B,OAAOxB,MAAM,IAAIL,GAAGq7D,eAAe5/C,MAAMsgD;QAE5C/7D,GAAG6B,OAAOk6D;YACNK,oBAAoB,SAASxhD,IAAInO,QAAQywD;gBACrC,IAAIN,qBAAqBnhD,KAAK4uC,WAAWqB,aAAa9wC;gBAEtDa,KAAK8vC,sBAAsB3wC,IAAI;gBAE/BgiD,mBAAmB71D,QAAQw1D,yBAAyB3hD;gBAEpD,IAAIsiD,YAAY;oBACZN,mBAAmBO;;gBAGvBL,yBAAyBF,oBAAoBhiD;gBAC7CmiD,6BAA6BH,oBAAoBhiD;;;;G3CvF9B5V","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"
tag\n if (innerHtml && innerHtml.match(/^= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5533,12 +5793,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5566,6 +5821,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5653,9 +5916,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5695,8 +5955,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5721,6 +5983,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -5773,7 +6037,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -5856,6 +6120,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6584,7 +6850,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6716,7 +6982,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -6780,15 +7046,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -6894,13 +7160,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -6912,6 +7178,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -6921,7 +7188,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } @@ -7411,4 +7678,4 @@ }); }; })(window); -//# sourceMappingURL=fine-uploader.js.map +//# sourceMappingURL=fine-uploader.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.js.map b/styles/bootstrap/fine-uploader/fine-uploader.js.map index f04b96e4a..a87518cba 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"
= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -2912,7 +3034,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -2950,13 +3073,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -2965,8 +3089,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -2978,30 +3100,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3077,7 +3214,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3113,6 +3255,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3120,7 +3263,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3193,12 +3339,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3277,6 +3437,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3296,6 +3463,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3486,7 +3656,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3524,7 +3706,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3561,15 +3746,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3628,7 +3819,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3648,8 +3839,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3659,7 +3853,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3717,6 +3911,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3726,6 +3921,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3736,6 +3932,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -3792,10 +3991,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5322,18 +5523,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5355,7 +5562,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5371,7 +5578,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5382,17 +5589,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5407,42 +5629,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5458,6 +5712,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5469,24 +5724,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5506,7 +5766,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5533,12 +5793,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5566,6 +5821,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5653,9 +5916,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5695,8 +5955,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5721,6 +5983,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -5773,7 +6037,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -5856,6 +6120,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6584,7 +6850,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6716,7 +6982,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -6780,15 +7046,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -6894,13 +7160,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -6912,6 +7178,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -6921,7 +7188,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } @@ -7411,4 +7678,4 @@ }); }; })(window); -//# sourceMappingURL=fine-uploader.js.map +//# sourceMappingURL=fine-uploader.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.js.map b/styles/bootstrap/fine-uploader/fine-uploader.js.map index f04b96e4a..a87518cba 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"
tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","self","disposeSupport","options","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","dropZoneElements","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA,QCEV,GAAIC,IAAK,SAASC,GACd,YAEA,QACIC,KAAM,WAEF,MADAD,GAAQE,MAAMC,QAAU,OACjBC,MAIXC,OAAQ,SAASC,EAAMC,GAMnB,MALIP,GAAQQ,iBACRR,EAAQQ,iBAAiBF,EAAMC,GAAI,GAC5BP,EAAQS,aACfT,EAAQS,YAAY,KAAOH,EAAMC,GAE9B,WACHR,GAAGC,GAASU,OAAOJ,EAAMC,KAIjCG,OAAQ,SAASJ,EAAMC,GAMnB,MALIP,GAAQW,oBACRX,EAAQW,oBAAoBL,EAAMC,GAAI,GAC/BP,EAAQS,aACfT,EAAQY,YAAY,KAAON,EAAMC,GAE9BH,MAGXS,SAAU,SAASC,GAKf,QAAKA,IAKDd,IAAYc,IAIZd,EAAQa,SACDb,EAAQa,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwBf,OAOrDgB,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAahB,EAASiB,GACnCb,MAGXe,OAAQ,WAEJ,MADAnB,GAAQkB,WAAWE,YAAYpB,GACxBI,MAOXiB,IAAK,SAASC,GAEV,GAAqB,MAAjBtB,EAAQE,MACR,KAAM,IAAIH,IAAGwB,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1BxB,GAAQE,MAAMsB,SAAqD,SAArBxB,EAAe,UACpEsB,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9EzB,GAAG6B,OAAO5B,EAAQE,MAAOoB,GAElBlB,MAGXyB,SAAU,SAASC,EAAMC,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAUH,EAAO,QACrC,OAAOE,GAAGE,KAAKlC,EAAQmC,eAAiBJ,IAAkBC,EAAGE,KAAKlC,EAAQkB,WAAWiB,aAGzFC,SAAU,SAASN,GAIf,MAHK/B,IAAGC,GAAS6B,SAASC,KACtB9B,EAAQmC,WAAa,IAAML,GAExB1B,MAGXiC,YAAa,SAASP,GAClB,GAAIE,GAAK,GAAIC,QAAO,QAAUH,EAAO,QAErC,OADA9B,GAAQmC,UAAYnC,EAAQmC,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtElC,MAGXmC,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASxC,EAAQ2C,cACV3C,EAAQ2C,cAAc,IAAMR,GAE9BnC,EAAQ4C,iBACN5C,EAAQ4C,iBAAiB,IAAMT,IAG1CM,EAAazC,EAAQ6C,qBAAqB,KAE1C9C,GAAG+C,KAAKL,EAAY,SAASM,EAAKC,GAC1BjD,GAAGiD,GAAKnB,SAASM,IACjBO,EAAOO,KAAKD,KAGbR,EAAQE,EAAO,GAAKA,IAG/BQ,gBAAiB,SAASf,GACtB,MAAOpC,IAAGC,GAASuC,WAAWJ,GAAW,IAG7CgB,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQpD,EAAQqD,WAEbD,GACoB,IAAnBA,EAAME,UACNH,EAASF,KAAKG,GAElBA,EAAQA,EAAMG,WAGlB,OAAOJ,IAGXK,QAAS,SAASC,GAGd,MAFAzD,GAAQ0D,UAAYD,EACpBzD,EAAQ2D,YAAcF,EACfrD,MAGXwD,UAAW,WACP,MAAO7D,IAAGC,GAASwD,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAI/D,GAAQ6D,eAEH7D,EAAQ6D,aAAaC,IAKkC,MAArD,WAAaE,KAAKhE,EAAQiE,aAAaH,KAG9CC,EAAU/D,EAAQ8D,GAEFI,SAAZH,GAKiC,MAA9B,WAAaC,KAAKD,QAMxC,WACG,YAEAhE,IAAGoE,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAOvE,IAAGwE,cAAcH,EAAOI,UAAUH,EAAMC,KAGnDvE,GAAGwE,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAASC,EAAMV,GACxB,GAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,IAyB3C,OAlBIM,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlCnB,EAAWJ,EAAaG,IAGnC9E,GAAGmG,IAAM,SAASC,EAASC,GACnBnB,OAAOoB,UACFD,GAAmB,SAAVA,EAKNnB,OAAOoB,QAAQD,GACfnB,OAAOoB,QAAQD,GAAOD,GAGtBlB,OAAOoB,QAAQH,IAAI,IAAME,EAAQ,KAAOD,GAR5ClB,OAAOoB,QAAQH,IAAIC,KAc/BpG,GAAGuG,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAASjD,UAAyD,oBAA7CkD,OAAOC,UAAUC,SAASC,KAAKJ,IAG5ExG,GAAG6G,WAAa,SAASL,GACrB,MAA6B,kBAAf,IASlBxG,GAAG8G,QAAU,SAASC,GAClB,MAAiD,mBAA1CN,OAAOC,UAAUC,SAASC,KAAKG,IACjCA,GAAS7B,OAAOY,aAAeiB,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBnB,aAIrF9F,GAAGkH,WAAa,SAASC,GACrB,MAAyD,kCAAlDV,OAAOC,UAAUC,SAASC,KAAKO,IAK1CnH,GAAGoH,WAAa,SAASC,GACrB,MAAyD,sBAAlDZ,OAAOC,UAAUC,SAASC,KAAKS,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CvH,GAAGwH,SAAW,SAASC,GACnB,MAAuD,oBAAhDhB,OAAOC,UAAUC,SAASC,KAAKa,IAG1CzH,GAAG0H,QAAU,SAASC,GAClB,MAAIC,QAAOlB,UAAUmB,KACVF,EAAOE,OAGXF,EAAOpF,QAAQ,aAAc,KAOxCvC,GAAG8H,OAAS,SAASC,GAEjB,GAAIC,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,GAC9CC,EAASL,EACTM,EAAmBD,EAAOzC,QAAQ,KAetC,OAbA3F,IAAG+C,KAAKiF,EAAM,SAAShF,EAAKC,GAQxB,GAJAmF,EAHgBA,EAAOE,UAAU,EAAGD,GAGfpF,EAFNmF,EAAOE,UAAUD,EAAmB,GAGnDA,EAAmBD,EAAOzC,QAAQ,KAAM0C,EAAmBpF,EAAI8C,QAG3DsC,EAAmB,EACnB,OAAO,IAIRD,GAGXpI,GAAGuI,OAAS,SAASC,GACjB,MAAOtD,QAAOuD,MAAsD,kBAA9ChC,OAAOC,UAAUC,SAASC,KAAK4B,IAGzDxI,GAAG0I,WAAa,SAASC,GACrB,MAAOzD,QAAO0D,UAA8D,sBAAlDnC,OAAOC,UAAUC,SAASC,KAAK+B,IAG7D3I,GAAG6I,cAAgB,SAASC,GACxB,MAAO9I,IAAGuI,OAAOO,IAAqB9I,GAAG+I,QAAQD,IAGrD9I,GAAG+I,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAAS3I,GACxB,GAAI4I,GAAiB5I,EAAK6I,aAE1B,OAAIH,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAIjE,OAAOmE,kBAC4C,8BAA/C5C,OAAOC,UAAUC,SAASC,KAAKoC,IAC3BA,EAAWzI,MAAQ2I,EAAaF,EAAWzI,WAKnDyI,EAAWM,SAC8B,UAArCN,EAAWM,QAAQF,eACfJ,EAAWzI,MAAQ2I,EAAaF,EAAWzI,QAS3DP,GAAGuJ,OAAS,SAASC,GACjB,GAAItE,OAAOO,MAAsD,kBAA9CgB,OAAOC,UAAUC,SAASC,KAAK4C,GAC9C,OAAO,GAIfxJ,GAAGyJ,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAMnJ,KAAO,OAGU4D,SAAnBuF,EAAMG,UACc,mBAATpB,OACa,mBAAbqB,WACoC,SAAnC9J,GAAG+J,oBAAqBC,QAI5ChK,GAAG+J,kBAAoB,WACnB,GAAI7E,OAAO+E,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOC,GAEH,MADAnK,IAAGmG,IAAI,wCAAyC,SACzC,OAIfnG,GAAGoK,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMvE,OAAS,GAC5BsE,EAAaC,MAAM,GAAGC,kBAG9BvK,GAAGwK,wBAA0B,WACzB,OAAQxK,GAAGyK,gBACPzK,GAAGyJ,yBACuBtF,SAAzBsE,KAAK/B,UAAUwB,OAAsD/D,SAA/BsE,KAAK/B,UAAUgE,aAAyDvG,SAA5BsE,KAAK/B,UAAUiE,WAG1G3K,GAAG4K,UAAY,SAASC,EAAYC,EAAOC,GAGvC,OAFaF,EAAW3C,OAAS2C,EAAWF,UAAYE,EAAWH,aAErD9D,KAAKiE,EAAYC,EAAOC,IAG1C/K,GAAGgL,iBAAmB,SAAShE,GAC3B,GAAIiE,GAAa,GACbC,EAAQ,GAAIlF,YAAWgB,EAY3B,OAVAhH,IAAG+C,KAAKmI,EAAO,SAASlI,EAAKmI,GACzB,GAAIC,GAAeD,EAAIxE,SAAS,GAE5ByE,GAAarF,OAAS,IACtBqF,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXjL,GAAGqL,cAAgB,SAASC,EAAMC,EAAaxF,GAC3C,GAAIyF,GAAcxL,GAAG4K,UAAUU,EAAMC,EAAaA,EAAcxF,GAC5D0F,EAAa,GAAIC,YACjBC,EAAU,GAAI3L,IAAG4L,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQ9L,GAAGgL,iBAAiBS,EAAW9I,UAGnD8I,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGX3L,GAAG6B,OAAS,SAASY,EAAOyJ,EAAQC,GAahC,MAZAnM,IAAG+C,KAAKmJ,EAAQ,SAASE,EAAMnJ,GACvBkJ,GAAgBnM,GAAGuG,SAAStD,IACRkB,SAAhB1B,EAAM2J,KACN3J,EAAM2J,OAEVpM,GAAG6B,OAAOY,EAAM2J,GAAOnJ,GAAK,IAG5BR,EAAM2J,GAAQnJ,IAIfR,GAaXzC,GAAGqM,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACAC,EAASF,EAASC,EAUtB,OARAxM,IAAG+C,KAAK0J,EAAQ,SAASC,EAAaC,GACNxI,SAAxBmI,EAAOI,KACPF,EAAOE,GAAeJ,EAAOI,IAGjCJ,EAAOI,GAAeC,IAGnBL,GAMXtM,GAAG2F,QAAU,SAASiH,EAAKC,EAAKC,GAC5B,GAAIF,EAAIjH,QACJ,MAAOiH,GAAIjH,QAAQkH,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAI7G,MAMd,KAJI+G,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIX9M,GAAGiN,YAAc,WACb,MAAO,uCAAuC1K,QAAQ,QAAS,SAAS2K,GAEpE,GAAIC,GAAoB,GAAhBxL,KAAKyL,SAAgB,CAC7B,QADyC,KAALF,EAAWC,EAAS,EAAJA,EAAU,GACrDxG,SAAS,OAM1B3G,GAAGqN,GAAK,WACJ,MAAOC,WAAUC,UAAU5H,QAAQ,WAAY,GAC3C2H,UAAUC,UAAU5H,QAAQ,cAAe,GAGnD3F,GAAGwN,IAAM,WACL,MAAOF,WAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAGyN,IAAM,WACL,MAAOH,WAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAG0N,KAAO,WACN,MAAOJ,WAAUC,UAAU5H,QAAQ,cAAe,GAGtD3F,GAAG2N,KAAO,WACN,MAAO3N,IAAGqN,MAAQC,UAAUC,UAAU5H,QAAQ,YAAa,GAG/D3F,GAAG4N,KAAO,WACN,MAAON,WAAUC,UAAU5H,QAAQ,SAAW,GAGlD3F,GAAG6N,OAAS,WACR,MAA4B1J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,YAAa,GAGnF3F,GAAG+N,OAAS,WACR,MAA4B5J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,aAAc,GAGpF3F,GAAGgO,MAAQ,WACP,MAA4B7J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,YAAa,GAGnF3F,GAAGiO,QAAU,WACT,OAASjO,GAAG4N,SAAW5N,GAAG2N,QAAUL,UAAUC,UAAU5H,QAAQ,cAAe,GAA2BxB,SAArBmJ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrI9N,GAAGkO,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrBnO,GAAGoO,QAAU,WACT,MAAOd,WAAUC,UAAUnE,cAAczD,QAAQ,cAAe,GAKpE3F,GAAGyK,aAAe,WACd,MAAOzK,IAAGoO,WAAad,UAAUC,UAAUnE,cAAczD,QAAQ,UAAY,GAGjF3F,GAAGqO,KAAO,WACN,MAAOrO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAGjE3F,GAAGuO,KAAO,WACN,MAAOvO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAGjE3F,GAAGwO,KAAO,WACN,MAAOxO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAIjE3F,GAAGyO,OAAS,WACR,MAAOzO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,eAAgB,GAGnE3F,GAAGsO,IAAM,WAEL,MAAOhB,WAAUC,UAAU5H,QAAQ,WAAY,GACxC2H,UAAUC,UAAU5H,QAAQ,WAAY,GACxC2H,UAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAG0O,UAAY,WACX,MAAO1O,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,YAAa,GAGhE3F,GAAG2O,UAAY,WACX,MAAO3O,IAAGsO,QAAUtO,GAAG0O,aAAepB,UAAUC,UAAU5H,QAAQ,aAAc,GAGpF3F,GAAG4O,iBAAmB,WAClB,MAAO5O,IAAGsO,QAAUtO,GAAG0O,cAAgB1O,GAAG2O,aAM9C3O,GAAG6O,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxB/O,GAAGgP,UAAa,WACZ,GAAIC,GAAMtF,SAASC,cAAc,MACjC,OAAO,UAASsF,GACZD,EAAIE,UAAYD,CAChB,IAAIjP,GAAUgP,EAAI3L,UAElB,OADA2L,GAAI5N,YAAYpB,GACTA,MAKfD,GAAG+C,KAAO,SAASqM,EAAcC,GAC7B,GAAIC,GAAYC,CAEhB,IAAIH,EAEA,GAAIlK,OAAOsK,SAAWJ,EAAanI,cAAgB/B,OAAOsK,QACtD,IAAKF,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASD,EAAaK,IAAIH,GAAaF,EAAaM,QAAQN,EAAaK,IAAIH,KAClFC,KAAW,GAFoCD,SAStD,IAAItP,GAAG8G,QAAQsI,IAAiBpP,GAAGkH,WAAWkI,IAAiBpP,GAAGoH,WAAWgI,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GAFoCD,SAOtD,IAAItP,GAAGwH,SAAS4H,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASC,EAAYF,EAAaO,OAAOL,IAC9CC,KAAW,GAFoCD,SAQvD,KAAKA,IAAcF,GACf,GAAI3I,OAAOC,UAAUsG,eAAepG,KAAKwI,EAAcE,KACnDC,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GACX,OASxBvP,GAAG4P,KAAO,SAASC,EAASC,GACxB,GAAI9P,GAAG6G,WAAWgJ,GAAU,CACxB,GAAI7H,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,EAElD,OAAO,YACH,GAAI4H,GAAU/P,GAAG6B,UAAWmG,EAI5B,OAHIG,WAAUpC,SACVgK,EAAUA,EAAQC,OAAO/H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,aAEjD0H,EAAQI,MAAMH,EAASC,IAItC,KAAM,IAAIvO,OAAM,wCAmBpBxB,GAAGkQ,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQjO,KAAKiO,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAWpN,KACa,gBAAZuN,GACFzQ,GAAGkQ,QAAQO,EAASE,GAAU,GACe,sBAA5ClK,OAAOC,UAAUC,SAASC,KAAK6J,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAKpO,KAAKiO,GAAU,MAAMjO,KAAKiO,GAAS,GAAK,IAAM,IAC7DE,EAAWpN,KAAKkN,GAChBE,EAAWpN,KAAKlD,GAAGkQ,QAAQC,KACqB,mBAAxC1J,OAAOC,UAAUC,SAASC,KAAKuJ,IAA8C,SAARA,EAC7EnQ,GAAG+C,KAAKoN,EAAK,SAASnN,EAAKC,GACvBuN,EAAIvN,EAAKD,KAEU,SAARmN,GAAiC,OAARA,GAAiC,gBAARA,GACjEnQ,GAAG+C,KAAKoN,EAAK,SAAS/D,EAAMnJ,GACxBuN,EAAIvN,EAAKmJ,KAGbkE,EAAWpN,KAAK0N,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBhO,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7BvC,GAAG8Q,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAIjH,WAGnB9J,GAAG+C,KAAKoN,EAAK,SAASV,EAAKxM,GACvBwM,EAAMuB,EAAeA,EAAe,IAAMvB,EAAM,IAAMA,EAElDzP,GAAGuG,SAAStD,GACZjD,GAAG8Q,aAAa7N,EAAK8N,EAAUtB,GAE1BzP,GAAG6G,WAAW5D,GACnB8N,EAASxL,OAAOkK,EAAKxM,KAGrB8N,EAASxL,OAAOkK,EAAKxM,KAItB8N,GAGX/Q,GAAGiR,WAAa,SAASd,EAAKe,GAC1B,GAAIxH,EAeJ,OAbKwH,KACDA,EAAOvH,SAASC,cAAc,SAGlC5J,GAAG8Q,aAAaX,GACZ5K,OAAQ,SAASkK,EAAKxM,GAClByG,EAAQC,SAASC,cAAc,SAC/BF,EAAMyH,aAAa,OAAQ1B,GAC3B/F,EAAMyH,aAAa,QAASlO,GAC5BiO,EAAKE,YAAY1H,MAIlBwH,GAOXlR,GAAGqR,UAAY,SAASC,MAEpB,MAAIpM,QAAOqM,MAAQvR,GAAG6G,WAAW0K,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjCtR,GAAG0R,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAAS5L,OAAS6L,IAIzD5R,GAAG+R,YAAc,SAASC,GAGtB,MAAIhS,IAAG+I,QAAQiJ,GAEJA,EAAgBjL,MAAMxE,QAAQ,YAAa,IAE7CvC,GAAGuI,OAAOyJ,IACkB,OAA7BA,EAAgBC,UAAkD9N,SAA7B6N,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgBjQ,MAM3B/B,GAAGkS,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIX/R,OAAQ,WACJ,GAAI0H,GAAOG,SAEX9H,MAAKkS,YAAYvS,GAAGgI,EAAK,IAAI1H,OAAO2P,MAAM5P,KAAM4H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,MAI1FoK,YAAa,SAASC,GAClBL,EAAUjP,KAAKsP,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAOzS,MAGY,mBAAX2S,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAU5S,GAGjBD,OAAOC,GAAKA,MCRnB,WACG,YAEAA,IAAGwB,MAAQ,SAAS4E,GAChB/F,KAAK+F,QAAU,kBAAoBpG,GAAG6S,QAAU,KAAOzM,GAG3DpG,GAAGwB,MAAMkF,UAAY,GAAIlF,UCV7BxB,GAAG6S,QAAU,SCAb7S,GAAG8S,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAYrJ,SAASC,cAAc,SACnCoJ,EAAUzS,KAAO,OACjBP,GAAGgT,GAAW9S,OAEV8S,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQpT,GAAG+N,UAAY/N,GAAGgO,UAC+C7J,SAArEmJ,UAAUC,UAAU8F,MAAM,uCAIlC,QAASC,KACL,GAAIpO,OAAO+E,eAAgB,CAIvB,MAA+B9F,UAHrBnE,GAAG+J,oBAGFwJ,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiCrP,UAA1Be,OAAOuO,eAKlB,QAASC,KACL,QAAIJ,KAIGE,IAGX,QAASG,KAEL,MAA2DxP,UAApDwF,SAASC,cAAc,SAASgK,gBAG3C,QAASC,KACL,IACI,QAAS3O,OAAO4O,cAEZ9T,GAAG6G,WAAW3B,OAAO4O,aAAaC,SAE1C,MAAO5J,GAEH,OAAO,GAIf,QAAS6J,KACL,GAAIC,GAAOtK,SAASC,cAAc,OAElC,QAAQ,aAAeqK,IAAS,eAAiBA,IAAQ,UAAYA,MAChEjU,GAAGoO,YAAcpO,GAAGsO,MA1F7B,GAAI4F,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAzCAd,GAAoBnB,IAEpBsB,EAA4BH,GAAqBlU,GAAGyJ,uBAEpD0K,EAAyBE,IAA8BrU,GAAGyK,eAE1D2J,EAAmBC,GAA6BL,IAGhDM,EAAqBF,GAAqB,WACtC,GAAI1K,GAAQC,SAASC,cAAc,QAGnC,OADAF,GAAMnJ,KAAO,UACH,oBAAsBmJ,GAASC,SAAS9G,iBAAiB,oBAAoB,QAG3F0R,EAAmBF,GAA6BrU,GAAGwK,0BAEnDgK,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BjB,IAEtDsB,EAAqBR,IAA6C/P,SAAvBe,OAAO+P,aAA6BZ,GAE/EO,EAA4BtB,IAE5BqB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmDlQ,SAAtBe,OAAOwG,WAE5DsJ,EAA0B,WACtB,QAAIX,KACQrU,GAAGyK,iBAAmBzK,GAAG0O,iBAMrCwG,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiBvQ,OAAOwQ,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAcrW,GAAG6N,SACjByI,0BAA2BtW,GAAGsO,MAC9BiI,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxBzU,GAAG4W,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQ9W,GAAG6G,WAAWgQ,EAAaC,QAG9E9W,GAAG4L,QAAU,WACT,YAEA,IAAImL,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZpX,IAAG6B,OAAOxB,MACNyW,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiB/T,KAAKmU,GAEtBC,GACAJ,EAAiBhU,KAAKoU,IAGrBF,KAAU,EACfE,GAAaA,EAAUrH,MAAM,KAAM+G,GAE9BK,GACLA,EAAUpH,MAAM,KAAM8G,GAGnB1W,MAGXkX,KAAM,SAASlI,GAQX,MAPc,KAAV+H,EACAD,EAAcjU,KAAKmM,GAGnBA,EAASY,MAAM,KAAsB9L,SAAhB6S,EAA4BD,EAAcC,GAG5D3W,MAGXyL,QAAS,WAgBL,MAfAsL,GAAQ,EACRL,EAAc5O,UAEV8O,EAAiBlR,QACjB/F,GAAG+C,KAAKkU,EAAkB,SAASjU,EAAKqM,GACpCA,EAASY,MAAM,KAAM8G,KAIzBI,EAAcpR,QACd/F,GAAG+C,KAAKoU,EAAe,SAASnU,EAAKqM,GACjCA,EAASY,MAAM,KAAM8G,KAItB1W,MAGX2L,QAAS,WAgBL,MAfAoL,IAAQ,EACRJ,EAAc7O,UAEV+O,EAAiBnR,QACjB/F,GAAG+C,KAAKmU,EAAkB,SAASlU,EAAKqM,GACpCA,EAASY,MAAM,KAAM+G,KAIzBG,EAAcpR,QACd/F,GAAG+C,KAAKoU,EAAe,SAASnU,EAAKqM,GACjCA,EAASY,MAAM,KAAM+G,KAItB3W,SC3EnBL,GAAGwX,UAAY,SAASC,EAAeC,GACnC,YAEA1X,IAAG6B,OAAOxB,MACNoX,cAAeA,EAEfE,OAAQ,WACJ,MAAOD,GAASD,OCF5BzX,GAAG4X,aAAe,SAASC,GACvB,YA0CA,SAASC,KACL,GAAIpO,GAAQC,SAASC,cAAc,QAmEnC,OAjEAF,GAAMyH,aAAanR,GAAG4X,aAAaG,oBAAqBC,GACxDtO,EAAMyH,aAAa,QAAS8G,EAAQC,OAEpCC,EAAKC,YAAYH,EAAQpO,SAAUH,GAE/BuO,EAAQI,SAAWrY,GAAG8S,kBAAkB+C,iBAExCnM,EAAMyH,aAAa,kBAAmB,IAGtC8G,EAAQK,aACR5O,EAAMyH,aAAa,SAAU8G,EAAQK,aAGzC5O,EAAMyH,aAAa,OAAQ,QAC3BzH,EAAMyH,aAAa,OAAQ8G,EAAQlW,MAEnC/B,GAAG0J,GAAOpI,KACNiX,SAAU,WAIVC,MAAO,EACPC,IAAK,EACLC,WAAY,QASZC,SAAU3Y,GAAGqN,OAASrN,GAAGyN,MAAQ,SAAW,QAC5CmL,OAAQ,EACRC,QAAS,EACTC,OAAQ,UACRrX,QAAS,KAKZzB,GAAGwN,OAASxN,GAAG0J,GAAOpI,KAAKyX,OAAQ,SAEpCd,EAAQhY,QAAQmR,YAAY1H,GAE5BsP,EAAe1Y,OAAOoJ,EAAO,SAAU,WACnCuO,EAAQgB,SAASvP,KAIrBsP,EAAe1Y,OAAOoJ,EAAO,YAAa,WACtC1J,GAAGiY,EAAQhY,SAASoC,SAAS4V,EAAQiB,cAEzCF,EAAe1Y,OAAOoJ,EAAO,WAAY,WACrC1J,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQiB,cAG5CF,EAAe1Y,OAAOoJ,EAAO,QAAS,WAClC1J,GAAGiY,EAAQhY,SAASoC,SAAS4V,EAAQkB,cAEzCH,EAAe1Y,OAAOoJ,EAAO,OAAQ,WACjC1J,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQkB,cAGrCzP,EA5GX,GAgCIA,GAAOsO,EAhCPG,EAAO9X,KAEP2Y,EAAiB,GAAIhZ,IAAGkS,eAExB+F,GAEIK,YAAa,KAGbrY,QAAS,KAETkZ,WAAY,yBAGZd,SAAS,EAGTa,WAAY,yBAEZE,4BAA4B,EAG5BvP,UAAU,EAGV9H,KAAM,SAGNkX,SAAU,SAASvP,KAEnBwO,MAAO,KAKflY,IAAG6B,OAAOoW,EAASJ,GAEnBG,EAAWhY,GAAGiN,cA2EdjN,GAAGiY,EAAQhY,SAASqB,KAChBiX,SAAU,WACVc,SAAU,SAEVC,UAAW,QAIftZ,GAAG6B,OAAOxB,MACNkZ,SAAU,WACN,MAAO7P,IAGX8P,YAAa,WACT,MAAOxB,IAGXI,YAAa,SAASqB,EAAYC,GAC9B,GAAIhQ,GAAQgQ,GAAYrZ,KAAKkZ,UAKzBtB,GAAQmB,4BAA8BpZ,GAAGwO,SAAWxO,GAAG0O,aAAe1O,GAAG4O,oBACzElF,EAAMyH,aAAa,WAAY,IAI3BsI,EACA/P,EAAMyH,aAAa,WAAY,IAG/BzH,EAAMiQ,gBAAgB,aAKlCC,eAAgB,SAAStB,GACjBA,IAAgBL,EAAQK,aACxB5O,EAAMyH,aAAa,SAAUmH,IAIrCuB,MAAO,WACCnQ,EAAMvI,YACNnB,GAAG0J,GAAOtI,SAGdpB,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQkB,YACxCzP,EAAQ,KACRA,EAAQoO,OAIhBpO,EAAQoO,KAGZ9X,GAAG4X,aAAaG,oBAAsB,eCxLtC/X,GAAG8Z,WAAa,SAASC,GACrB,YAQA,SAASC,GAAaC,GAClB,GAAIja,GAAG8G,QAAQmT,GAAU,CACrB,GAAIC,KAMJ,OAJAla,IAAG+C,KAAKkX,EAAS,SAASjX,EAAKmX,GAC3BD,EAAQhX,KAAK8B,EAAKmV,MAGfD,EAGX,MAAOlV,GAAKiV,GAGhB,QAASG,GAAeC,GACpB,GAAIra,GAAG8G,QAAQuT,GAAQ,CACnB,GAAIH,KAMJ,OAJAla,IAAG+C,KAAKsX,EAAO,SAASrX,EAAKsX,GACzBJ,EAAQhX,KAAK8B,EAAKuV,EAAOD,OAGtBJ,EAGX,MAAOlV,GAAKuV,EAAOF,IAGvB,QAASG,GAAgBC,GACrB,GAAIC,MACAC,KAAc3K,OAAOyK,EAYzB,OAVAza,IAAG+C,KAAK4X,EAAU,SAASC,EAAOC,GAC9B,GAAIC,GAAsBC,EAASF,EAEP1W,UAAxB2W,GACA9a,GAAG+C,KAAK+X,EAAqB,SAASpK,EAAGsK,GACrCN,EAAcxX,KAAK8B,EAAKgW,QAK7BN,EAhDX,GAAI1V,MACAuV,KACAQ,KACAE,KACAC,IA+CJlb,IAAG6B,OAAOxB,MAgBN8a,QAAS,SAASC,GACd,GAAIX,GAASW,EAAKX,QAAUza,GAAGya,OAAOY,WAClClB,EAAKnV,EAAK9B,MACNnB,KAAMqZ,EAAKrZ,KACXuZ,aAAcF,EAAKrZ,KACnBuY,KAAMc,EAAKd,KACXiB,KAAmB,MAAbH,EAAKG,MAAe,EAAKH,EAAKG,KACpCd,OAAQA,EACRe,KAAMJ,EAAKI,OACV,CA+BT,OA7BIJ,GAAKK,UACLzW,EAAKmV,GAAIsB,QAAUL,EAAKK,QAEQtX,SAA5B+W,EAAUE,EAAKK,WACfP,EAAUE,EAAKK,aAEnBP,EAAUE,EAAKK,SAASvY,KAAKiX,IAG7BiB,EAAKM,eACL1W,EAAKmV,GAAIuB,aAAeN,EAAKM,aAEavX,SAAtC8W,EAAeG,EAAKM,gBACpBT,EAAeG,EAAKM,kBAExBT,EAAeG,EAAKM,cAAcxY,KAAKiX,IAG3CnV,EAAKmV,GAAIA,GAAKA,EACdI,EAAOa,EAAKd,MAAQH,EAEKhW,SAArB4W,EAASN,KACTM,EAASN,OAEbM,EAASN,GAAQvX,KAAKiX,GAEtBiB,EAAKO,sBAAwBP,EAAKO,qBAAqBxB,GACvDJ,EAAc6B,eAAezB,EAAI,KAAMM,GAEhCN,GAGX0B,SAAU,SAASC,GACf,MAAI9b,IAAGuG,SAASuV,IAAmB9W,EAAKe,OACV5B,SAAtB2X,EAAe3B,GACRH,EAAa8B,EAAe3B,IAGNhW,SAAxB2X,EAAexB,KACbF,EAAe0B,EAAexB,MAGhCwB,EAAerB,OACbD,EAAgBsB,EAAerB,QADrC,OAKEza,GAAG6B,UAAWmD,GAAM,IAInC+W,cAAe,SAAS5B,GACpB,GAAI6B,GAAShC,EAAaG,EAEtB6B,UACOA,GAAOR,MAItB3B,MAAO,WACH7U,KACAuV,KACAQ,KACAG,MAGJe,UAAW,SAAS9B,EAAI+B,GACpB,GAAIC,GAAYnX,EAAKmV,GAAIM,OACrB2B,EAAyBpc,GAAG2F,QAAQoV,EAASoB,GAAYhC,EAE7DY,GAASoB,GAAWE,OAAOD,EAAwB,GAEnDpX,EAAKmV,GAAIM,OAASyB,EAEU/X,SAAxB4W,EAASmB,KACTnB,EAASmB,OAEbnB,EAASmB,GAAWhZ,KAAKiX,GAEzBJ,EAAc6B,eAAezB,EAAIgC,EAAWD,IAGhDI,YAAa,SAASnC,EAAIoC,GACtB,GAAIC,GAAUxX,EAAKmV,GAAIG,IAEvBtV,GAAKmV,GAAIG,KAAOiC,EAChBhC,EAAOgC,GAAWpC,QACXI,GAAOiC,IAGlBC,WAAY,SAAStC,EAAIuC,GACrB1X,EAAKmV,GAAIpY,KAAO2a,GAGpBC,WAAY,SAASxC,EAAIyC,GACrB5X,EAAKmV,GAAIoB,KAAOqB,GAIpBC,YAAa,SAASC,EAAUC,GAC5B/X,EAAK8X,GAAUC,SAAWA,GAG9BC,mBAAoB,SAAS7C,GACzB,GAAIuB,GAAe1W,EAAKmV,GAAIuB,YAE5B,OAAIA,GACOT,EAAeS,OAK9BuB,cAAe,SAAS9C,GAGpB,MAAOe,GAFOlW,EAAKmV,GAAIsB,aAOnCzb,GAAGya,QACCY,WAAY,aACZ6B,UAAW,YACXC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,UAAW,YACXC,kBAAmB,oBACnBC,gBAAiB,kBACjBC,kBAAmB,oBACnBC,cAAe,gBACfC,cAAe,gBACfC,SAAU,WACVC,QAAS,WCpNZ,WACG,YAEA9d,IAAG+d,eAECC,SAAU,SAASC,EAAiBC,EAAQC,GACxC9d,KAAK+d,SAASH,EAAiBC,EAAQC,IAG3CE,gBAAiB,SAASC,GACtB,GAAInG,GAAO9X,IAEXL,IAAG+C,KAAKub,EAAgB,SAAS1D,EAAO2D,GACpCpG,EAAKqG,eAAeD,MAI5BH,SAAU,SAASpZ,EAAMkZ,EAAQC,GAC7B9d,KAAKoe,kCAEL,IAAIhD,GAAqC,IAA3Bpb,KAAKqe,WAAW3Y,OAAe/F,GAAGiN,cAAgB5M,KAAKse,gBAEjEC,EAAc5e,GAAG4P,KAAK,SAAStE,GAC3BjL,KAAKwe,gBACDvT,KAAMA,EACNvJ,KAAM1B,KAAKye,SAASC,MAAMC,aAC3BvD,EAASwD,IACb5e,MAEH6e,EAAkBlf,GAAG4P,KAAK,SAASuP,GAC/B9e,KAAKwe,eAAeM,EAAU1D,EAASwD,IACxC5e,MAEH+e,EAAgBpf,GAAG4P,KAAK,SAASvL,GAC7B,GAAIiH,GAAOtL,GAAGoE,aAAaC,EAE3BhE,MAAKwe,gBACDvT,KAAMA,EACNvJ,KAAM1B,KAAKye,SAASC,MAAMC,YAAc,QACzCvD,EAASwD,IACb5e,MAEHgf,EAAoBrf,GAAG4P,KAAK,SAAS0P,GACjC,GAAIC,GAAoBD,EAAW/a,SAAW+a,EAAW/a,QAAU,IAC/D+G,EAAOtL,GAAGoE,aAAakb,EAAWjb,OAAQib,EAAW/e,KAAMgf,EAE/Dlf,MAAKwe,gBACDvT,KAAMA,EACNvJ,KAAMud,EAAWvd,MAClB0Z,EAASwD,IACb5e,MAEHmf,EAAqBxf,GAAG4P,KAAK,SAAS6P,GAClC,GAAIzf,GAAG+I,QAAQ0W,IAAgBzf,GAAG8S,kBAAkBoC,cAAe,CAC/D,GAAIwK,GAAQzX,MAAMvB,UAAUwB,MAAMtB,KAAK6Y,EAAYC,OAC/CvH,EAAO9X,IAEXL,IAAG+C,KAAK2c,EAAO,SAAS1c,EAAKwY,GACzBrD,EAAK0G,eAAerD,EAAMC,EAASwD,SAIvC5e,MAAKwe,eAAeY,EAAahE,EAASwD,IAE/C5e,MAEHsf,EAAgB,WACR3f,GAAG0I,WAAW1D,KACdA,EAAOiD,MAAMvB,UAAUwB,MAAMtB,KAAK5B,IAEtCA,KAAUgL,OAAOhL,IAGrBmT,EAAO9X,KACP4e,IAEJ5e,MAAKse,gBAAkBlD,EAEnBzW,IACA2a,IAEA3f,GAAG+C,KAAKiC,EAAM,SAAShC,EAAK4c,GACpB5f,GAAG6I,cAAc+W,GACjBJ,EAAmBI,GAEd5f,GAAGuJ,OAAOqW,GACfhB,EAAYgB,GAEP5f,GAAGuG,SAASqZ,GACbA,EAActU,MAAQsU,EAAc7d,KACpCmd,EAAgBU,GAEXA,EAAcvb,QAAUub,EAAc7d,MAC3Csd,EAAkBO,GAGjBA,EAActW,SAAmD,WAAxCsW,EAActW,QAAQF,cACpDgW,EAAcQ,GAGdzH,EAAKhS,IAAIyZ,EAAgB,6CAA8C,UAI/Evf,KAAK8F,IAAI,YAAc8Y,EAAclZ,OAAS,WAC9C1F,KAAKwf,uBAAuBZ,EAAef,EAAQC,KAI3D2B,OAAQ,SAAS3F,GACb,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAE5C4F,IAAcA,EAAWtF,SAAWza,GAAGya,OAAO+C,kBAC9Cnd,KAAK8F,IAAInG,GAAG8H,OAAO,2DAA4DqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,SAGtG9Z,KAAK6f,SAASJ,OAAO3F,IAI7BgG,UAAW,WACP,GAAIC,MACAjI,EAAO9X,IAEXL,IAAG6B,OAAOue,EAAe/f,KAAKqe,YAC9B1e,GAAG+C,KAAKqd,EAAe,SAASpd,EAAKqd,GACjClI,EAAK2H,OAAOO,KAGhBhgB,KAAK6f,SAASC,aAGlBG,iBAAkB,WACdjgB,KAAKqe,eAGT6B,eAAgB,SAASpG,GACrB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAEhD,UAAKna,GAAG8S,kBAAkBmD,QAAU5V,KAAKye,SAASzJ,SAASmL,WAIvDT,EAAWtF,SAAWza,GAAGya,OAAO6C,QAChCjd,KAAK8F,IAAInG,GAAG8H,OAAO,yDAA0DqS,EAAI9Z,KAAK4f,QAAQ9F,KAC9F9Z,KAAKogB,YAAYtG,IACV,IAGP9Z,KAAK8F,IAAInG,GAAG8H,OAAO,sDAAuDqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,UAG9F,KAGXuG,WAAY,SAASvG,GACjB,MAAO9Z,MAAKsgB,gBAAgBxG,IAIhCyG,UAAW,SAASC,GAChB,MAAOxgB,MAAK6f,SAASY,QAAQD,IAOjCE,cAAe,SAASC,EAAQC,EAAaC,EAASC,EAAYC,GAC9D,GACIC,GAAWpJ,EADXqJ,EAAkB,GAAIthB,IAAG4L,OAqC7B,OAlCIvL,MAAKkhB,iBACLF,EAAYhhB,KAAKmhB,eAAeR,GAChC/I,GACImJ,qBAAsBA,EACtBF,QAASA,EAAU,EAAIA,EAAU,KACjCO,MAAOP,EAAU,IAKhBC,GAAcnhB,GAAG8S,kBAAkBgD,gBACpCuL,EAAYhhB,KAAKqhB,QAAQV,IAIZ,MAAbK,EACAC,EAAgBtV,SAAS2V,UAAWV,EAAa9W,MAAO,2BAGxD9J,KAAKkhB,gBAAgBK,SAASP,EAAWJ,EAAahJ,GAASnB,KAC3D,SAAiB+K,GACbP,EAAgBxV,QAAQ+V,IAG5B,SAAiBF,EAAWG,GACxBR,EAAgBtV,SAAS2V,UAAWA,EAAWxX,MAAO2X,GAAU,oCAM5ER,EAAgBtV,SAAS2V,UAAWV,EAAa9W,MAAO,mCAGrDmX,GAGXS,UAAW,SAASf,GAChB,MAAO3gB,MAAK2hB,WAAW3hB,KAAK4hB,qBAAqBjB,KAGrDkB,YAAa,SAASlB,GAClB,MAAO3gB,MAAK8hB,eAAeC,IAAIpB,IAGnCU,QAAS,SAASb,GACd,GACIwB,GADA7G,EAAOnb,KAAK6f,SAASwB,QAAQb,EAWjC,OARKrF,KACD6G,EAAmBhiB,KAAK2f,YAAYnE,UAAU1B,GAAI0G,IAE9CwB,IACA7G,EAAO6G,EAAiB7G,OAIzBA,GAAQ,MAGnB8G,cAAe,WACX,MAAOjiB,MAAK2f,YAAYnE,UACpBpB,QACIza,GAAGya,OAAO8C,UACVvd,GAAGya,OAAOgD,gBACVzd,GAAGya,OAAO2C,UAEfrX,QAGPka,QAAS,SAAS9F,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKpY,MAI/CwgB,YAAa,SAASpI,GAClB,GAAIqI,GAAkBniB,KAAKoiB,YAAYtI,GAAIA,IACvC4C,EAAW,IAQf,OANIyF,IACiCre,SAA7Bqe,EAAgBzF,WAChBA,EAAWyF,EAAgBzF,UAI5BA,GAGX2F,sBAAuB,WACnB,MAAOriB,MAAK6f,SAASwC,yBAGzBC,QAAS,SAASxI,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKoB,MAG/CqH,cAAe,WACX,MAAOviB,MAAKwiB,cAGhBC,yBAA0B,WACtB,GAAIC,GAAe1iB,KAAK2iB,iBAExB,OAAID,GAAe,EACRA,EAAe1iB,KAAK4iB,qBAGxB,MAGXR,WAAY,SAAS3G,GACjB,MAAOzb,MAAK2f,YAAYnE,SAASC,IAGrCoH,QAAS,SAAS/I,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKG,MAG/C6I,YAAa,SAAShJ,GAClB,MAAO9Z,MAAK6f,SAASkD,gBAAgBjJ,IAGzChU,IAAK,SAAS4B,EAAK1B,IACXhG,KAAKye,SAASuE,OAAWhd,GAAmB,SAAVA,EAG7BA,GAAmB,SAAVA,GACdrG,GAAGmG,IAAI,kBAAoBnG,GAAG6S,QAAU,KAAO9K,EAAK1B,GAHpDrG,GAAGmG,IAAI,kBAAoBnG,GAAG6S,QAAU,KAAO9K,IAQvDub,YAAa,SAASnJ,GAClB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAEhD,KAAKna,GAAG8S,kBAAkBmD,QAAU5V,KAAKye,SAASzJ,SAASmL,QACvD,OAAO,CAIX,IAAIxgB,GAAG2F,SAAS3F,GAAGya,OAAO8C,UAAWvd,GAAGya,OAAOgD,iBAAkBsC,EAAWtF,SAAW,EAAG,CACtF,GAAIpa,KAAK6f,SAASjK,MAAMkE,GAEpB,MADA9Z,MAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO6C,SAClC,CAGPjd,MAAK8F,IAAInG,GAAG8H,OAAO,mCAAoCqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,aAIlF9Z,MAAK8F,IAAInG,GAAG8H,OAAO,wDAAyDqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,QAGvG,QAAO,GAGX4B,cAAe,SAAS5B,GACpB9Z,KAAK6f,SAASqD,QAAQpJ,GACtB9Z,KAAK2f,YAAYjE,cAAc5B,IAGnCN,MAAO,WACHxZ,KAAK8F,IAAI,yBAET9F,KAAK6f,SAASrG,QACdxZ,KAAKqe,cACLre,KAAKmjB,gBACLnjB,KAAKojB,kBACLpjB,KAAKqjB,mBACLrjB,KAAKmhB,kBAELxhB,GAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjCA,EAAO/J,UAGXxZ,KAAKwjB,aAAahK,QAClBxZ,KAAK8hB,eAAetI,QACpBxZ,KAAK4iB,qBAAuB,EAC5B5iB,KAAKwiB,aAAe,EACpBxiB,KAAK2f,YAAYnG,QACjBxZ,KAAK4hB,wBAEL5hB,KAAKyjB,eAAiBzjB,KAAKyjB,cAAcjK,QACzCxZ,KAAKye,SAASiF,QAAQC,gBAAkB3jB,KAAK4jB,sBAE7C5jB,KAAK6jB,kCACL7jB,KAAK8jB,+BAEL9jB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAevK,QAE3CxZ,KAAKgkB,uBAAuBxK,SAGhCyK,MAAO,SAASnK,GACZ,MAAO9Z,MAAKkkB,aAAapK,IAG7BqK,WAAY,SAASrK,EAAIsK,GACrB,GAAItM,GAAO9X,IAEX,OAAOL,IAAG0kB,OAAOhe,UAAU8d,WAAWrK,EAAIsK,GACtCte,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvBuJ,QAAS1hB,GAAG4P,KAAKuI,EAAKuJ,QAASvJ,GAC/B4H,WAAY5H,EAAK6H,eAIzB2E,iBAAkB,SAASC,EAASzK,GAChC9Z,KAAKwkB,oBAAoBC,IAAIF,EAASzK,IAG1C4K,oBAAqB,SAAS5K,EAAInV,GAC9B3E,KAAKgkB,uBAAuBS,IAAI9f,EAAMmV,IAG1C6K,2BAA4B,SAASJ,EAASzK,GAC1C9Z,KAAK4kB,8BAA8BH,IAAIF,EAASzK,IAGpD+K,sBAAuB,SAAS/G,EAAUhE,GACtC9Z,KAAK8kB,yBAAyBL,IAAI3G,EAAUhE,IAGhDiL,oBAAqB,SAASlH,EAAQ/D,GAClC9Z,KAAKglB,uBAAuBP,IAAI5G,EAAQ/D,IAI5CmL,YAAa,SAASnH,EAAUhE,GAC5B9Z,KAAK8hB,eAAe2C,IAAI3G,EAAUhE,IAGtCoL,QAAS,SAASC,GACdnlB,KAAKolB,4BAA4BD,IAGrCE,aAAc,SAASC,GACnBtlB,KAAK2iB,kBAAoB2C,GAG7BC,QAAS,SAASzL,EAAIuC,GAClBrc,KAAK2f,YAAYvD,WAAWtC,EAAIuC,IAGpCmJ,UAAW,SAAS3H,EAAQ/D,GACxB9Z,KAAKwjB,aAAaiB,IAAI5G,EAAQ/D,IAGlC2L,QAAS,SAAS3L,EAAIoC,GAClB,MAAOlc,MAAK2f,YAAY1D,YAAYnC,EAAIoC,IAY5CN,UAAW,SAAS9B,EAAI+B,GAEpB,IADiB7b,KAAKoiB,YAAYtI,GAAIA,IAElC,KAAM,IAAIna,IAAGwB,MAAM2Y,EAAK,2BAG5B,QAAQ+B,GACJ,IAAKlc,IAAGya,OAAOqD,QACXzd,KAAK0lB,kBAAkB5L,EAAI,MAAM,EACjC,MACJ,KAAKna,IAAGya,OAAOmD,cACXvd,KAAK0lB,kBAAkB5L,EAAI,MAAM,EACjC,MACJ,SACI,GAAI6L,GAAe,+BAAiCjkB,KAAO,6BAA+Bma,CAE1F,MADA7b,MAAK8F,IAAI6f,GACH,GAAIhmB,IAAGwB,MAAMwkB,KAI/BC,kBAAmB,WACgB,IAA3B5lB,KAAKqe,WAAW3Y,OAChB1F,KAAK6lB,WAAW,gBAGhB7lB,KAAK8lB,uBAQjBnmB,GAAGomB,gBAEC5H,eAAgB,SAAS6H,GACrB,GAAIlO,GAAO9X,IAEX,OAAOA,MAAK2f,YAAY7E,SACpBb,KAAM+L,EAAY/L,KAClBvY,KAAMskB,EAAYtkB,KAClBwZ,KAAM8K,EAAY9K,KAClBd,OAAQza,GAAGya,OAAOiD,kBAClB/B,qBAAsB,SAASxB,GAC3BkM,EAAYC,oBAAsBnO,EAAK+M,sBAAsBmB,EAAYC,mBAAoBnM,GAC7FkM,EAAYE,kBAAoBpO,EAAKiN,oBAAoBiB,EAAYE,iBAAkBpM,GAEnFkM,EAAYG,eACZrO,EAAKqJ,eAAerH,GAAMkM,EAAYG,cAG1CrO,EAAK0K,eACL1K,EAAK8K,2BAKjBwD,sBAAuB,SAASjL,EAAMkL,GAC9B1mB,GAAGuI,OAAOiT,KACVA,EAAKmL,WAAatmB,KAAKumB,aAAaF,KAI5CG,YAAa,SAASzgB,GAClB/F,KAAKye,SAASgI,UAAUC,QAAQ,KAAM,KAAM3gB,EAASjC,SAGzD6iB,qBAAsB,WAClB,GAAI7O,GAAO9X,IAEX,OAAO,IAAIL,IAAGinB,yBACVC,OAAQ7mB,KAAKye,SAAS4B,WAAWwG,OAAOC,cACxCC,eAAgB/mB,KAAKye,SAASsI,eAC9BC,cAAehnB,KAAKye,SAASwI,QAAQC,SACrCC,cAAennB,KAAK4kB,8BACpBwC,YAAapnB,KAAKglB,uBAClBqC,cAAernB,KAAK8kB,yBACpBwC,KAAMtnB,KAAKye,SAAS6I,KACpBxhB,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvByP,SAAU,SAASzN,GACfhC,EAAK0P,UAAU1N,GACfhC,EAAK2G,SAASgI,UAAUc,SAASzN,IAErC2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,GACrC7P,EAAK4N,kBAAkB5L,EAAI4N,EAAUC,GACrC7P,EAAK2G,SAASgI,UAAUgB,iBAAiB3N,EAAI4N,EAAUC,OAMnEC,oBAAqB,WACjB,GAAI9P,GAAO9X,IAEX,OAAO,IAAIL,IAAGkoB,cACVC,cAAe9nB,KAAKye,SAASsJ,MAAMD,cACnCrB,WACI3gB,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvBkQ,cAAe,SAAS/c,GACpB6M,EAAKmQ,wBACDvmB,KAAM,kBACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAUyB,gBAAiBpQ,EAAM7M,GACjE+L,UAAWrX,GAAG4P,KAAKuI,EAAKqQ,oBAAqBrQ,EAAM7M,GACnDmd,WAAY,sBAOhCC,aAAc,SAASC,EAAcC,GACjC,GAAIC,MACAC,EAAWH,EACXI,KACAC,EAAiBJ,EACjBK,EAAO,SAASC,GACZ,MAAIlpB,IAAGuG,SAAS2iB,GACLlpB,GAAG6B,UAAWqnB,GAElBA,GAEXC,EAAoB,WAChB,MAAInpB,IAAG6G,WAAWmiB,GACPA,IAEJA,GAEXI,EAAwB,SAASjP,EAAIkP,GAC7BL,GAAkBhpB,GAAGuG,SAAS8iB,IAC9BrpB,GAAG6B,OAAOwnB,EAAUF,KAGpBJ,EAAoB5O,IACpBna,GAAG6B,OAAOwnB,EAAUN,EAAoB5O,IAIpD,QACI2K,IAAK,SAAS7hB,EAAKkX,GAEL,MAANA,GACA0O,KACAC,EAAWG,EAAKhmB,IAGhB4lB,EAAM1O,GAAM8O,EAAKhmB,IAIzBmf,IAAK,SAASjI,GACV,GAAImP,EAYJ,OARIA,GADM,MAANnP,GAAc0O,EAAM1O,GACX0O,EAAM1O,GAGN8O,EAAKH,GAGlBM,EAAsBjP,EAAImP,GAEnBL,EAAKK,IAGhBC,YAAa,SAASpP,EAAImP,GAElBtpB,GAAGuG,SAASsiB,KAED,OAAP1O,EACIna,GAAG6G,WAAWyiB,GACdN,EAAiBM,GAGjBN,EAAiBA,MACjBhpB,GAAG6B,OAAOmnB,EAAgBM,KAI9BP,EAAoB5O,GAAM4O,EAAoB5O,OAC9Cna,GAAG6B,OAAOknB,EAAoB5O,GAAKmP,MAK/CloB,OAAQ,SAAS4f,GACb,aAAc6H,GAAM7H,IAGxBnH,MAAO,WACHgP,KACAE,KACAD,EAAWH,KAKvBa,yBAA0B,WACtB,GAAIrR,GAAO9X,IAEX,OAAO,IAAIL,IAAG8Z,YACVmG,QAAS,SAAS9F,GACd,MAAOhC,GAAK8H,QAAQ9F,IAExB+I,QAAS,SAAS/I,GACd,MAAOhC,GAAK+K,QAAQ/I,IAExBwI,QAAS,SAASxI,GACd,MAAOhC,GAAKwK,QAAQxI,IAExByB,eAAgB,SAASzB,EAAIgC,EAAWD,GACpC/D,EAAKsR,sBAAsBtP,EAAIgC,EAAWD,GAC1C/D,EAAK2G,SAASgI,UAAUlL,eAAezB,EAAIgC,EAAWD,GACtD/D,EAAKuR,kBAAkBvP,EAAI+B,GAEvB/D,EAAKiM,gBACLuF,WAAW,WACPxR,EAAKiM,eAAexI,eAAezB,EAAIgC,EAAWD,IACnD,OAcnB0N,oBAAqB,SAASxO,GAM1B,QAASyO,KACL,QAAI7pB,GAAG8S,kBAAkBoC,kBAEjBiD,EAAK2G,SAASgL,YAAYC,gBAC1B/pB,GAAGsO,QACFtO,GAAGqO,QACJ8J,EAAK6R,oBAAoBC,EAAmB,WAK1B9lB,SAAlBiX,EAAKvR,SACEsO,EAAK2G,SAASjV,SAGlBuR,EAAKvR,WApBpB,GAGI+Z,GAHAzL,EAAO9X,KACPiY,EAAc8C,EAAK8O,QAAU7pB,KAAKye,SAASqL,WAAW7R,YACtD2R,EAAoB7O,EAAK6O,mBAAqB5pB,KAAKye,SAASqL,WAAWF,iBA6C3E,OArBArG,GAAS,GAAI5jB,IAAG4X,cACZU,YAAaA,EACbrY,QAASmb,EAAKnb,QACdkZ,WAAY9Y,KAAKye,SAASsL,QAAQC,YAClChS,QAAS+C,EAAK/C,QACda,WAAY7Y,KAAKye,SAASsL,QAAQE,YAClClR,2BAA4B/Y,KAAKye,SAASgL,YAAYS,iBACtD1gB,SAAUggB,IACV9nB,KAAM1B,KAAKye,SAASwI,QAAQkD,UAC5BvR,SAAU,SAASvP,GACfyO,EAAKsS,eAAe/gB,IAExBwO,MAAqB,MAAdkD,EAAKlD,MAAgB7X,KAAKye,SAASpb,KAAKgnB,eAAiBtP,EAAKlD,QAGzE7X,KAAKsqB,gBAAgBpY,YAAY,WAC7BqR,EAAOxR,YAGX+F,EAAKwL,SAASzgB,KAAK0gB,GAEZA,GAGXgH,qBAAsB,SAASC,EAAmBC,GAC9C,GAAI3S,GAAO9X,KACP0qB,KACA9S,GACIoL,MAAOhjB,KAAKye,SAASuE,MACrB+D,eAAgB/mB,KAAKye,SAASsI,eAC9BO,KAAMtnB,KAAKye,SAAS6I,KACpBF,YAAapnB,KAAKwjB,aAClB6D,cAAernB,KAAK8hB,eACpB9M,SAAUhV,KAAKye,SAASzJ,SACxBc,OAAQ9V,KAAKye,SAAS3I,OACtB4I,MAAO1e,KAAKye,SAASC,MACrB5Y,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvB6S,kBAAmB3qB,KAAKye,SAASwF,MAAM2G,6BACvCC,WAAY,SAAS/Q,EAAIpY,EAAMopB,EAAQC,GAC/BD,EAAS,GAAKC,EAAQ,IAItBL,EAAe5Q,GACX4Q,EAAe5Q,GAAIgR,SAAWA,GAAUJ,EAAe5Q,GAAIiR,QAAUA,IACrEjT,EAAKkT,YAAYlR,EAAIpY,EAAMopB,EAAQC,GACnCjT,EAAK2G,SAASgI,UAAUoE,WAAW/Q,EAAIpY,EAAMopB,EAAQC,KAIzDjT,EAAKkT,YAAYlR,EAAIpY,EAAMopB,EAAQC,GACnCjT,EAAK2G,SAASgI,UAAUoE,WAAW/Q,EAAIpY,EAAMopB,EAAQC,IAGzDL,EAAe5Q,IAAOgR,OAAQA,EAAQC,MAAOA,KAGjDE,WAAY,SAASnR,EAAIpY,EAAMY,EAAQ4oB,SAC5BR,GAAe5Q,EAEtB,IACI5K,GADAkL,EAAStC,EAAKsK,YAAYtI,GAAIA,IAAKM,MAOnCA,KAAWza,GAAGya,OAAOiD,mBAAqBjD,IAAWza,GAAGya,OAAOkD,gBAInEpO,EAAS4I,EAAKqT,YAAYrR,EAAIpY,EAAMY,EAAQ4oB,GAIxChc,YAAmBvP,IAAG4L,QACtB2D,EAAOgI,KAAK,WACRY,EAAK2G,SAASgI,UAAUwE,WAAWnR,EAAIpY,EAAMY,EAAQ4oB,KAIzDpT,EAAK2G,SAASgI,UAAUwE,WAAWnR,EAAIpY,EAAMY,EAAQ4oB,KAG7DE,SAAU,SAAStR,EAAIpY,EAAM2pB,GACzB,GAAI/f,GAAU,GAAI3L,IAAG4L,OAgBrB,OAdAuM,GAAKmQ,wBACDvmB,KAAM,WACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAU2E,SAAUtT,EAAMgC,EAAIpY,GAC9DuV,UAAW3L,EAAQK,QACnBqL,UAAW,WACPqU,EAAyB5U,KAAK,WAC1BqB,EAAKwT,UAAUxR,EAAIpY,KAGvB4J,EAAQG,WAEZ2c,WAAYtO,IAGTxO,GAEXigB,aAAc5rB,GAAG4P,KAAKvP,KAAKwrB,cAAexrB,MAC1CyrB,SAAU,SAAS3R,EAAIpY,GACnBoW,EAAK4T,UAAU5R,EAAIpY,EACnB,IAAIiqB,GAAiB7T,EAAK2G,SAASgI,UAAUgF,SAAS3R,EAAIpY,EAE1D,OAAI/B,IAAG4W,iBAAiBoV,IACpB7T,EAAKhS,IAAInG,GAAG8H,OAAO,+DAAgEqS,IAC5E6R,IAGJ,GAAIhsB,IAAG4L,SAAUE,WAE5BmgB,cAAe,SAAS9R,EAAIpY,EAAMmqB,GAC9B/T,EAAKgU,eAAehS,EAAI+R,EACxB,IAAIE,GAAsBjU,EAAK2G,SAASgI,UAAUmF,cAAc9R,EAAIpY,EAAMmqB,EAE1E,OAAIlsB,IAAG4W,iBAAiBwV,IACpBjU,EAAKhS,IAAInG,GAAG8H,OAAO,uEAAwEqS,EAAI+R,EAAUG,YAClGD,IAGJ,GAAIpsB,IAAG4L,SAAUE,WAE5BwgB,qBAAsB,SAASnS,EAAI+R,EAAWvpB,EAAQ4oB,GAClDpT,EAAKoU,sBAAsBpS,EAAI+R,GAC/B/T,EAAK2G,SAASgI,UAAUwF,qBAAqBrc,MAAMkI,EAAMhQ,YAE7DqkB,SAAU,SAASrS,EAAIpY,EAAMmqB,EAAWO,GACpC,MAAOtU,GAAK2G,SAASgI,UAAU0F,SAASrS,EAAIpY,EAAMmqB,EAAWO,IAEjEC,YAAa,SAASvS,EAAIpY,EAAM4qB,EAAcpB,GAC1C,MAAOpT,GAAKyU,aAAa3c,MAAMkI,EAAMhQ,YAEzC0kB,cAAe,SAAS1S,EAAIoC,GACxBpE,EAAKhS,IAAI,sCAAwCgS,EAAK+K,QAAQ/I,GAAM,SAAWoC,EAAU,KACzFpE,EAAK2N,QAAQ3L,EAAIoC,IAErB0D,QAASjgB,GAAG4P,KAAKuI,EAAK8H,QAAS9H,GAC/B+K,QAASljB,GAAG4P,KAAKuI,EAAK+K,QAAS/K,GAC/BwK,QAAS3iB,GAAG4P,KAAKuI,EAAKwK,QAASxK,GAC/B2U,QAAS9sB,GAAG4P,KAAKuI,EAAK4U,SAAU5U,GAChC6U,cAAe,SAAS1S,GACpB,MAAOnC,GAAKsK,YAAYnI,KAAMA,KAElC2S,SAAU,SAAS9S,GACf,GAAIM,GAAStC,EAAKsK,YAAYtI,GAAIA,IAAKM,MACvC,OAAOA,KAAWza,GAAGya,OAAO2C,QACxB3C,IAAWza,GAAGya,OAAOyC,WACrBzC,IAAWza,GAAGya,OAAOgD,iBACrBhD,IAAWza,GAAGya,OAAO6C,QAE7BN,mBAAoB7E,EAAK6H,YAAYhD,mBACrCC,cAAe9E,EAAK6H,YAAY/C,cAChCiQ,aAAc,SAAS/S,GACnB,MAAOhC,GAAKsK,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAO8C,WAE1D4P,oBAAqBntB,GAAG4P,KAAKuI,EAAKiV,qBAAsBjV,GACxD8D,UAAW,SAAS9B,EAAIM,GACpBtC,EAAK6H,YAAY/D,UAAU9B,EAAIM,IAgB3C,OAZAza,IAAG+C,KAAK1C,KAAKye,SAASwI,QAAS,SAASlb,EAAMnJ,GAC1CgV,EAAQ7L,GAAQnJ,IAGpBgV,EAAQuP,cAAgBnnB,KAAKwkB,oBAEzBgG,GACA7qB,GAAG+C,KAAK8nB,EAAmB,SAASpb,EAAKxM,GACrCgV,EAAQxI,GAAOxM,IAIhB,GAAIjD,IAAGqtB,wBAAwBpV,EAAS6S,IAGnDwC,oBAAqB,SAASnT,GAC1B9Z,KAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO0C,WAG7CoQ,YAAa,SAASriB,GAClB,GAAc,IAAVA,EACA,MAAOA,GAAQ7K,KAAKye,SAASpb,KAAK8pB,YAAY,EAElD,IAAI9c,IAAI,CACR,GACIxF,IAAgB,IAChBwF,UACKxF,EAAQ,IAEjB,OAAOvJ,MAAK8rB,IAAIviB,EAAO,IAAKwiB,QAAQ,GAAKrtB,KAAKye,SAASpb,KAAK8pB,YAAY9c,IAK5Eid,0BAA2B,WACvB,GAAIxV,GAAO9X,IAEXA,MAAKutB,qBAEL5tB,GAAG+C,KAAK1C,KAAKye,SAAS+O,aAAc,SAAS7qB,EAAK8qB,GAC9C,GAAIjkB,GAAWikB,EAAuBjkB,SAClCsgB,EAAanqB,GAAG6B,UAAWsW,EAAK2G,SAASqL,YAAY,GACrD4D,EAAkB/tB,GAAG6B,UAAWisB,EAEnB3pB,UAAb0F,IACAA,EAAWsO,EAAK2G,SAASjV,UAGzBkkB,EAAgB5D,YAChBnqB,GAAG6B,OAAOsoB,EAAY2D,EAAuB3D,YAAY,GAG7DnqB,GAAG6B,OAAOksB,GACNlkB,SAAUA,EACVsgB,WAAYA,IACb,GAEHhS,EAAK6V,iBAAiBD,MAI9B/L,WAAY,SAAShK,GACjB,GAAIiW,GAAmB5tB,KAAKutB,kBAAkB5V,EAE9C,OAAIiW,GACOA,EAAiBhuB,QAEnB+X,IAAa3X,KAAK6tB,iBAChB7tB,KAAKye,SAAS8E,OADpB,QAYTgD,aAAc,SAASuH,GACnB,GAAIC,GAAQC,EACRC,EAAkBH,CAQtB,IALIG,YAA2BtuB,IAAGwX,YAC9B8W,EAAkBA,EAAgB7W,eAIlC6W,IAAoBtuB,GAAGuJ,OAAO+kB,GAAkB,CAChD,GAAItuB,GAAGuI,OAAO+lB,GACV,MAAOA,GAAgB3H,UAEtB,IAA8C,UAA1C2H,EAAgBhlB,QAAQF,eACU,SAAvCklB,EAAgB/tB,KAAK6I,cAErB,MAAOklB,GAAgBpqB,aAAalE,GAAG4X,aAAaG,oBAYxD,IATAqW,EAASE,EAAgBxrB,qBAAqB,SAE9C9C,GAAG+C,KAAKqrB,EAAQ,SAASprB,EAAK0G,GAC1B,GAAmC,SAA/BA,EAAMxF,aAAa,QAEnB,MADAmqB,GAAY3kB,GACL,IAIX2kB,EACA,MAAOA,GAAUnqB,aAAalE,GAAG4X,aAAaG,uBAK1DqV,qBAAsB,SAASpM,GAC3B,MAAO3gB,MAAKgkB,uBAAuBjC,IAAIpB,IAG3CuN,gBAAiB,WACb,MAAOluB,MAAK2f,YAAYnE,UACpBpB,QACIza,GAAGya,OAAO8C,UACVvd,GAAGya,OAAOgD,gBACVzd,GAAGya,OAAO2C,OACVpd,GAAGya,OAAOY,WACVrb,GAAGya,OAAOyC,UACVld,GAAGya,OAAO6C,UAEfvX,QAKPyoB,mBAAoB,SAASxW,GACzB,GAAI+V,GAAkB1tB,KAAKutB,kBAAkB5V,EAE7C,OAAO+V,GAAkBA,EAAgB5D,WAAa9pB,KAAKye,SAASqL,YAGxEsE,yBAA0B,SAASC,GAC/B,MAAIA,GAAYlT,eAAgBxb,IAAGwX,WAE3BzV,KAAM/B,GAAG+R,YAAY2c,EAAYlT,KAAK/D,eACtC8D,KAAMmT,EAAYlT,KAAK/D,cAAc8D,OAKzCxZ,KAAM1B,KAAKoiB,YAAYtI,GAAIuU,EAAYvU,KAAKpY,KAC5CwZ,KAAMlb,KAAKoiB,YAAYtI,GAAIuU,EAAYvU,KAAKoB,OAIpDoT,0BAA2B,SAASC,GAChC,GAAIzW,GAAO9X,KACPwuB,IAMJ,OAJA7uB,IAAG+C,KAAK6rB,EAAc,SAAS5rB,EAAK0rB;gCAChCG,EAAgB3rB,KAAKiV,EAAKsW,yBAAyBC,MAGhDG,GAIXC,oBAAqB,WACjB,GAAIzuB,KAAKye,SAASiQ,OAAOzgB,KAAOtO,GAAGsO,MAAO,CACtC,GACIsV,GAASvjB,KAAKye,SAASiQ,OAAOnL,OAC9B5L,EAAW4L,EAASvjB,KAAKumB,aAAahD,GAAUvjB,KAAK6tB,iBACrDc,EAAa3uB,KAAKye,QAGlB9G,IAAYA,IAAa3X,KAAK6tB,mBAC9Bc,EAAa3uB,KAAKutB,kBAAkB5V,IAIxCgX,EAAWnlB,UAAW,EAGoB,OAAtCmlB,EAAW7E,WAAW7R,YACtB0W,EAAW7E,WAAW7R,YAfJ,yBAkBlB0W,EAAW7E,WAAW7R,aAAe,0BAIzCtY,GAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjC,GAAIA,EAAOpK,gBAAkBxB,EAIzB,MAHA4L,GAAOxL,YAAY4W,EAAWnlB,UAC9B+Z,EAAOhK,eAAeoV,EAAW1W,cAE1B,MAMvBgQ,uBAAwB,SAAS2G,GAC7B,GAAI9W,GAAO9X,KACP6uB,EAAiBD,EAAQ5f,UAE7B,OAAIrP,IAAG4W,iBAAiBsY,IACpB7uB,KAAK8F,IAAI8oB,EAAQltB,KAAO,kBAAoBktB,EAAQltB,KAAO,gCAAkCktB,EAAQxG,YAC9FyG,EAAepY,KAClB,SAASqY,GACLhX,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,YAC1DwG,EAAQ5X,UAAU8X,IAEtB,WACQF,EAAQ3X,WACRa,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,YAC1DwG,EAAQ3X,aAGRa,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,gBAKtEyG,KAAmB,EACnBD,EAAQ5X,UAAU6X,GAGdD,EAAQ3X,WACRjX,KAAK8F,IAAI8oB,EAAQltB,KAAO,mCAAqCktB,EAAQxG,WAAa,iCAClFwG,EAAQ3X,aAGRjX,KAAK8F,IAAI8oB,EAAQltB,KAAO,mCAAqCktB,EAAQxG,WAAa,wBAInFyG,IAIXrQ,eAAgB,SAASrD,EAAMC,EAAS2T,GACpC,GAAIjX,GAAO9X,KACPia,EAAOta,GAAGiN,cACVsO,GAAO,EACPxZ,EAAO/B,GAAG+R,YAAYyJ,GACtB6T,EAAa7T,EAAKlQ,MAAQkQ,EAC1B8T,EAAUjvB,KAAKkvB,sBACXlvB,KAAKkvB,sBACLvvB,GAAG4P,KAAKuI,EAAKqX,sBAAuBrX,IAEvCnY,GAAG+I,QAAQsmB,IAAeA,EAAW9T,MAAQ,IAC9CA,EAAO8T,EAAW9T,MAGtB+T,EAAQD,EAAYttB,EAAMuY,EAAMiB,EAAM6T,EAAoB3T,EAASpb,KAAKye,SAASwI,QAAQC,UACrFxH,WAAY5H,EAAK6H,YACjByH,YAAatP,EAAK0L,aAClB4L,iBAAkB,SAAStV,EAAIqB,GAC3BrD,EAAK+H,SAAS1P,IAAI2J,EAAIqB,GACtBrD,EAAK8K,uBACL9K,EAAKuX,aAAavV,OAK9BqV,sBAAuB,SAAShU,EAAMzZ,EAAMuY,EAAMiB,EAAMoU,EAAUlU,GAC9D,GAAItB,GAAK9Z,KAAK2f,YAAY7E,SACtBb,KAAMA,EACNvY,KAAMA,EACNwZ,KAAMA,EACNE,QAASA,EACTD,KAAMA,GAGVnb,MAAK6f,SAAS1P,IAAI2J,EAAIqB,GAEtBnb,KAAKqvB,aAAavV,GAElB9Z,KAAK4iB,uBAEL0M,EAASzsB,MAAMiX,GAAIA,EAAIqB,KAAMA,KAGjCgN,oBAAqB,SAASld,EAAMskB,GAChC,GAAIC,GAAYvkB,EAAK/K,KAAKmF,MAAM,KAAK,GACjC3D,EAAO6tB,CAGC,OAAR7tB,IACAA,EAAO1B,KAAKye,SAASsJ,MAAMpJ,aAG/Bjd,GAAQ,IAAM8tB,EAEdxvB,KAAK+d,UACDrc,KAAMA,EACNuJ,KAAMA,KAIdwkB,qBAAsB,SAAS3V,GAC3B,GAAI9Z,KAAKoiB,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAOqD,QAAS,CACxD,GAAI/b,GAAO1B,KAAK4f,QAAQ9F,EAExB9Z,MAAK4iB,uBACL5iB,KAAKwiB,eACLxiB,KAAK6f,SAASqD,QAAQpJ,GACtB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOqD,SACzCzd,KAAK8F,IAAI,uBAAyBpE,EAAO,sBAIjDguB,oBAAqB,SAAS5V,EAAI4N,GAC9B,GAAIhmB,GAAO1B,KAAK4f,QAAQ9F,EAExB9Z,MAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOmD,eACzCvd,KAAK8F,IAAI,uBAAyBpE,EAAO,gBAAiB,SAKrDgmB,GAAyC5jB,SAA7B4jB,EAASxU,gBAItBlT,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,4CAA8CgmB,EAAStN,OAAQsN,GAHzG1nB,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,wBAAyBgmB,IAQ3EiG,iBAAkB,SAAS5S,GACvB,GAAIwI,GAASvjB,KAAKupB,qBACdM,OAAQ9O,EAAK+O,WAAW7R,YACxB2R,kBAAmB7O,EAAK+O,WAAWF,kBACnChqB,QAASmb,EAAKnb,QACdoY,QAAS+C,EAAK/C,QACdxO,SAAUuR,EAAKvR,SACfqO,MAAOkD,EAAKsP,gBAGhBrqB,MAAKutB,kBAAkBhK,EAAOpK,eAAiB4B,GAGnD4U,0BAA2B,WACvB3vB,KAAK4vB,aAAejwB,GAAGkwB,aAAe,GAAIlwB,IAAGkwB,YACzC7vB,KAAKye,SAAS5N,KAAMlR,GAAG4P,KAAKvP,KAAK4lB,kBAAmB5lB,MAAOL,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OAG7EA,KAAK4vB,cAAgB5vB,KAAK4vB,aAAaE,gBACvC9vB,KAAKwjB,aAAexjB,KAAKqoB,aACrBroB,KAAKye,SAASwI,QAAQpJ,OAAS7d,KAAK4vB,aAAaG,uBAGrD/vB,KAAKye,SAASuR,WAAahwB,KAAK4vB,aAAaK,cACzCjwB,KAAK4vB,aAAaM,cAClBlwB,KAAKye,SAASwI,QAAQnJ,SAAW9d,KAAK4vB,aAAaM,cAIvDlwB,KAAKwjB,aAAexjB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQpJ,SAIpEsS,kBAAmB,WACf,SAAKxwB,GAAGinB,0BAA4B5mB,KAAKye,SAAS4B,WAAWF,YAIzDngB,KAAKye,SAAS6I,KAAK8I,aACfzwB,GAAG8S,kBAAkB0C,sBAIrBxV,GAAG8S,kBAAkByC,oBAAqBlV,KAAKye,SAAS6I,KAAK+I,aAUzE1G,oBAAqB,SAAS2G,EAAS1e,GACnC,GAAI2e,IAAQ,CAEZ,QAAKD,EAAQ5qB,SAIb/F,GAAG+C,KAAK4tB,EAAS,SAAS3tB,EAAK6tB,GAK3B,GAAI7wB,GAAGwH,SAASqpB,GAAa,CAEzB,GAAIC,GAAW,GAAI5uB,QAAO,MAAQ2uB,EAAa,IAAK,IAEpD,IAAgC,MAA5B5e,EAASoB,MAAMyd,GAEf,MADAF,IAAQ,GACD,KAKZA,IAWX1K,WAAY,SAAS6K,EAAMC,EAAkB1pB,GASzC,QAAS6F,GAAEpL,EAAMkvB,GAAe7qB,EAAUA,EAAQ7D,QAAQR,EAAMkvB,GARhE,GAMIC,GAAsBC,EANtB/qB,EAAU/F,KAAKye,SAASsS,SAASL,GACjC9G,KACAoH,KAAWrhB,OAAOghB,GAClBjvB,EAAOsvB,EAAM,GACbrZ,EAAW3X,KAAKumB,aAAatf,GAC7BgqB,EAAiBjxB,KAAKmuB,mBAAmBxW,EA+B7C,OA1BAhY,IAAG+C,KAAKuuB,EAAerH,kBAAmB,SAASjnB,EAAKuuB,GAKhDvxB,GAAGwH,SAAS+pB,IACZtH,EAAkB/mB,KAAKquB,KAI/BL,EAAuBjH,EAAkBpZ,KAAK,MAAMzH,cAEpD+D,EAAE,SAAU9M,KAAKye,SAAS0S,eAAezvB,IACzCoL,EAAE,eAAgB+jB,GAClB/jB,EAAE,cAAe9M,KAAKktB,YAAY+D,EAAeG,YACjDtkB,EAAE,iBAAkB9M,KAAKktB,YAAY+D,EAAeI,eAEpDP,EAAmB/qB,EAAQiN,MAAM,cACR,OAArB8d,GACAnxB,GAAG+C,KAAKouB,EAAkB,SAASnuB,EAAK2uB,GACpCxkB,EAAEwkB,EAAaN,EAAMruB,MAI7B3C,KAAKye,SAASgI,UAAUC,QAAQ,KAAMhlB,EAAMqE,EAASjC,QAE9CiC,GAYXme,aAAc,SAASpK,EAAI9K,GACvB,GAAIhP,KAAKuxB,qBAAqBzX,GAW1B,MAVA9Z,MAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOgD,iBAErCpO,EACAA,EAAS8K,GAGT9Z,KAAK6f,SAASoE,MAAMnK,IAGjB,GAIfuP,kBAAmB,SAASvP,EAAIM,GAC5B,GAAItC,GAAO9X,KACPwxB,EAAcxxB,KAAKkuB,iBAEnB9T,KAAWza,GAAGya,OAAOiD,kBACrBrd,KAAK6jB,+BAA+BhhB,KAAKiX,GAEpCM,IAAWza,GAAGya,OAAOkD,eAC1Btd,KAAK8jB,4BAA4BjhB,KAAKiX,GAGtB,IAAhB0X,IACCxxB,KAAK6jB,+BAA+Bne,QAAU1F,KAAK8jB,4BAA4Bpe,SAEhF4jB,WAAW,WACPxR,EAAK2Z,eAAe3Z,EAAK+L,+BAAgC/L,EAAKgM,8BAC/D,IAIX1F,iCAAkC,WAC9B,GAAItG,GAAO9X,IAEX,IAAIA,KAAKye,SAASgL,YAAYiI,mBAAqB/xB,GAAGyO,UAAYzO,GAAG2O,YAIjE,KAHAgb,YAAW,WACPzkB,OAAO8sB,MAAM7Z,EAAK2G,SAASsS,SAASa,+BACrC,GACG,GAAIjyB,IAAGwB,MAAMnB,KAAKye,SAASsS,SAASa,+BAIlDC,8BAA+B,SAAS/X,EAAIpY,EAAMowB,EAAU5G,GAGxD,IAAK4G,EAASrmB,QACV,GAAIyf,GAAsB,MAAfA,EAAI9Q,SAAmB0X,EAAShoB,MACvC9J,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,8BAAgCwpB,EAAI9Q,OAAQ8Q,OAErF,CACD,GAAI6G,GAAcD,EAAShoB,MAAQgoB,EAAShoB,MAAQ9J,KAAKye,SAASpb,KAAK2uB,oBACvEhyB,MAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAMqwB,EAAa7G,KAKnE+G,6CAA8C,SAASC,EAAWjoB,EAAOsQ,EAAOsD,EAAQC,GACpF,GAAIhG,GAAO9X,IAEX,IAAIiK,EAAMvE,OAAS6U,EACf,GAAI2X,IAAclyB,KAAKye,SAASqL,WAAWqI,uBAEvC7I,WAAW,WACP,GAAI8I,GAAuBta,EAAKsW,yBAAyBnkB,EAAMsQ,IAC3D5C,EAAWG,EAAKyO,aAAatc,EAAMsQ,GAAOY,MAC1CoI,EAASzL,EAAK6J,WAAWhK,EAE7BG,GAAKmQ,wBACDvmB,KAAM,aACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAU4L,WAAYva,EAAMsa,EAAsB7O,GAClFvM,UAAWrX,GAAG4P,KAAKuI,EAAKwa,2BAA4Bxa,EAAM7N,EAAOsQ,EAAOsD,EAAQC,GAChF7G,UAAWtX,GAAG4P,KAAKuI,EAAKya,2BAA4Bza,EAAM7N,EAAOsQ,EAAOsD,EAAQC,GAChFsK,WAAY,SAAWgK,EAAqB1wB,KAAO,YAAc0wB,EAAqBlX,QAE3F,OAEF,KAAKgX,EACN,KAAO3X,EAAQtQ,EAAMvE,OAAQ6U,IACzBzC,EAAKmV,oBAAoBhjB,EAAMsQ,GAAOT,KAMtD2X,eAAgB,SAASe,EAAYC,GACjCzyB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAe2O,cAAcF,EAAYC,EAAQzyB,KAAKqjB,iBAElFrjB,KAAKye,SAASgI,UAAUiM,cAAc/yB,GAAG6B,UAAWgxB,GAAa7yB,GAAG6B,UAAWixB,IAE/EzyB,KAAK6jB,kCACL7jB,KAAK8jB,gCAeTyI,aAAc,SAASzS,EAAIpY,EAAM4qB,EAAcpB,EAAKlc,GAChD,GAAI8I,GAAO9X,IAIX,IAFA8X,EAAKuL,gBAAgBvJ,GAAMwS,EAAaxU,EAAK2G,SAASwF,MAAM2G,8BAExD9S,EAAK6a,iBAAiB7Y,GAAK,CAC3B,GAAI8Y,GAAyD,IAAvC9a,EAAK2G,SAASwF,MAAM4O,gBAkB1C,OAhBA/a,GAAK+Z,8BAA8BjiB,MAAMkI,EAAMhQ,WAC/CgQ,EAAK2G,SAASgI,UAAU4F,YAAYvS,EAAIpY,EAAMoW,EAAKqL,aAAarJ,IAChEhC,EAAKgb,mBAAmBhZ,EAAIpY,GAE5BoW,EAAK6H,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOgD,iBACzCtF,EAAKsL,eAAetJ,GAAMwP,WAAW,WACjCxR,EAAKhS,IAAI,sBAAwBpE,EAAO,OAEpCsN,EACAA,EAAS8K,GAGThC,EAAK+H,SAASoE,MAAMnK,IAEzB8Y,IAEI,IAIfE,mBAAoB,SAAShZ,EAAIpY,GAC7B1B,KAAK8F,IAAI,WAAa9F,KAAKye,SAASwF,MAAM4O,iBAAmB,4BAA8BnxB,EAAO,QAItG6vB,qBAAsB,SAASzX,GAC3B,GACIlI,GADAmhB,EAAY/yB,KAAK2iB,iBAGrB,OAAI3iB,MAAKqjB,gBAAgBvJ,IACrB9Z,KAAK8F,IAAI,gCAAkCgU,EAAI,SACxC,GAEF9Z,KAAK6f,SAASY,QAAQ3G,IAC3BlI,EAAW5R,KAAK4f,QAAQ9F,GAEpB9Z,KAAKye,SAASgI,UAAUuM,cAAclZ,EAAIlI,MAAc,IAIxDmhB,EAAY,GAAK/yB,KAAK4iB,qBAAuB,EAAImQ,GACjD/yB,KAAK6lB,WAAW,0BACT,IAGX7lB,KAAK8F,IAAI,wBAA0B8L,EAAW,UAAYkI,EAAK,SACxD,MAGP9Z,KAAK8F,IAAI,IAAMgU,EAAK,2BAA4B,UACzC,IAIfwR,UAAW,SAASxR,EAAIpY,GACpB1B,KAAK4iB,uBAELqQ,aAAajzB,KAAKojB,eAAetJ,GAEjC,IAAIoZ,GAAkBvzB,GAAG2F,QAAQtF,KAAKqe,WAAYvE,IAC7C9Z,KAAKye,SAASuR,YAAckD,GAAmB,GAChDlzB,KAAKqe,WAAWrC,OAAOkX,EAAiB,GAG5ClzB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO4C,WAG7CmO,YAAa,SAASrR,EAAIpY,EAAMY,EAAQ4oB,GAoBpC,MAnBK5oB,GAAOmJ,SASJnJ,EAAO6jB,eACPnmB,KAAKmhB,eAAerH,GAAMxX,EAAO6jB,cAGrCnmB,KAAKwiB,eACLxiB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOiD,qBAbzCrd,KAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOkD,eAErChb,EAAOtC,KAAKye,SAASwF,MAAM2G,iCAAkC,IAC7D5qB,KAAKqjB,gBAAgBvJ,IAAM,IAYnC9Z,KAAK6xB,8BAA8B/X,EAAIpY,EAAMY,EAAQ4oB,KAE9C5oB,EAAOmJ,SAGlB+b,UAAW,SAAS1N,GAChB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOoD,WAG7CkI,kBAAmB,SAAS5L,EAAI4N,EAAUC,GAC3B3nB,KAAK4f,QAAQ9F,EAEpB6N,GACA3nB,KAAK0vB,oBAAoB5V,EAAI4N,GAG7B1nB,KAAKyvB,qBAAqB3V,IAIlCsQ,eAAgB,SAAS/gB,GACrB,GAAI8pB,EAEJ,IAAIxzB,GAAG8S,kBAAkBoC,cAAe,CACpC,IAAKse,EAAY,EAAGA,EAAY9pB,EAAMgW,MAAM3Z,OAAQytB,IAChDnzB,KAAKomB,sBAAsB/c,EAAMgW,MAAM8T,GAAY9pB,EAGvDrJ,MAAK+d,SAAS1U,EAAMgW,WAGfhW,GAAM3C,MAAMhB,OAAS,GAC1B1F,KAAK+d,SAAS1U,EAGlB1J,IAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjCA,EAAO/J,WAIfwR,YAAa,SAASlR,EAAIpY,EAAMopB,EAAQC,GACpC/qB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAeqP,qBAAqBtZ,EAAIgR,EAAQC,IAGhFsI,UAAW,SAASvZ,EAAIpY,KAIxB4xB,yBAA0B,SAASxZ,EAAIpY,GACnC1B,KAAKqzB,UAAUzjB,MAAM5P,KAAM8H,WAC3B9H,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOyC,WACzC7c,KAAKuzB,aAAa3jB,MAAM5P,KAAM8H,WAE1B9H,KAAKye,SAASuR,YACdhwB,KAAKye,SAASgI,UAAU+M,YAAY5jB,MAAM5P,KAAM8H,WAChD9H,KAAKogB,YAAYtG,KAGjB9Z,KAAKyzB,eAAe3Z,GACpB9Z,KAAKye,SAASgI,UAAU+M,YAAY5jB,MAAM5P,KAAM8H,aAIxDwY,gBAAiB,SAASxG,EAAI4Z,EAAmBC,GAC7C,GACIC,GADA3Z,EAAOja,KAAK6iB,QAAQ/I,EAOxB,OAJI4Z,KACAE,EAA4Bj0B,GAAG4P,KAAKmkB,EAAmB1zB,KAAM8Z,EAAIG,EAAM0Z,IAGvE3zB,KAAKmwB,qBACLnwB,KAAKioB,wBACDvmB,KAAM,iBACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAUoN,eAAgB7zB,KAAM8Z,GAChE9C,UAAW4c,GACPj0B,GAAG4P,KAAKvP,KAAK8zB,eAAeC,WAAY/zB,KAAM8Z,EAAIG,EAAM0Z,GAC5DvL,WAAYtO,KAET,IAGP9Z,KAAK8F,IAAI,iCAAmCgU,EAAK,wHACuB,SACjE,IAIfyZ,aAAc,SAASzZ,KAIvBka,iBAAkB,SAASlJ,EAAQC,GAC/B/qB,KAAKye,SAASgI,UAAUwN,gBAAgBnJ,EAAQC,IAGpDS,cAAe,SAAS1R,KAIxB4R,UAAW,SAAS5R,EAAIpY,GACpB1B,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO8C,YAG7C4O,eAAgB,SAAShS,EAAI+R,KAI7BK,sBAAuB,SAASpS,EAAI+R,IAC3B7rB,KAAKqjB,gBAAgBvJ,IAAO9Z,KAAKye,SAASwF,MAAMiQ,aACjDl0B,KAAKmjB,aAAarJ,GAAM,IAIhCsP,sBAAuB,SAAStP,EAAIgC,EAAWD,GAEvCA,IAAclc,GAAGya,OAAO6C,QACxBgW,aAAajzB,KAAKojB,eAAetJ,KAIzCqa,gCAAiC,SAAS5F,GACtC,GAAIzW,GAAO9X,IAEXL,IAAG+C,KAAK6rB,EAAc,SAAS5rB,EAAK0rB,GAChCvW,EAAKmV,oBAAoBoB,EAAYvU,OAI7Csa,gCAAiC,SAASC,EAAuBpqB,EAAO4T,EAAQC,EAAUyF,GACtF,GAAIoC,GACAoN,EAAY/yB,KAAK2iB,kBACjB2R,EAAmCt0B,KAAK4iB,oBAE1B,KAAdmQ,GAAmBuB,GAAoCvB,EACnD9oB,EAAMvE,OAAS,EACf1F,KAAKioB,wBACDvmB,KAAM,aACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAU4L,WAAYryB,KAAMq0B,EAAsB,GAAI9Q,GACtFvM,UAAWrX,GAAG4P,KAAKvP,KAAKsyB,2BAA4BtyB,KAAMiK,EAAO,EAAG4T,EAAQC,GAC5E7G,UAAWtX,GAAG4P,KAAKvP,KAAKuyB,2BAA4BvyB,KAAMiK,EAAO,EAAG4T,EAAQC,GAC5EsK,WAAY,SAAWne,EAAM,GAAGkR,KAAKzZ,KAAO,YAAcuI,EAAM,GAAGkR,KAAKD,OAI5Elb,KAAK6lB,WAAW,iBAIpB7lB,KAAKm0B,gCAAgClqB,GACrC0b,EAAe3lB,KAAKye,SAASsS,SAASwD,kBACjCryB,QAAQ,gBAAiBoyB,GACzBpyB,QAAQ,iBAAkB6wB,GAC/B/yB,KAAKwmB,YAAYb,KAIzB4M,2BAA4B,SAAStoB,EAAOsQ,EAAOsD,EAAQC,GACvD,GAAI0W,GAAYja,EAAQ,CAExBva,MAAKitB,oBAAoBhjB,EAAMsQ,GAAOT,GAAI7P,EAAMsQ,GAAOY,KAAKzZ,MAE5D1B,KAAKiyB,8CAA6C,EAAOhoB,EAAOuqB,EAAW3W,EAAQC,IAGvFwU,2BAA4B,SAASroB,EAAOsQ,EAAOsD,EAAQC,GACvD,GAAIhG,GAAO9X,KACPw0B,EAAYja,EAAQ,EACpB6X,EAAuBpyB,KAAKouB,yBAAyBnkB,EAAMsQ,GAE/Dva,MAAKy0B,wBAAwBxqB,EAAMsQ,GAAQ6X,GACtC3b,KACD,WACIqB,EAAK4c,QAAQzqB,EAAMsQ,GAAOT,GAAI+D,EAAQC,GACtChG,EAAKma,8CAA6C,EAAMhoB,EAAOuqB,EAAW3W,EAAQC,IAEtF,WACIhG,EAAKma,8CAA6C,EAAOhoB,EAAOuqB,EAAW3W,EAAQC,MAK/F0B,uBAAwB,SAASvV,EAAO4T,EAAQC,GAC5C,GAAqB,IAAjB7T,EAAMvE,OAEN,WADA1F,MAAK6lB,WAAW,eAIpB,IAAIwO,GAAwBr0B,KAAKsuB,0BAA0BrkB,GACvD0N,EAAW3X,KAAKumB,aAAatc,EAAM,GAAGkR,MACtCoI,EAASvjB,KAAK2hB,WAAWhK,EAE7B3X,MAAKioB,wBACDvmB,KAAM,kBACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAUkO,gBAAiB30B,KAAMq0B,EAAuB9Q,GACxFvM,UAAWrX,GAAG4P,KAAKvP,KAAKo0B,gCAAiCp0B,KAAMq0B,EAAuBpqB,EAAO4T,EAAQC,EAAUyF,GAC/GtM,UAAWtX,GAAG4P,KAAKvP,KAAKm0B,gCAAiCn0B,KAAMiK,GAC/Dme,WAAY,sBAIpBwM,wBAAyB,WACrB,GAAI9c,GAAO9X,IAEXA,MAAKsqB,gBAAgBrqB,OAAO4E,OAAQ,eAAgB,SAAS4J,GACzD,GAAIqJ,EAAKmK,gBAKL,MAJAxT,GAAIA,GAAK5J,OAAOgwB,MAEhBpmB,EAAEC,YAAcoJ,EAAK2G,SAASsS,SAAS+D,QAEhChd,EAAK2G,SAASsS,SAAS+D,WAQ1ClR,oBAAqB,WACjB,GAAI9L,GAAO9X,KACP4X,EAAU5X,KAAKye,SAASiF,OAGxB/jB,IAAGo1B,SAA6C,MAAlC/0B,KAAKye,SAASiF,QAAQ5F,WAC/B9d,KAAKg1B,WACNr1B,GAAG6B,OAAOoW,GAAU0P,KAAMtnB,KAAKye,SAAS6I,OAExC1P,EAAQ9R,IAAMnG,GAAG4P,KAAKvP,KAAK8F,IAAK9F,MAChC4X,EAAQqd,cAAgBt1B,GAAG4P,KAAKvP,KAAKme,eAAgBne,MAErDA,KAAKg1B,SAAW,GAAIr1B,IAAGo1B,QAAQnd,IAGnC0R,WAAW,WACPxR,EAAKkd,SAASE,UAAUze,KAAK,SAASqb,EAAUpK,GAC5C5P,EAAKqd,0BACLrd,EAAK2G,SAASgI,UAAU2O,yBAAyBtD,GAAU,EAAMpK,IAElE,SAASoK,EAAUpK,GAElB5P,EAAK2G,SAASgI,UAAU2O,yBAAyBtD,GAAU,EAAOpK,MAEvE,KAIXyN,wBAAyB,aAEzBzI,SAAU,SAAS5S,EAAIyC,GACnBvc,KAAK2f,YAAYrD,WAAWxC,EAAIyC,GAChCvc,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAesR,UAAUvb,IAGzD6Y,iBAAkB,SAAS7Y,GACvB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAGhD,WAAK9Z,KAAKqjB,gBAAgBvJ,IACnB9Z,KAAKye,SAASwF,MAAMiQ,YACpBxU,EAAWtF,SAAWza,GAAGya,OAAO6C,SAELnZ,SAA1B9D,KAAKmjB,aAAarJ,KAClB9Z,KAAKmjB,aAAarJ,GAAM,GAGxB9Z,KAAKmjB,aAAarJ,GAAM9Z,KAAKye,SAASwF,MAAMqR,oBAC5Ct1B,KAAKmjB,aAAarJ,IAAO,GAClB,IAOnB2Z,eAAgB,SAAS3Z,GACrB9Z,KAAKqe,WAAWxb,KAAKiX,IAIzBuV,aAAc,SAASvV,GACnB,GAAInC,EAGAA,GADAhY,GAAG8S,kBAAkBoC,cACV7U,KAAK6f,SAASwB,QAAQvH,GAAIwM,WAG1BtmB,KAAKumB,aAAavmB,KAAK6f,SAAS3G,SAASY,IAGpDnC,IACA3X,KAAK4hB,qBAAqB9H,GAAMnC,IAIxCyN,4BAA6B,SAASmQ,GAClCv1B,KAAKye,SAAS5N,KAAKjR,QAAU21B,EAE7Bv1B,KAAK4vB,aAAejwB,GAAGkwB,aAAe,GAAIlwB,IAAGkwB,YACrC7vB,KAAKye,SAAS5N,KAAMlR,GAAG4P,KAAKvP,KAAK4lB,kBAAmB5lB,MAAOL,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OAGjFA,KAAK4vB,cAAgB5vB,KAAK4vB,aAAaE,iBACvC9vB,KAAKwjB,aAAa0F,YAAY,KAAMlpB,KAAK4vB,aAAaG,uBAEtD/vB,KAAKye,SAASuR,WAAahwB,KAAK4vB,aAAaK,cACzCjwB,KAAK4vB,aAAaM,aAClBlwB,KAAKilB,YAAYjlB,KAAK4vB,aAAaM,eAK/CwE,QAAS,SAAS5a,EAAI+D,EAAQC,GAC1B,GAAIpc,GAAO1B,KAAK4f,QAAQ9F,EAEpB+D,IACA7d,KAAKwlB,UAAU3H,EAAQ/D,GAGvBgE,GACA9d,KAAKilB,YAAYnH,EAAUhE,GAG/B9Z,KAAKioB,wBACDvmB,KAAM,WACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAU+O,SAAUx1B,KAAM8Z,EAAIpY,GAC9DsV,UAAWrX,GAAG4P,KAAKvP,KAAKszB,yBAA0BtzB,KAAM8Z,EAAIpY,GAC5DuV,UAAWtX,GAAG4P,KAAKvP,KAAKitB,oBAAqBjtB,KAAM8Z,EAAIpY,GACvD0mB,WAAYtO,KAIpBsG,YAAa,SAAStG,GACb9Z,KAAK6f,SAASlW,OAAOmQ,IACtB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO2C,SAIjD+I,mBAAoB,WAIhB,IAHA,GAAI2P,GAAYC,EACZ5d,EAAO9X,KAEJA,KAAKqe,WAAW3Y,QACnB+vB,EAAaz1B,KAAKqe,WAAWpM,QAC7BjS,KAAKogB,YAAYqV,EAIrBC,GAAkB11B,KAAKoiB,YAAYhI,OAAQza,GAAGya,OAAOY,aAAatV,OAC9DgwB,IACA/1B,GAAGmG,IAAI,qBAAuB4vB,EAAkB,yEAChDpM,WAAW,WACPxR,EAAKgO,sBACN,OAYX2O,wBAAyB,SAASpG,EAAa+D,GAC3C,GAAIta,GAAO9X,KACPmb,EAAQ,WACJ,MAAIkT,GAAYlT,eAAgBxb,IAAGwX,UACxBkX,EAAYlT,KAAK/D,cAErBiX,EAAYlT,QAEvBzZ,EAAO0wB,EAAqB1wB,KAC5BwZ,EAAOkX,EAAqBlX,KAC5BvD,EAAW3X,KAAKumB,aAAa8H,EAAYlT,MACzC8V,EAAiBjxB,KAAKmuB,mBAAmBxW,GACzCge,EAAkB,GAAIh2B,IAAG4L,OAQ7B,OANAoqB,GAAgBlf,KACZ,aACA,WACIqB,EAAKmV,oBAAoBoB,EAAYvU,GAAIpY,KAG7C/B,GAAG6I,cAAc2S,KAAUnb,KAAK2pB,oBAAoBsH,EAAerH,kBAAmBloB,IACtF1B,KAAK6lB,WAAW,YAAankB,EAAMyZ,GAC5Bwa,EAAgBhqB,WAGtB3L,KAAKye,SAASqL,WAAW8L,YAAuB,IAAT1a,EAKxCA,EAAO,GAAK+V,EAAeG,WAAalW,EAAO+V,EAAeG,WAC9DpxB,KAAK6lB,WAAW,YAAankB,EAAMyZ,GAC5Bwa,EAAgBhqB,WAGvBuP,EAAO,GAAKA,EAAO+V,EAAeI,cAClCrxB,KAAK6lB,WAAW,eAAgBnkB,EAAMyZ,GAC/Bwa,EAAgBhqB,YAGvBhM,GAAGk2B,iBAAmBl2B,GAAG8S,kBAAkBgD,eAAiB9V,GAAGuI,OAAOiT,GACtE,GAAIxb,IAAGk2B,gBAAgB1a,EAAMxb,GAAG4P,KAAKuI,EAAKhS,IAAKgS,IAAOge,SAAS7E,EAAe8E,OAAOtf,KACjFkf,EAAgBlqB,QAChB,SAASuqB,GACLle,EAAK+N,WAAWmQ,EAAY,aAAct0B,EAAMyZ,GAChDwa,EAAgBhqB,YAKxBgqB,EAAgBlqB,UAGbkqB,IA3BH31B,KAAK6lB,WAAW,aAAcnkB,EAAMyZ,GAC7Bwa,EAAgBhqB,YA6B/BsqB,eAAgB,WACZ,GAAIne,GAAMoe,EAAcnqB,CAExB+L,GAAO9X,KAEPk2B,EAAe,SAASx0B,EAAMsN,EAAUrH,GACpC,GAAIwuB,EAEJ,KACI,MAAOnnB,GAASY,MAAMkI,EAAMnQ,GAEhC,MAAOyuB,GACHD,EAAWC,EAAUrwB,SAAWqwB,EAAU9vB,WAC1CwR,EAAKhS,IAAI,wBAA0BpE,EAAO,gBAAkBy0B,EAAU,UAK9E,KAAKpqB,IAAQ/L,MAAKye,SAASgI,WACtB,WACG,GAAI4P,GAAcC,CAClBD,GAAetqB,EACfuqB,EAAexe,EAAK2G,SAASgI,UAAU4P,GACvCve,EAAK2G,SAASgI,UAAU4P,GAAgB,WACpC,MAAOH,GAAaG,EAAcC,EAAcxuB,oBCr7DvE,WACG,YAEAnI,IAAG42B,kBAAoB,SAAS/e,GAC5B,GAAIM,GAAO9X,IAGXA,MAAKye,UACDuE,OAAO,EACPO,OAAQ,KACR/Z,UAAU,EACVud,eAAgB,EAChByP,6BAA6B,EAC7BxG,YAAY,EACZyG,kBAAkB,EAElBxP,SACIE,iBACArJ,SAAU,iBACV4Y,cAAe,aACfC,gBAAgB,EAChBxM,UAAW,SACXtD,OAAQ,OACR+P,mBAAmB,EACnB/Y,UACAgZ,cAAc,EACdC,oBAAoB,EACpBC,kBAAmB,kBACnB7P,SAAU,UAGd4C,YACIF,qBACAwH,UAAW,EACXC,aAAc,EACd0B,UAAW,EACXZ,wBAAwB,EACxBla,YAAa,KACb8d,OACIiB,UAAW,EACXC,SAAU,EACVC,UAAW,EACXC,SAAU,GAEdvB,YAAY,GAGhBnP,WACI+O,SAAU,SAAS1b,EAAIpY,KACvB8xB,YAAa,SAAS1Z,EAAIpY,KAC1BupB,WAAY,SAASnR,EAAIpY,EAAM4qB,EAAc8K,KAC7C1E,cAAe,SAASF,EAAYC,KACpCrH,SAAU,SAAStR,EAAIpY,KACvB+pB,SAAU,SAAS3R,EAAIpY,KACvBkqB,cAAe,SAAS9R,EAAIpY,EAAMmqB,KAClCI,qBAAsB,SAASnS,EAAI+R,EAAWS,EAAcpB,KAC5DiB,SAAU,SAASrS,EAAIlI,EAAUia,EAAWO,KAC5CvB,WAAY,SAAS/Q,EAAIpY,EAAMopB,EAAQC,KACvCkJ,gBAAiB,SAASnJ,EAAQC,KAClCrE,QAAS,SAAS5M,EAAIpY,EAAM+f,EAAQ4V,KACpChL,YAAa,SAASvS,EAAIpY,EAAM41B,KAChCtE,cAAe,SAASlZ,EAAIpY,KAC5BizB,gBAAiB,SAAS4C,KAC1BlF,WAAY,SAASkF,KACrB1D,eAAgB,SAAS/Z,KACzByN,SAAU,SAASzN,KACnB2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,KACzCO,gBAAiB,SAASjd,KAC1BsQ,eAAgB,SAASzB,EAAIgC,EAAWD,KACxCuZ,yBAA0B,SAAStD,EAAUrmB,EAASic,MAG1DqJ,UACIyG,UAAW,qEACXC,UAAW,yDACXC,aAAc,4DACdC,WAAY,yDACZC,aAAc,sBACdrD,kBAAmB,6EACnBsD,oBAAqB,qBACrBC,mBAAoB,qBACpBC,oBAAqB,4BACrBC,mBAAoB,4BACpBC,sBAAuB,mDACvBnD,QAAS,8EACTlD,6BAA8B,6KAGlC3N,OACIiQ,YAAY,EACZoB,gBAAiB,EACjBzC,iBAAkB,EAClBjI,6BAA8B,gBAGlCb,SACIE,YAAa,yBACbD,YAAa,0BAGjBhV,UACImL,SAAS,EACT+X,YACI/X,SAAS,GAEbgY,WAAW,EACXC,YACIpM,UAAW,cACXqM,eAAgB,mBAChBC,UAAW,cACXC,cAAe,kBACfC,WAAY,gBAEhBC,SAAU,SAAS3e,GACf,MAAO,MAGXrO,SACIqS,SAAU,KAEVyG,QAAS,SAASzK,GACd,MAAO,OAGX4e,aAAa,EAEb7R,OAAQ,OAERhJ,OAAQ,SAAS/D,GACb,MAAO,OAGX6e,mBAIR7iB,QACIqK,SAAS,EACTyY,gBAAiB,EACjBR,YACIS,SAAU,YAEdC,WAAY,SAASnY,GACjB,WAIRwQ,eAAgB,SAAS4H,GACrB,MAAOA,IAGX11B,MACI2uB,qBAAsB,gCACtB3H,eAAgB,aAChB8C,aAAc,KAAM,KAAM,KAAM,KAAM,KAAM,OAGhD9M,YACIF,SAAS,EACT0G,OAAQ,SACR/I,SAAU,iBACVqJ,iBACAtJ,WAGJyJ,MACI8I,UAAU,EACV4I,iBAAiB,EACjB3I,UAAU,GAGd3R,OACIC,YAAa,aAGjBoJ,OACID,cAAe,KACfnJ,YAAa,gBAGjB+P,QACIzgB,KAAK,EAGLsV,OAAQ,MASZiK,gBAIA9J,SACI5F,SAAU,KACVD,UACAsJ,iBACAxD,gBAAgB,GAIpB9S,MAEIjR,QAAS,UAGTowB,YAAY,EAGZiJ,iBAAiB,GAIrBljB,SACImjB,cAAe,KAGfC,cAAc,EAGdC,QAAQ,EAIRC,YAAa,KAEbC,eAAgB,GAEhBC,YAAa,kBAEbC,aAAa,EAGbC,UAGJhQ,aACIC,gBAAgB,EAChBgI,mBAAmB,EACnBxH,kBAAkB,IAK1BvqB,GAAG6B,OAAOxB,KAAKye,SAAUjH,GAAG,GAE5BxX,KAAKsjB,YACLtjB,KAAKutB,qBACLvtB,KAAK4hB,wBAEL5hB,KAAKi2B,iBACLj2B,KAAKsqB,gBAAmB,GAAI3qB,IAAGkS,eAE/B7R,KAAKqe,cACLre,KAAKmjB,gBACLnjB,KAAKojB,kBACLpjB,KAAKqjB,mBACLrjB,KAAKmhB,kBAELnhB,KAAK4iB,qBAAuB,EAC5B5iB,KAAKwiB,aAAe,EACpBxiB,KAAK2f,YAAc3f,KAAKmpB,2BAExBnpB,KAAK2vB,4BAEL3vB,KAAKwkB,oBAAsBxkB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQE,eACnEnnB,KAAK4kB,8BAAgC5kB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAW8G,eAEhFnnB,KAAKglB,uBAAyBhlB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAWxC,QAEzE7d,KAAK8hB,eAAiB9hB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQnJ,UAC9D9d,KAAK8kB,yBAA2B9kB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAWvC,UAE3E9d,KAAK6f,SAAW7f,KAAKuqB,uBAErBvqB,KAAK8zB,eAAiBn0B,GAAGinB,yBAA2B5mB,KAAK2mB,uBAErD3mB,KAAKye,SAAS8E,SACdvjB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKye,SAAS8E,OACvB1L,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGPnZ,KAAKstB,4BAELttB,KAAKyuB,sBAEDzuB,KAAKye,SAASsJ,MAAMD,gBAChBnoB,GAAGkoB,aACH7nB,KAAKyjB,cAAgBzjB,KAAK4nB,sBAG1B5nB,KAAK8F,IAAI,iCAAkC,UAInD9F,KAAKye,SAASgY,kBAAoBz2B,KAAK40B,0BAEvC50B,KAAKkhB,gBAAkBvhB,GAAG+5B,gBAAkB,GAAI/5B,IAAG+5B,eAAe/5B,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OACpFA,KAAK4jB,sBAEL5jB,KAAK6jB,kCACL7jB,KAAK8jB,+BAEL9jB,KAAK25B,QAAWh6B,GAAG0kB,QAAU,GAAI1kB,IAAG0kB,OAAOrkB,KAAKye,SAAS1I,QAASpW,GAAG4P,KAAKvP,KAAK8F,IAAK9F,WAChFA,KAAK25B,QAAQxZ,UACbngB,KAAKkvB,sBAAwBvvB,GAAG4P,KAAKvP,KAAK25B,QAAQC,cAAe55B,KAAK25B,UAGtEh6B,GAAGk6B,eAAiBl6B,GAAG8S,kBAAkBoD,cACzC7V,KAAK+jB,eAAiB,GAAIpkB,IAAGk6B,cACzBl6B,GAAG4P,KAAKvP,KAAKg0B,iBAAkBh0B,MAE/B,SAAS8Z,GACL,GAAIggB,GAAQhiB,EAAK6H,YAAYnE,UAAU1B,GAAIA,GAC3C,OAAQggB,IAASA,EAAM5e,MAAS,KAK5Clb,KAAK2iB,kBAAoB3iB,KAAKye,SAASqL,WAAWiJ,UAElD/yB,KAAKgkB,uBAAyBhkB,KAAKqoB,gBAIvC1oB,GAAG42B,kBAAkBlwB,UAAY1G,GAAG+d,cACpC/d,GAAG6B,OAAO7B,GAAG42B,kBAAkBlwB,UAAW1G,GAAGomB,mBC3UjDpmB,GAAGo6B,cAAgB,SAASviB,GACxB,YA2CA,SAASwiB,KACL,MAAOr6B,IAAG2F,SAAS,MAAO,OAAQ,QAASsS,EAAQiP,SAAW,EAMlE,QAASoT,GAAyB1V,GAC9B,GAAI2V,IAAoB,CASxB,OAPAv6B,IAAG+C,KAAKw3B,EAAmB,SAASv3B,EAAKw3B,GACrC,GAAIx6B,GAAG2F,SAAS,SAAU,kBAAmB,mBAAoB,gBAAiB60B,GAAU,EAExF,MADAD,IAAoB,GACb,IAIRA,EAGX,QAASE,GAAMlP,GAEX,MAAOtT,GAAQ0P,KAAK8I,UAAoCtsB,SAAxBonB,EAAIhY,gBAIxC,QAASmnB,KACL,GAAI3S,EAeJ,QAbI7iB,OAAO+E,gBAAkB/E,OAAOgF,iBAChC6d,EAAW/nB,GAAG+J,oBAEmB5F,SAA7B4jB,EAASxU,kBACTwU,EAAW,GAAItU,gBAEfsU,EAASlc,OAAS,aAClBkc,EAAShc,QAAU,aACnBgc,EAAS4S,UAAY,aACrB5S,EAAS6S,WAAa,eAIvB7S,EAIX,QAAS8S,GAAY1gB,EAAI2gB,GACrB,GAAI/S,GAAWgT,EAAY5gB,IAAO4gB,EAAY5gB,GAAIoR,GAkBlD,OAhBKxD,KAEGA,EADA+S,EACWA,EAGP7iB,EAAQ0P,KAAK8I,SACFiK,IAGA16B,GAAG+J,oBAItBgxB,EAAY5gB,GAAIoR,IAAMxD,GAGnBA,EAIX,QAASiT,GAAQ7gB,GACb,GAEI8gB,GAFAvqB,EAAI1Q,GAAG2F,QAAQu1B,EAAO/gB,GACtBsT,EAAMxV,EAAQmP,qBAGX2T,GAAY5gB,GACnB+gB,EAAM7e,OAAO3L,EAAG,GAEZwqB,EAAMn1B,QAAU0nB,GAAO/c,EAAI+c,IAC3BwN,EAASC,EAAMzN,EAAM,GACrB0N,EAAYF,IAIpB,QAAS3P,GAAWnR,EAAIihB,GACpB,GAAI7P,GAAMsP,EAAY1gB,GAClB+M,EAASjP,EAAQiP,OACjBc,EAAUoT,KAAa,CAE3BJ,GAAQ7gB,GAEJ6N,EACA7hB,EAAI+gB,EAAS,gBAAkB/M,EAAK,cAAe,SAE7CsgB,EAAMlP,IAAS8P,EAAqB9P,EAAI9Q,UAC9CuN,GAAU,EACV7hB,EAAI+gB,EAAS,gBAAkB/M,EAAK,+BAAiCoR,EAAI9Q,OAAQ,UAGrFxC,EAAQqT,WAAWnR,EAAIoR,EAAKvD,GAGhC,QAASsT,GAAUnhB,GACf,GAEI+D,GAFAqd,EAAiBR,EAAY5gB,GAAIqhB,iBACjCC,EAAiBxjB,EAAQwjB,cAqB7B,OAlBIxjB,GAAQwP,YAAYrF,MACpBlE,EAASjG,EAAQwP,YAAYrF,IAAIjI,IAGjCohB,GACAv7B,GAAG+C,KAAKw4B,EAAgB,SAASx5B,EAAMkB,GACnCib,EAASA,MACTA,EAAOnc,GAAQkB,IAInBw4B,GACAz7B,GAAG+C,KAAK04B,EAAgB,SAAS15B,EAAMkB,GACnCib,EAASA,MACTA,EAAOnc,GAAQkB,IAIhBib,EAGX,QAASid,GAAYhhB,EAAIuhB,GACrB,GAIIC,GAJApQ,EAAMsP,EAAY1gB,EAAIuhB,GACtBxU,EAASjP,EAAQiP,OACjBhJ,EAASod,EAAUnhB,GACnByhB,EAAUb,EAAY5gB,GAAIyhB,OA+C9B,OA5CA3jB,GAAQ4jB,OAAO1hB,GAEfwhB,EAAMG,EAAU3hB,EAAI+D,EAAQ6c,EAAY5gB,GAAI4hB,uBAGxCtB,EAAMlP,IACNA,EAAI1f,OAASmwB,EAAkB7hB,GAC/BoR,EAAIxf,QAAUkwB,EAAmB9hB,IAGjCoR,EAAI2Q,mBAAqBC,EAA8BhiB,GAG3DiiB,EAA0BjiB,GAG1BoR,EAAI8Q,KAAKnV,EAAQyU,GAAK,GAIlB1jB,EAAQ0P,KAAK8I,UAAYxY,EAAQ0P,KAAK0R,kBAAoBoB,EAAMlP,KAChEA,EAAIhY,iBAAkB,GAG1B+oB,EAAWniB,GAEXhU,EAAI,WAAa+gB,EAAS,gBAAkB/M,GAExCyhB,EACArQ,EAAIgR,KAAKX,GAEJY,IAAgCte,EACrCqN,EAAIgR,OAECre,GAAUjG,EAAQwkB,aAAexkB,EAAQwkB,YAAYrzB,cAAczD,QAAQ,sCAAwC,EACxH4lB,EAAIgR,KAAKv8B,GAAGkQ,QAAQgO,EAAQ,KAEvBA,GAAUjG,EAAQwkB,aAAexkB,EAAQwkB,YAAYrzB,cAAczD,QAAQ,qBAAuB,EACvG4lB,EAAIgR,KAAKhrB,KAAKmrB,UAAUxe,IAGxBqN,EAAIgR,KAAKre,GAGNqN,EAGX,QAASuQ,GAAU3hB,EAAI+D,EAAQ6d,GAC3B,GAAI5d,GAAWlG,EAAQyP,cAActF,IAAIjI,GACrCwiB,EAAY5B,EAAY5gB,GAAIwiB,SAehC,OAZiBx4B,SAAbw4B,IACAxe,GAAY,IAAMwe,GAGlBH,GAA+Bte,IAC/BC,EAAWne,GAAGkQ,QAAQgO,EAAQC,IAG9B4d,IACA5d,EAAWne,GAAGkQ,QAAQ6rB,EAAuB5d,IAG1CA,EAKX,QAASge,GAA8BhiB,GACnC,MAAO,YACgC,IAA/B0gB,EAAY1gB,GAAIyiB,YAChBtR,EAAWnR,IAKvB,QAASiiB,GAA0BjiB,GAC/B,GAAI+Q,GAAajT,EAAQiT,UAErBA,KACA2P,EAAY1gB,GAAInQ,OAAO4wB,WAAa,SAAS9rB,GACrCA,EAAE+tB,kBACF3R,EAAW/Q,EAAIrL,EAAEqc,OAAQrc,EAAEsc,SAQ3C,QAAS4Q,GAAkB7hB,GACvB,MAAO,YACHmR,EAAWnR,IAMnB,QAAS8hB,GAAmB9hB,GACxB,MAAO,YACHmR,EAAWnR,GAAI,IAIvB,QAASmiB,GAAWniB,GAChB,GAAIoR,GAAMsP,EAAY1gB,GAClBqN,EAAgBvP,EAAQuP,cACxBsV,EAAkB/B,EAAY5gB,GAAI4iB,sBAClC7V,EAASjP,EAAQiP,OACjB8V,IAGCvC,GAAMlP,KACPtT,EAAQglB,cAAgB1R,EAAI2R,iBAAiB,SAAUjlB,EAAQglB,cAG3DhlB,EAAQklB,qCAKHllB,EAAQ0P,KAAK8I,UAAc4J,MAAoBC,EAAyB9S,KACzE+D,EAAI2R,iBAAiB,mBAAoB,kBACzC3R,EAAI2R,iBAAiB,gBAAiB,eAI1CjlB,EAAQwkB,aAA2B,SAAXvV,GAAgC,QAAXA,GAC7CqE,EAAI2R,iBAAiB,eAAgBjlB,EAAQwkB,aAGjDz8B,GAAG6B,OAAOm7B,EAAYh9B,GAAG6G,WAAW2gB,GAAiBA,EAAcrN,GAAMqN,GACzExnB,GAAG6B,OAAOm7B,EAAYF,GAEtB98B,GAAG+C,KAAKi6B,EAAY,SAASj7B,EAAMkB,GAC/BsoB,EAAI2R,iBAAiBn7B,EAAMkB,MAKvC,QAASo4B,GAAqB+B,GAC1B,MAAOp9B,IAAG2F,QAAQsS,EAAQolB,wBAAwBplB,EAAQiP,QAASkW,IAAiB,EAGxF,QAASE,GAAcnjB,EAAIuhB,EAAQiB,EAAWnB,EAAkBO,EAAuBgB,EAAmBnB,GAYtG,GAXAb,EAAY5gB,IACRwiB,UAAWA,EACXnB,iBAAkBA,EAClBO,sBAAuBA,EACvBgB,kBAAmBA,EACnBnB,QAASA,GAGHV,EAAMh4B,KAAKiX,IAGVlC,EAAQmP,eACf,MAAO+T,GAAYhhB,EAAIuhB,GA7U/B,GAAIv1B,GAAKq2B,EACLtB,KACAH,KACA9iB,GACIglB,aAAc,KACdM,cAAe,QAAS,OAAQ,OAChCrW,OAAQ,OACRuV,YAAa,oCACbrV,eAAgB,EAChBI,iBACAE,iBACAD,eACAgU,kBACA0B,oCAAoC,EACpCE,yBACIG,QAAS,IAAK,IAAK,KACnBC,OAAQ,IAAK,IAAK,IAAK,IAAK,KAC5BC,MAAO,IAAK,IAAK,IAAK,IAAK,KAC3BC,KAAM,IAAK,IAAK,IAAK,IAAK,KAC1BC,KAAM,MAEVjW,MACI8I,UAAU,EACV4I,iBAAiB,GAErBlzB,IAAK,SAAS4B,EAAK1B,KACnBw1B,OAAQ,SAAS1hB,KACjBmR,WAAY,SAASnR,EAAI4N,EAAUC,KACnCkD,WAAY,KAMpB,IAHAlrB,GAAG6B,OAAOoW,EAASJ,GACnB1R,EAAM8R,EAAQ9R,IAEVnG,GAAG2F,QAAQsS,EAAQslB,aAActlB,EAAQiP,QAAU,EACnD,KAAM,IAAI1lB,OAAM,IAAMyW,EAAQiP,OAAS,wDA8S3CsV,GAAiD,QAAnBvkB,EAAQiP,QAAuC,WAAnBjP,EAAQiP,OAElElnB,GAAG6B,OAAOxB,MAENw9B,cAAe,SAAS1jB,GACpB,GAAI2jB,GAAM5f,EAAQ0G,EAASgX,EAASmC,EAAahC,CAEjD,QAEIiC,SAAU,SAASC,GAEf,MADAH,GAAOG,EACA59B,MAOX69B,WAAY,SAAS1C,GAEjB,MADAtd,GAASsd,EACFn7B,MAGX89B,gBAAiB,SAASC,GAEtB,MADArC,GAAwBqC,EACjB/9B,MAIXg+B,YAAa,SAAStB,GAElB,MADAnY,GAAUmY,EACH18B,MAIXi+B,YAAa,SAASC,GAElB,MADA3C,GAAU2C,EACHl+B,MAIXm+B,gBAAiB,WAEb,MADAT,IAAc,EACP19B,MAIXk8B,KAAM,SAASb,GAKX,MAJIqC,IAAe/9B,GAAG2F,SAAS,MAAO,UAAWsS,EAAQiP,SAAW,IAChEhJ,EAAOugB,aAAc,GAAIC,OAAOC,WAG7BrB,EAAcnjB,EAAIuhB,EAAQoC,EAAM5f,EAAQ6d,EAAuBnX,EAASgX,MAK3FgD,SAAU,SAASzkB,GACf6gB,EAAQ7gB,OC1YpBna,GAAG6+B,cAAgB,SAASzjB,GACxB,YAEA,IAAI0jB,GAAQ1jB,EAAK0jB,MACbC,KACAtT,EAAWqT,EAAMrT,SACjBxL,EAAU6e,EAAM7e,OAEpBjgB,IAAG6B,OAAOxB,MACNmQ,IAAK,SAAS2J,EAAI6kB,GACdD,EAAU5kB,GAAM6kB,EAChBD,EAAU5kB,GAAI/J,SAGlB0P,OAAQ,SAAS3F,GACb,GAAIhC,GAAO9X,KACPqrB,EAA2B,GAAI1rB,IAAG4L,OACjB6f,GAAStR,EAAI8F,EAAQ9F,GAAKuR,GAEhC5U,KAAK,WACZqB,EAAK2I,QAAQ3G,KACb4kB,EAAU5kB,GAAIykB,UAAW,EACzBzmB,EAAKoL,QAAQpJ,IAEjBuR,EAAyB5f,aAIjCyX,QAAS,SAASpJ,SACP4kB,GAAU5kB,IAGrB8kB,oBAAqB,SAAS9kB,GAC1B,MAAO4kB,GAAU5kB,GAAI1K,KAGzBqR,QAAS,SAAS3G,GACd,MAAyBhW,UAAlB46B,EAAU5kB,IAGrBN,MAAO,WACHklB,MAGJG,cAAe,SAAS/kB,GACpB,MAAO4kB,GAAU5kB,IAGrBglB,qBAAsB,SAAShlB,EAAIilB,GAC/BL,EAAU5kB,GAAI1K,IAAM2vB,GAGxBC,aAAc,SAASllB,GACnB,QAAS4kB,EAAU5kB,GAAIykB,aCpDnC5+B,GAAGqtB,wBAA0B,SAASxV,EAAGiT,GACrC,YAEA,IAGcwU,GAAsBn5B,EAAKmpB,EAHrCiQ,EAAal/B,KACbm/B,GAAmB,EACnBC,GAA6B,EAGjCxnB,GACIwP,eACAL,eAAgB,EAChB/R,UACImL,SAAS,EACT3W,UACI2W,SAAS,IAGjBra,IAAK,SAAS4B,EAAK1B,KACnB6kB,WAAY,SAAS/Q,EAAIlI,EAAUkZ,EAAQC,KAC3CE,WAAY,SAASnR,EAAIlI,EAAUkgB,EAAU5G,KAC7CE,SAAU,SAAStR,EAAIlI,KACvB2Z,aAAc,SAASzR,KACvB2R,SAAU,SAAS3R,EAAIlI,KACvBga,cAAe,SAAS9R,EAAIlI,EAAUia,KACtCI,qBAAsB,SAASnS,EAAI+R,EAAWiG,EAAU5G,KACxDmB,YAAa,SAASvS,EAAIlI,EAAUkgB,EAAU5G,KAC9CiB,SAAU,SAASrS,EAAIlI,EAAUia,EAAWO,KAC5CI,cAAe,SAAS1S,EAAIoC,KAC5B0D,QAAS,SAAS9F,KAClB2S,QAAS,SAAS3S,EAAIyC,KACtBqQ,SAAU,SAAS9S,KACnB6C,mBAAoB,SAAS7C,KAC7B8C,cAAe,SAAS9C,KACxB+S,aAAc,SAAS/S,MAG3BulB,GAEInoB,KAAM,SAAS4C,EAAIwlB,EAAUxN,EAAU5G,GACnC,GAAIW,GAAYoD,EAAQsQ,cAAczlB,EAAIwlB,EAE1CrQ,GAAQ4P,cAAc/kB,GAAI0lB,kBAAmB,QAEtCvQ,GAAQ4P,cAAc/kB,GAAI/J,KAAK0vB,cAAcH,GACpDrQ,EAAQ4P,cAAc/kB,GAAIgR,QAAUe,EAAU3Q,KAE9CtD,EAAQqU,qBAAqBnS,EAAImV,EAAQyQ,yBAAyB7T,GAAYiG,EAAU5G,IAK5FyU,SAAU,SAAS7lB,GACf,GAAIoB,GAAOtD,EAAQ0K,QAAQxI,GACvBpY,EAAOkW,EAAQgI,QAAQ9F,EAE3BhU,GAAI,qCAAuCgU,EAAK,qBAChDmV,EAAQ2Q,eAAe9lB,GAAIrD,KACvB,SAASqb,EAAU5G,GACfplB,EAAI,2BAA6BgU,EAEjC,IAAI+lB,GAAoBl2B,EAAOm2B,kBAAkBhO,GAAU,EAE3Dla,GAAQiT,WAAW/Q,EAAIpY,EAAMwZ,EAAMA,GACnC+T,EAAQ8Q,+BAA+BjmB,GACvCnQ,EAAOq2B,QAAQlmB,EAAI+lB,EAAmB3U,IAE1C,SAAS4G,EAAU5G,GACf,GAAI+U,GAAqBt2B,EAAOm2B,kBAAkBhO,GAAU,EAE5DhsB,GAAI,yCAA2CgU,EAAK,MAAQmmB,EAAmBn2B,MAAO,UAGlFm2B,EAAmBzmB,OAClB0R,GAAOtT,EAAQ5C,SAASvJ,QAAQktB,cAAcrzB,QAAQ4lB,EAAI9Q,SAAW,IAEtEilB,EAAQ7lB,MAAMM,GAGblC,EAAQyU,YAAYvS,EAAIpY,EAAMu+B,EAAoB/U,IACnDvhB,EAAOq2B,QAAQlmB,EAAImmB,EAAoB/U,MAMvDgV,cAAe,SAASZ,EAAUxlB,EAAIgY,EAAU5G,GAC5C,GAAIxpB,GAAOkW,EAAQgI,QAAQ9F,EAE3BhU,GAAI,qCAAuCgU,EAAK,WAAawlB,GAE7DrQ,EAAQkR,iBAAiBrmB,EAAIwlB,EAE7B,IACIc,GADAC,EAAmB12B,EAAOm2B,kBAAkBhO,GAAU,EAG1D,IAAIuO,EAAiB7mB,MACjB6lB,EAAQ7lB,MAAMM,OAEb,CACD,GAAIwmB,GAAwBrR,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,UAE/DH,GAAgBE,EAAwB3gC,GAAG2F,QAAQg7B,EAAuBhB,IAAY,EAClFc,GAAiB,IACjBnR,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,WAAWvkB,OAAOokB,EAAe,GACpEnR,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAUC,QAAQnB,IAMxDrQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,gBAG5BtB,IACAnQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,eAAgB,EAE/C56B,EAAInG,GAAG8H,OAAO,mFAAoFyJ,KAAKmrB,UAAUj2B,OAAOu6B,KAAK1R,EAAQ2R,SAAS9mB,KAAO5I,KAAKmrB,UAAUpN,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,cACvM5gC,GAAG+C,KAAKusB,EAAQ2R,SAAS9mB,GAAK,SAAS+mB,EAAMC,GACzCh7B,EAAInG,GAAG8H,OAAO,sDAAuDqS,EAAI+mB,EAAMC,EAAMvE,aACrFuE,EAAMC,QAGND,EAAME,YAAa,IAIvB/R,EAAQgS,0BAA0BnnB,GAIlConB,EAAkBC,KAAKrnB,GAAI,IAG1BlC,EAAQyU,YAAYvS,EAAIpY,EAAM2+B,EAAkBnV,IAIjDvhB,EAAOq2B,QAAQlmB,EAAIumB,EAAkBnV,KAKjDkW,aAAc,SAAStnB,GACnB,QAASmV,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAU96B,QAG1D27B,SAAU,SAASvnB,GACf,GAAIwnB,GAAUrS,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAUvuB,OAM3D,OAJIqvB,IAAWrS,EAAQsS,gBAAgBznB,KACnCwnB,EAAU,MAGPA,GAGX9nB,MAAO,SAASM,GACZhU,EAAI,8FAAgGgU,EAAI,SAExGmV,EAAQ8Q,+BAA+BjmB,GACvCmV,EAAQuS,mBAAmB1nB,GAC3BmV,EAAQ4P,cAAc/kB,GAAIgR,OAAS,EACnCmE,EAAQ4P,cAAc/kB,GAAI0lB,kBAAmB,GAGjDiC,SAAU,SAAS3nB,GACf,GAAIoB,GAAOtD,EAAQ0K,QAAQxI,GACvBpY,EAAOkW,EAAQgI,QAAQ9F,GACvBwlB,EAAWD,EAAQgC,SAASvnB,GAC5B+R,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCZ,EAAYzP,EAAQ4P,cAAc/kB,GAClC+e,EAAW6F,EAAUc,iBACrBkC,EAAmBhD,EAAU1pB,SAASurB,cAe1C,IAbwB,MAApB7B,EAAU5T,SACV4T,EAAU5T,OAAS,GAInB+N,GAAYjhB,EAAQuU,SAASrS,EAAIpY,EAAMmqB,EAAW6S,EAAUtS,qBAAsB,IAClFiT,EAAQ7lB,MAAMM,GACdwlB,EAAWD,EAAQgC,SAASvnB,GAC5B+R,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCzG,GAAW,GAIC,MAAZyG,GAAgD,IAA5BoC,EAAiBh8B,OACrC25B,EAAQM,SAAS7lB,OAIhB,CACD4nB,EAAiB7+B,KAAKy8B,GACtBrQ,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,WAAamB,EAE5CtC,GACA8B,EAAkBlF,KAAKliB,EAAIwlB,GAG3BF,GAA8B8B,EAAkBS,aAAe1S,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAU96B,QAC5G25B,EAAQoC,SAAS3nB,GAGO,IAAxB+R,EAAU5gB,KAAKiQ,OACfpV,EAAInG,GAAG8H,OAAO,+DAAgE63B,EAAUxlB,GAAK,SAC7FulB,EAAQa,cAAcZ,EAAUxlB,EAAI,8BAA+B,MAG5ClC,GAAQgU,cAAc9R,EAAIpY,EAAMutB,EAAQyQ,yBAAyB7T,IAEvEpV,KACjB,SAASmrB,GACL,GAAKhqB,EAAQiV,aAAa/S,GAGrB,CACDhU,EAAInG,GAAG8H,OAAO,oEAAqEqS,EAAIwlB,EAAUzT,EAAUphB,MAAQ,EAAGohB,EAAUnhB,IAAKwQ,GAErI,IAAI2mB,IACAvC,SAAUA,EACVxlB,GAAIA,EACJgoB,UAAWF,EACX/I,SAAUA,EAGd5J,GAAQ8S,YAAYF,GAAiBprB,KAEjC,SAAiBqb,EAAU5G,GACvBplB,EAAI,wCAA0CgU,EAAK,WAAawlB,GAEhErQ,EAAQkR,iBAAiBrmB,EAAIwlB,EAE7B,IAAIoC,GAAmBzS,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,eACtDF,EAAmB12B,EAAOm2B,kBAAkBhO,GAAU,GACtDkQ,EAAqBriC,GAAG2F,QAAQo8B,EAAkBpC,EAEtDx5B,GAAInG,GAAG8H,OAAO,8CAA+C63B,EAAUxlB,IAEvEulB,EAAQnoB,KAAK4C,EAAIwlB,EAAUe,EAAkBnV,GAEzC8W,GAAsB,GACtBN,EAAiB1lB,OAAOgmB,EAAoB,GAGhD/S,EAAQgT,0BAA0BnoB,GAE7BulB,EAAQ+B,aAAatnB,IAAmC,IAA5B4nB,EAAiBh8B,OAGzC25B,EAAQ+B,aAAatnB,GAC1BulB,EAAQoC,SAAS3nB,GAGjBhU,EAAInG,GAAG8H,OAAO,oGAAqGqS,EAAI5I,KAAKmrB,UAAUqF,KANtIrC,EAAQM,SAAS7lB,IAWzB,SAAiBgY,EAAU5G,GACvBmU,EAAQa,cAAcZ,EAAUxlB,EAAIgY,EAAU5G,KAGjDhU,KAAK,WACF+X,EAAQiT,SAASpoB,EAAIwlB,SAlD7Bx5B,GAAInG,GAAG8H,OAAO,6EAA8EqS,EAAIwlB,KAuDxG,SAASx1B,GACLu1B,EAAQa,cAAcZ,EAAUxlB,EAAIhQ,EAAO,WAO/Do3B,GACIiB,SACAC,eACAC,YAEAV,UAAW,WACP,GAAIvU,GAAMxV,EAAQmP,eACdub,EAAwB,EACxBC,EAAkB,CAOtB,OALA5iC,IAAG+C,KAAKw+B,EAAkBkB,YAAa,SAASzhB,EAAQ6hB,GACpDF,IACAC,GAAmBC,EAAiB98B,SAGjC0nB,GAAO8T,EAAkBiB,MAAMz8B,OAAS48B,EAAwBC,IAM3EpB,KAAM,SAASrnB,EAAI2oB,GACf,GAGI7H,GAHA8H,GAAaD,EACbE,EAAehjC,GAAG2F,QAAQ47B,EAAkBmB,SAAUvoB,GACtD8oB,EAAmBjjC,GAAG2F,QAAQ47B,EAAkBiB,MAAOroB,SAGpDonB,GAAkBkB,YAAYtoB,GAEjCnQ,EAAOk5B,eAAe/oB,YAAena,IAAGwX,YACxCrR,EAAI,uCAAyCgU,EAAK,qCAC3CmV,GAAQ4P,cAAc/kB,GAAIqB,MAIjCwnB,GAAgB,EAChBzB,EAAkBmB,SAASrmB,OAAO2mB,EAAc,GAG3CD,GAAaE,GAAoB,IACtC1B,EAAkBiB,MAAMnmB,OAAO4mB,EAAkB,GAEjDhI,EAASsG,EAAkBmB,SAASpwB,QAChC2oB,GAAU,IACVsG,EAAkBiB,MAAMt/B,KAAK+3B,GAC7BjxB,EAAOc,MAAMmwB,MAKzBkI,sBAAuB,WACnB,GAAIC,KAqBJ,OAjBApjC,IAAG+C,KAAKw+B,EAAkBkB,YAAa,SAASzhB,EAAQqiB,GAChDA,GAAUA,EAAOt9B,QACjBq9B,EAAmBlgC,KAAKogC,SAAStiB,MAMzChhB,GAAG+C,KAAKw+B,EAAkBiB,MAAO,SAASx/B,EAAKge,GACtCugB,EAAkBkB,YAAYzhB,IAC/BoiB,EAAmBlgC,KAAKogC,SAAStiB,MAKzCoiB,EAAqBA,EAAmBpzB,OAAOuxB,EAAkBmB,WAKrEa,kBAAmB,SAASppB,GACxB,MAAOna,IAAG2F,QAAQ47B,EAAkBiB,MAAOroB,IAAO,GAGtDkiB,KAAM,SAASliB,EAAIwlB,GAKf,MAJgB,OAAZA,GACA4B,EAAkBmB,SAASx/B,KAAKiX,KAGhConB,EAAkBS,cACF,MAAZrC,GACA4B,EAAkBmB,SAASc,MAC3BjC,EAAkBiB,MAAMt/B,KAAKiX,IAG5B,WACG,GAAIspB,GAAkBlC,EAAkBkB,YAAYtoB,MACpDspB,GAAgBvgC,KAAKy8B,GACrB4B,EAAkBkB,YAAYtoB,GAAMspB,MAIrC,IAMf5pB,MAAO,WACH0nB,EAAkBmB,YAClBnB,EAAkBiB,WAI1BkB,GACInH,KAAM,SAASpiB,EAAIpY,GACf,GAAIg9B,GAAYzP,EAAQ4P,cAAc/kB,EAEtC,KAAK4kB,EAED,WADA54B,GAAI,yEAA2EgU,EAAI,OAIvF4kB,GAAU5T,OAAS,EAEnBhlB,EAAI,qCAAuCgU,GAC3CmV,EAAQqU,WAAWxpB,GAAIrD,KACnB,SAASqb,EAAUuJ,GACfv1B,EAAI,uCAAyCgU,EAE7C,IAAIumB,GAAmB12B,EAAOm2B,kBAAkBhO,GAAU,GACtD5W,EAAOtD,EAAQ0K,QAAQxI;+CAE3BlC,GAAQiT,WAAW/Q,EAAIpY,EAAMwZ,EAAMA,GACnCvR,EAAO45B,aAAazpB,EAAIumB,GACxB12B,EAAOq2B,QAAQlmB,EAAIumB,EAAkBhF,IAGzC,SAASvJ,EAAUuJ,GACfv1B,EAAI,oCAAsCgU,EAE1C,IAAIumB,GAAmB12B,EAAOm2B,kBAAkBhO,GAAU,EAErDla,GAAQyU,YAAYvS,EAAIpY,EAAM2+B,EAAkBhF,IACjD1xB,EAAOq2B,QAAQlmB,EAAIumB,EAAkBhF,OAOzD1xB,GACI8V,OAAQ,SAAS3F,GACbhU,EAAI,cAAgBgU,GACpBlC,EAAQwP,YAAYrmB,OAAO+Y,GAC3BonB,EAAkBC,KAAKrnB,IAG3BkmB,QAAS,SAASlmB,EAAIgY,EAAUuJ,GAC5B,GAAI35B,GAAOkW,EAAQgI,QAAQ9F,EAE3BlC,GAAQqT,WAAWnR,EAAIpY,EAAMowB,EAAUuJ,GAEnCpM,EAAQ4P,cAAc/kB,IACtBmV,EAAQuU,YAAcvU,EAAQuU,WAAW1pB,GAG7ConB,EAAkBC,KAAKrnB,IAK3B+oB,eAAgB,SAAS/oB,GACrB,MAAQmV,GAAQwU,UAAYxU,EAAQwU,SAAS3pB,IACxCmV,EAAQ5N,SAAW4N,EAAQ5N,QAAQvH,IAG5C4pB,YAAa,WAITzU,EAAU,IAHQxE,EAAY9qB,GAAG8qB,GAAa9qB,GAAGgkC,cACtBhkC,GAAG8S,kBAAkBoC,cAAgB,MAAQ,QAEvB,iBAC7C+C,GAEIkV,oBAAqBlV,EAAQkV,oBAC7BH,cAAe/U,EAAQ+U,cACvB/M,QAAShI,EAAQgI,QACjB0C,QAAS1K,EAAQ0K,QACjBO,QAASjL,EAAQiL,QACjB/c,IAAKA,EACLslB,SAAUxT,EAAQwT,SAClBP,WAAYjT,EAAQiT,WACpB2B,cAAe5U,EAAQ4U,cACvBoX,aAAc,SAAS9pB,GACnBlC,EAAQgE,UAAU9B,EAAIna,GAAGya,OAAO+C,sBAKxC8R,EAAQ4U,+BACR5U,EAAQ4U,iCAIhBC,4BAA6B,SAAShqB,GAClC,MAAOlC,GAAQgV,SAAS9S,IAM5BiqB,WAAY,SAASjqB,EAAI7O,GAIrB,MAAIA,KAASgkB,EAAQ5N,QAAQvH,IAAO7O,YAAgBtL,IAAGwX,WAKnDS,EAAQ2T,aAAazR,GAErBhU,EAAI,+CAAiDgU,GACrD7O,EAAKqM,SAASb,KAAK,SAASutB,GACxBl+B,EAAI,mCAAqCgU,GAGzCmV,EAAQgV,WAAWnqB,EAAIkqB,GAGvBpsB,EAAQ6U,QAAQ3S,EAAIkqB,EAAc9oB,MAGlC+T,EAAQuS,mBAAmB1nB,GAE3BnQ,EAAOu6B,uBAAuBpqB,IAIlC,SAAS6L,GACL,GAAIwe,KAEAxe,KACAwe,EAAcr6B,MAAQ6b,GAG1B7f,EAAInG,GAAG8H,OAAO,yDAA0DqS,EAAI6L,GAAe,SAE3F/N,EAAQqT,WAAWnR,EAAIlC,EAAQgI,QAAQ9F,GAAKna,GAAG6B,OAAO2iC,EAAelF,GAAuB,MAC5Ft1B,EAAOu6B,uBAAuBpqB,GAC9BonB,EAAkBC,KAAKrnB,MAOxB,GAHInQ,EAAOu6B,uBAAuBpqB,IAO7CoqB,uBAAwB,SAASpqB,GAC7B,GAAIsqB,GAAaxsB,EAAQ+E,mBAAmB7C,GACxCuqB,GAAiB,CAoBrB,OAlBID,IAAcA,EAAW1+B,QACzBI,EAAI,0CAA4CgU,GAEhDna,GAAG+C,KAAK0hC,EAAY,SAASzhC,EAAK2hC,GAC9B,GAAI36B,EAAOm6B,4BAA4BQ,IAAgBrV,EAAQ5N,QAAQijB,GACnED,EAAiBC,IAAcxqB,EAC/BnQ,EAAO46B,IAAID,OAEV,IAAI36B,EAAOm6B,4BAA4BQ,GACxC,OAAO,MAKfD,GAAiB,EACjB16B,EAAO46B,IAAIzqB,IAGRuqB,GAGXd,aAAc,SAASzpB,EAAIgY,GACEhuB,SAArBguB,EAAS5V,SACTtE,EAAQ4U,cAAc1S,EAAIgY,EAAS5V,UAO3C4jB,kBAAmB,SAAS0E,EAAkBhS,GAC1C,GAAIV,GAAW0S,CAcf,OAVK7kC,IAAGuG,SAASs+B,KACb1S,KAEInyB,GAAGwH,SAASq9B,KAAsBhS,IAClCV,EAAShoB,MAAQ06B,IAIzB1S,EAASrmB,QAAU+mB,EAEZV,GAGXyS,IAAK,SAASzqB,GACV,GAAIpY,GAAOkW,EAAQgI,QAAQ9F,EAE3B,KAAKolB,EAAWze,QAAQ3G,GACpB,KAAM,IAAIna,IAAGwB,MAAM2Y,EAAK,qCAG5BlC,GAAQ6T,SAAS3R,EAAIpY,GAAM+U,KACvB,SAASqb,GACDA,GAAYA,EAASlc,OACrBgC,EAAQgE,UAAU9B,EAAIna,GAAGya,OAAO6C,QAChCgS,EAAQrZ,MAAMkE,GACdonB,EAAkBC,KAAKrnB,IAGnBqlB,GAAoBlQ,EAAQwV,qBAAqB3qB,GACjDulB,EAAQoC,SAAS3nB,GAGjBupB,EAAOnH,KAAKpiB,EAAIpY,IAK5B,SAASoI,GAKL,GAJAA,EAAQA,MAERhE,EAAIgU,EAAK,qEAAuEhQ,EAAO,UAElF8N,EAAQyU,YAAYvS,EAAIpY,EAAMoI,EAAMwiB,kBAAqB,CAC1D,GAAIwF,GAAWnoB,EAAOm2B,kBAAkBh2B,EAAMwiB,cAAc,EAC5D3iB,GAAOq2B,QAAQlmB,EAAIgY,OAMnCrnB,MAAO,SAASqP,GACZ,GAAI4qB,GAAe/6B,EAAOk5B,eAAe/oB,EAEzC,OAAI4qB,GACO/6B,EAAOo6B,WAAWjqB,EAAI4qB,IAG7B/6B,EAAO46B,IAAIzqB,IACJ,IAKnBna,IAAG6B,OAAOxB,MAINmQ,IAAK,SAAS2J,EAAIqB,GACd8T,EAAQ9e,IAAIP,MAAM5P,KAAM8H,YAM5B6B,OAAQ,SAASmQ,GACb,QAAIonB,EAAkBlF,KAAKliB,IAChBnQ,EAAOc,MAAMqP,IAK5BmK,MAAO,SAASnK,GAWZ,MANIslB,KACAnQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,eAAgB,GAK/CQ,EAAkBgC,kBAAkBppB,GAC7BnQ,EAAOc,MAAMqP,GAObolB,EAAWv1B,OAAOmQ,IAOjC2F,OAAQ,SAAS3F,GACb,GAAI6qB,GAAe1V,EAAQxP,OAAO3F,EAE9Bna,IAAG4W,iBAAiBouB,GACpBA,EAAaluB,KAAK,WACd9M,EAAO8V,OAAO3F,KAGb6qB,KAAiB,GACtBh7B,EAAO8V,OAAO3F,IAOtBgG,UAAW,WACP,GACIzP,GADA0yB,EAAqB7B,EAAkB4B,uBAK3C,IAAIC,EAAmBr9B,OACnB,IAAK2K,EAAI0yB,EAAmBr9B,OAAS,EAAG2K,GAAK,EAAGA,IAC5C6uB,EAAWzf,OAAOsjB,EAAmB1yB,GAI7C6wB,GAAkB1nB,SAKtB6H,QAAS,SAASvH,GACd,MAAImV,GAAQwU,UAAYxU,EAAQwU,SAAS3pB,GAC9BmV,EAAQwU,SAAS3pB,GAAI1C,cAGzB6X,EAAQ5N,SAAW4N,EAAQ5N,QAAQvH,IAI9C8qB,UAAW,SAAS9qB,GAChB,SAAUmV,EAAQwU,WAAYxU,EAAQwU,SAAS3pB,KAGnDZ,SAAU,SAASY,GACf,GAAImV,EAAQ/V,SACR,MAAO+V,GAAQ/V,SAASY,IAIhCN,MAAO,WACH1T,EAAI,4BACJo5B,EAAWpf,YACXohB,EAAkB1nB,QAClByV,EAAQzV,SAGZ0J,QAAS,SAASpJ,GACd,GAAIolB,EAAWze,QAAQ3G,GACnB,MAAOmV,GAAQ/L,QAAQpJ,IAO/B2G,QAAS,SAAS3G,GACd,MAAOmV,GAAQxO,QAAQ3G,IAG3BiJ,gBAAiB,SAASjJ,GACtB,GAAI1K,GAAM6f,EAAQxO,QAAQ3G,IACtBmV,EAAQ4V,oBACR5V,EAAQ4V,mBAAmB/qB,EAE/B,SAAI1K,KACSqE,aAAapE,QAAQD,IAMtCiT,sBAAuB,WACnB,MAAI4M,GAAQ5M,sBACD4M,EAAQ5M,4BAavBuc,oBAAqB,SAAS9kB,GAC1B,GAAIolB,EAAWze,QAAQ3G,GACnB,MAAOmV,GAAQ2P,oBAAoB9kB,IAS3ClE,MAAO,SAASkE,GACZ,SAAIolB,EAAWpc,YAAYhJ,IAAOmV,EAAQrZ,OAASspB,EAAWze,QAAQ3G,IAAOmV,EAAQrZ,MAAMkE,MACvFonB,EAAkBC,KAAKrnB,GACvBmV,EAAQgS,0BAA0BnnB,IAC3B,IAKfgrB,mBAAoB,SAAShrB,GACzB,QAASmV,EAAQ6V,oBAAsB7V,EAAQ6V,mBAAmBhrB,IAItEgJ,YAAa,SAAShJ,GAClB,QAASmV,EAAQnM,aAAemM,EAAQnM,YAAYhJ,MAI5Dna,GAAG6B,OAAOoW,EAASJ,GACnB1R,EAAM8R,EAAQ9R,IACdq5B,EAAmBvnB,EAAQ5C,SAASmL,SAAWxgB,GAAG8S,kBAAkBuC,SACpEoqB,EAA6BD,GAAoBvnB,EAAQ5C,SAASkjB,WAAW/X,QAE7E8e,EAAwB,WACpB,GAAInN,KAIJ,OAFAA,GAASla,EAAQ+S,oBAAqB,EAE/BmH,KAGXnoB,EAAO+5B,eC1zBX/jC,GAAGolC,qBAAuB,SAASvtB,GAC/B,YAEA,IAAII,IACI9R,IAAK,SAASC,EAASC,MAE3Bg/B,IAEJrlC,IAAG6B,OAAOoW,EAASJ,GAEnB7X,GAAG6B,OAAOxB,MACNilC,eAAgB,SAASnrB,EAAI9K,GACzB,GAAIk2B,GAA2B,SAASrQ,GAChC7lB,EAAS6lB,EAAMlwB,MAGnBE,QAAO+P,YACPowB,EAAyBlrB,GAAMna,GAAGkF,QAAQ5E,OAAO,UAAWilC,GAG5Dp/B,IAAI,wDAAyD,UAIrEq/B,sBAAuB,SAASrrB,GAC5B,GAAIjV,OAAO+P,YAAa,CACpB,GAAIwwB,GAAWJ,EAAyBlrB,EACpCsrB,IACAA,SCvBpBzlC,GAAG0lC,kBAAoB,SAAStqB,GAC5B,YAoBA,SAASuqB,GAAYxrB,SACVyrB,GAAiBzrB,GAKpB0rB,IACAvS,aAAawS,EAA0B3rB,UAChC2rB,GAA0B3rB,GACjC4rB,EAAoBP,sBAAsBrrB,GAG9C,IAAI6rB,GAASr8B,SAASs8B,eAAe3W,EAAQ4W,eAAe/rB,GACxD6rB,KAIAA,EAAO70B,aAAa,MAAO,qBAE3BnR,GAAGgmC,GAAQ5kC,UAQnB,QAAS+kC,GAAuBC,GAC5B,MAAOA,GAAW1gC,MAAM,KAAK,GAUjC,QAAS2gC,GAAoBtkC,GACzB,GAAIikC,GAAShmC,GAAGgP,UAAU,yCAA2CjN,EAAO,OAO5E,OALAikC,GAAO70B,aAAa,KAAMpP,GAE1BikC,EAAO7lC,MAAMC,QAAU,OACvBuJ,SAAS28B,KAAKl1B,YAAY40B,GAEnBA,EAUX,QAASO,GAA4BP,EAAQ32B,GACzC,GAAI+2B,GAAaJ,EAAO7rB,GACpB6G,EAASmlB,EAAuBC,EAGpCI,GAFWtjB,EAAQlC,IAEK3R,EAIxBu2B,EAAiB5kB,GAAUhhB,GAAGgmC,GAAQ1lC,OAAO,OAAQ,WAC7CgvB,EAAQ/V,SAASyH,KACjB7a,EAAI,mEAAqEigC,EAAa,KAEtFN,EAA0BM,GAAczc,WAAW,WAC/C,GAAI3D,GAAe,gEAAkEogB,CACrFjgC,GAAI6f,EAAc,SAClB3W,GACIlF,MAAO6b,KAEZ,QAMX+f,EAAoBT,eAAec,EAAY,SAAShgC,GACpDD,EAAI,2CAA6CC,EAAU,IAC3D,IAGIqgC,GAFAtU,GADSgU,EAAuBC,GACrB9W,EAAQoX,mBAAmBtgC,IACtCkU,EAAO6X,EAAS7X,IAGhBA,IAAQksB,EAAgBlsB,IACxBnU,EAAI,qCAAuCigC,GAC3C9S,aAAawS,EAA0BM,UAChCN,GAA0BM,GAEjC9W,EAAQqX,iBAAiBP,GAEzBK,EAAiBD,EAAgBlsB,SAE1BksB,GAAgBlsB,GACvByrB,EAAoBP,sBAAsBY,GAC1CK,EAAetU,IAET7X,GACNnU,EAAI,IAAMC,EAAU,2CAxHhC,GAAI6R,GAAUmD,EAAKnD,QACfqX,EAAUjvB,KACVy+B,EAAQ1jB,EAAK0jB,MACb8H,EAAwB5mC,GAAGiN,cAC3Bu5B,KACAZ,KACAE,KACAD,EAAS5tB,EAAQ4tB,OACjBrb,EAAYvS,EAAQuS,UACpBtH,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,IACZ4/B,EAAsB,GAAI/lC,IAAGolC,sBAAsBj/B,IAAKA,GAkH5DnG,IAAG6B,OAAOxB,KAAM,GAAIL,IAAG6+B,cAAczjB,IAErCpb,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OAIIgE,IAAK,SAAS2J,EAAIkU,GACd7hB,EAAOgE,IAAI2J,GAAKzQ,MAAO2kB,IAEvBA,EAAUld,aAAa,OAAQqZ,GAG3B6D,EAAUltB,YACVnB,GAAGquB,GAAWjtB,UAItBmiB,QAAS,SAASpJ,GACdwrB,EAAYxrB,GACZ3N,EAAO+W,QAAQpJ,IAGnB2G,QAAS,SAAS3G,GACd,MAAO3N,GAAOsU,QAAQ3G,IACkBhW,SAApCmrB,EAAQ4P,cAAc/kB,GAAIzQ,UAK1C1J,GAAG6B,OAAOxB,MACNkZ,SAAU,SAASY,GACf,MAAOmV,GAAQ4P,cAAc/kB,GAAIzQ,OAWrCm9B,iBAAkB,SAASb,EAAQ32B,GAE/B,GAAIy3B,EAEAjB,GACAU,EAA4BP,EAAQ32B,GAGpCu2B,EAAiBI,EAAO7rB,IAAMna,GAAGgmC,GAAQ1lC,OAAO,OAAQ,WAMpD,GALA6F,EAAI,yBAA2B6/B,EAAO7rB,IAKjC6rB,EAAO7kC,WAAZ,CAIA,IAEI,GAAI6kC,EAAOe,iBACPf,EAAOe,gBAAgBT,MACkB,SAAzCN,EAAOe,gBAAgBT,KAAKn3B,UAK5B,OAGR,MAAOhF,GAEHhE,EAAI,8EAAgFgE,EAAM/D,QAAU,IAAK,SACzG0gC,GAAsBh7B,SAAS,GAGnCuD,EAASy3B,OAWrBE,cAAe,SAAS7sB,GAGpB,MAAOksB,GAFU/W,EAAQ4W,eAAe/rB,KAU5CwsB,iBAAkB,SAASxsB,GACMhW,SAAzByhC,EAAiBzrB,KACjByrB,EAAiBzrB,WACVyrB,GAAiBzrB,KAQhC+rB,eAAgB,SAASllB,GACrB,MAAOA,GAAS,IAAM4lB,GAY1BK,mBAAoB,SAAS7rB,GACzB,GAAI8L,GAAS9L,EAAK8L,OACd/I,EAAW/C,EAAK+C,SAChBD,EAAS9C,EAAK8C,OACdgZ,EAAe9b,EAAK8b,aACpBgQ,EAAa9rB,EAAK8rB,WAClBh2B,EAAOlR,GAAGgP,UAAU,iBAAmBkY,EAAS,2CAChDyU,EAAMxd,CAcV,OAZI+Y,GACAl3B,GAAGiR,WAAWiN,EAAQhN,GAGtByqB,EAAM37B,GAAGkQ,QAAQgO,EAAQC,GAG7BjN,EAAKC,aAAa,SAAUwqB,GAC5BzqB,EAAKC,aAAa,SAAU+1B,GAC5Bh2B,EAAK/Q,MAAMC,QAAU,OACrBuJ,SAAS28B,KAAKl1B,YAAYF,GAEnBA,GAOXw1B,mBAAoB,SAASS,GACzB,GAAIhV,KAEJ,KACIA,EAAWnyB,GAAGqR,UAAU81B,GAE5B,MAAOh9B,GACHhE,EAAI,0DAA4DgE,EAAM/D,QAAU,IAAK,SAGzF,MAAO+rB,OCnSnBnyB,GAAGonC,iBAAmB,SAAShsB,GAC3B,YAqCA,SAASgmB,GAAMjnB,GACXna,GAAG+C,KAAKusB,EAAQ2R,SAAS9mB,GAAK,SAASktB,EAAO9b,GAC1C,GAAI+b,GAAgBhY,EAAQiY,kBAAkBptB,EAAIktB,EAElD9b,GAAI2Q,mBAAqB,KACzB3Q,EAAIvhB,OAAO4wB,WAAa,KACxBrP,EAAI6V,QACJkG,GAAiBA,EAAc1I,UAAY0I,EAAc1I,SAASzkB,KA1C1E,GAAImV,GAAUjvB,KACVyqB,EAAY1P,EAAKnD,QAAQ6S,UACzBgU,EAAQ1jB,EAAK0jB,MACbzpB,EAAW+F,EAAKnD,QAAQ5C,SACxBmyB,EAAe,SAASrtB,GACpB,GAAI4kB,GAAYzP,EAAQ4P,cAAc/kB,EAEtC,IAAI4kB,EAAUpG,UACV,MAAOoG,GAAUpG,SAIjB,IAAIA,GAAYtjB,EAASyjB,QAOzB,OALI94B,IAAG6G,WAAW8xB,KACdA,EAAYA,EAAUxe,EAAIwI,EAAQxI,KAGtC4kB,EAAUpG,UAAYA,EACfA,GAGfxiB,EAASiF,EAAKnD,QAAQ9B,OACtBsxB,EAAapyB,GAAY+F,EAAKnD,QAAQ5C,SAASmL,SAAWxgB,GAAG8S,kBAAkBuC,SAC/EqyB,EAAgBvxB,GAAUiF,EAAKnD,QAAQ9B,OAAOqK,SAAWinB,GAAcznC,GAAG8S,kBAAkBqD,OAC5F8J,EAAU6e,EAAM7e,QAChB0C,EAAUmc,EAAMnc,QAChBO,EAAU4b,EAAM5b,QAChBhB,EAAc4c,EAAM5c,YACpB8K,EAAgB8R,EAAM9R,cACtBH,EAAgBiS,EAAMjS,cACtB3B,EAAa4T,EAAM5T,WACnB/kB,EAAM24B,EAAM34B,IACZgnB,EAAsB2R,EAAM3R,mBAahCntB,IAAG6B,OAAOxB,KAAM,GAAIL,IAAG6+B,cAAczjB,IAErCpb,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OAIIgE,IAAK,SAAS2J,EAAIwtB,GACd,GAAI3nC,GAAGuI,OAAOo/B,IAAgB3nC,GAAGuJ,OAAOo+B,GACpCn7B,EAAOgE,IAAI2J,GAAKqB,KAAMmsB,QAErB,CAAA,KAAIA,YAAuB3nC,IAAGwX,WAI/B,KAAM,IAAIhW,OAAM,2CAHhBgL,GAAOgE,IAAI2J,GAAK2kB,MAAO6I,IAM3BrY,EAAQsY,eAAeztB,GACvButB,GAAiBpY,EAAQuY,uBAAuB1tB,IAGpDoJ,QAAS,SAASpJ,GACdinB,EAAMjnB,GACNmV,EAAQ8Q,+BAA+BjmB,GACvCmV,EAAQuU,WAAW1pB,GACnB3N,EAAO+W,QAAQpJ,OAK3Bna,GAAG6B,OAAOxB,MAENmgC,iBAAkB,SAASrmB,EAAIwlB,GAC3B,GAAIZ,GAAYzP,EAAQ4P,cAAc/kB,EAElC4kB,UACOA,GAAU3uB,KAAK03B,aAAanI,IAI3C4C,SAAU,SAASpoB,EAAIwlB,GACnB,GAAIoI,GAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAEtC23B,GAAUC,YACHD,GAAUC,KAAKrI,GAEtBoI,EAAUE,sBACHF,GAAUE,eAAetI,IAMxCM,eAAgB,SAAS9lB,EAAI+tB,GACzB,GAAIC,GAAe7Y,EAAQsS,gBAAgBznB,GAAM,EAC7CoR,EAAM+D,EAAQ8Y,QAAQjuB,EAAIguB,EAE9B,OAAID,IACO,GAAIloC,IAAG4L,SAAUE,QAAQo8B,EAAe3c,GAAMA,IAGlD,GAAIvrB,IAAG4L,SAAUE,WAAYyf,IAGxC7J,QAAS,SAASvH,GACd,MAAOmV,GAAQxO,QAAQ3G,IAAOmV,EAAQ4P,cAAc/kB,GAAIqB,MAG5DsoB,SAAU,SAAS3pB,GACf,MAAOmV,GAAQxO,QAAQ3G,IAAOmV,EAAQ4P,cAAc/kB,GAAI2kB,OAO5Dpc,sBAAuB,WACnB,GAAI2lB,KAuBJ,OArBA/Y,GAAQgZ,sBAAsB,SAAS74B,EAAKsQ,GACxCuP,EAAQgS,0BAA0B,KAAMvhB,EAAW1K,SAASurB,WAAa7gB,EAAW1K,SAASwrB,UAE7F,IAAI77B,IACAjD,KAAMge,EAAWhe,KACjB8+B,UAAW9gB,EAAW1K,SAASwrB,UAC/BtlB,KAAMwE,EAAWxE,KACjBjB,KAAMyF,EAAWzF,KAGjByF,GAAWtQ,MACXzK,EAAKyK,IAAMsQ,EAAWtQ,KAGtBsQ,EAAW0M,mBACXznB,EAAKynB,iBAAmB1M,EAAW0M,kBAGvC4b,EAAmBnlC,KAAK8B,KAGrBqjC,GAGXlD,mBAAoB,SAAShrB,GACzB,MAAOmV,GAAQ4P,cAAc/kB,GAAI0lB,kBAGrC1c,YAAa,SAAShJ,GAClB,QAAS9E,GAAYia,EAAQxO,QAAQ3G,KAChCmV,EAAQ4P,cAAc/kB,GAAIouB,cAGnCjH,0BAA2B,SAASnnB,EAAIquB,EAAeC,GACnD,GAAI1J,GAAYzP,EAAQ4P,cAAc/kB,OAClCuuB,EAAiB3J,EAAU1pB,aAC3BurB,EAAa4H,GAAiBE,EAAc9H,WAC5CC,EAAY4H,GAAgBC,EAAc7H,SAE1CD,KACAz6B,EAAInG,GAAG8H,OAAO,yDAA0DyJ,KAAKmrB,UAAUkE,KACvFA,EAAW+H,UACX3oC,GAAG+C,KAAK69B,EAAY,SAAS59B,EAAK28B,GAC9BkB,EAAUC,QAAQnB,KAEtBiB,EAAW76B,OAAS,IAI5BkQ,MAAO,SAASkE,GACZ,GAAImV,EAAQxO,QAAQ3G,GAIhB,MAHAhU,GAAInG,GAAG8H,OAAO,4DAA6DqS,EAAI8F,EAAQ9F,KACvFmV,EAAQ4P,cAAc/kB,GAAIyuB,QAAS,EACnCxH,EAAMjnB,IACC,GAIf0nB,mBAAoB,SAAS1nB,GACzB,GAAI9E,GAAYia,EAAQxO,QAAQ3G,GAAK,CACjC,GACI0uB,GACAn4B,EAFA0G,EAAQkY,EAAQ4P,cAAc/kB,EAQlC,UAJO/C,GAAM/B,SAEb+B,EAAM/B,YACNwzB,EAAcvZ,EAAQsS,gBAAgBznB,GAClC0uB,EAAc,GAAKxzB,EAASmjB,UAAW,CAKvC,IAJAphB,EAAM/B,SAASmL,SAAU,EACzBpJ,EAAM/B,SAASyzB,MAAQD,EACvBzxB,EAAM/B,SAASwrB,aAEVnwB,EAAI,EAAGA,EAAIm4B,EAAan4B,IACzB0G,EAAM/B,SAASwrB,UAAU39B,KAAKwN,EAGlC4e,GAAQsY,eAAeztB,OAGvB/C,GAAM/B,SAASmL,SAAU,IAKrC8jB,WAAY,SAASnqB,EAAI4uB,GACjBzZ,EAAQxO,QAAQ3G,KAChBmV,EAAQ4P,cAAc/kB,GAAIqB,KAAOutB,IAIzClF,WAAY,SAAS1pB,GACjB,GAAI4tB,GAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAE1CpQ,IAAG+C,KAAKglC,EAAUE,eAAgB,SAASe,SAChCjB,GAAUE,eAAee,KAGpChpC,GAAG+C,KAAKglC,EAAUC,KAAM,SAASgB,SACtBjB,GAAUC,KAAKgB,MAW9BC,WAAY,SAAS9uB,EAAI+uB,GACrB,MAAO5Z,GAAQ6Z,aAAahvB,EAAI+uB,EAAalpC,GAAG+J,sBAGpDw9B,kBAAmB,SAASptB,EAAI+uB,GAC5B,GAAIvJ,GAA0B,MAAfuJ,GAAsB,EAAKA,CAC1C,OAAO5Z,GAAQ4P,cAAc/kB,GAAI/J,KAAK63B,eAAetI,IAGzDC,cAAe,SAASzlB,EAAIivB,GACxB,GAAIzQ,GAAY6O,EAAartB,GACzBkvB,EAAW1mB,EAAQxI,GACnBtP,EAAaykB,EAAQ5N,QAAQvH,GAC7BmvB,EAAa3Q,EAAYyQ,EACzBG,EAAWD,EAAa3Q,GAAa0Q,EAAWA,EAAWC,EAAa3Q,EACxEkQ,EAAcvZ,EAAQsS,gBAAgBznB,GACtC2tB,EAAeznC,KAAK6+B,cAAc/kB,GAAI/J,KAAK03B,aAI3Cx8B,EAAOw8B,EAAasB,IAAeppC,GAAG4K,UAAUC,EAAYy+B,EAAYC,EAI5E,OAFAzB,GAAasB,GAAc99B,GAGvBk+B,KAAMJ,EACNt+B,MAAOw+B,EACPv+B,IAAKw+B,EACLE,MAAOZ,EACPv9B,KAAMA,EACNiQ,KAAMguB,EAAWD,IAIzBvJ,yBAA0B,SAAS7T,GAC/B,OACIG,UAAWH,EAAUsd,KACrBE,UAAWxd,EAAUphB,MAAQ,EAC7B6+B,QAASzd,EAAUnhB,IACnB8tB,WAAY3M,EAAUud,QAQ9BvE,mBAAoB,SAAS/qB,GACzB,GACIpY,GAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,GACfwe,EAAY6O,EAAartB,GACzBgE,EAAW+D,EAAY/H,GACvBgf,EAAahjB,EAAOgjB,WAAWhf,GAC/ByvB,EAAiB5pC,GAAG8H,OAAO,2BAA4BgjB,EANvC,MAMiE/oB,EAAMwZ,EAAMod,EAAWxa,EAM5G,OAJAgb,GAAW0Q,QAAQ,SAASp6B,GACxBm6B,GAAkB,IAAMn6B,IAGrBm6B,GAGXE,aAAc,SAAS3vB,GACnB,MAAOmV,GAAQ5N,QAAQvH,GAAI5Z,MAG/BwpC,oBAAqB,SAAS5vB,GAC1B,MAAOmV,GAAQ4P,cAAc/kB,GAAI9E,UAOrCusB,gBAAiB,SAASznB,GACtB,GAAI9E,EAAU,CACV,GAAIg0B,GAAW1mB,EAAQxI,GACnBwe,EAAY6O,EAAartB,EAE7B,OAAOxY,MAAKqoC,KAAKX,EAAW1Q,KAIpCyP,QAAS,SAASjuB,EAAI+uB,GAClB,GAAIvJ,GAA0B,MAAfuJ,GAAsB,EAAKA,CAC1C,OAAO5Z,GAAQ4P,cAAc/kB,GAAI/J,KAAK43B,KAAKrI,IAG/CsB,SAAU,SAAS9mB,GACf,MAAOmV,GAAQ4P,cAAc/kB,GAAI/J,KAAK43B,MAK1CM,sBAAuB,SAASj5B,GACxBq4B,GACA1nC,GAAG+C,KAAK+Q,aAAc,SAASrE,EAAKnI,GAChC,GAAwD,IAApDmI,EAAI9J,QAAQ3F,GAAG8H,OAAO,aAAcgjB,IAAmB,CAEvDzb,EAASI,EADQ8B,KAAKC,MAAMlK,QAO5CsgC,eAAgB,SAASztB,GACrBmV,EAAQ4P,cAAc/kB,GAAI/J,MACtB63B,kBACAnI,iBACAkI,QACAF,kBAIRmC,kBAAmB,SAAS9vB,GACxBmV,EAAQ4P,cAAc/kB,GAAIouB,cAAe,GAK7CnI,+BAAgC,SAASjmB,GACrC,GAAIyvB,EAEJ,UAAIlC,GAAiBpY,EAAQnM,YAAYhJ,KACrCyvB,EAAiBta,EAAQ4V,mBAAmB/qB,GAExCyvB,GAAkB91B,aAAapE,QAAQk6B,OACvC91B,aAAao2B,WAAWN,IACjB,IASnB/B,uBAAwB,SAAS1tB,GAC7B,GACIyvB,GAAgBO,EADhB/yB,EAAQkY,EAAQ4P,cAAc/kB,EAK9ButB,IAA+BvjC,SAAdiT,EAAM3H,MACvBm6B,EAAiBta,EAAQ4V,mBAAmB/qB,GAC5CgwB,EAAgBr2B,aAAapE,QAAQk6B,GAGjCO,IACAA,EAAgB54B,KAAKC,MAAM24B,GAIvBnd,EAAcmd,EAAc7vB,MAC5BgV,EAAQ2a,kBAAkB9vB,IAG1BhU,EAAInG,GAAG8H,OAAO,0DAA2DqS,EAAI8F,EAAQ9F,KAErF0S,EAAc1S,EAAIgwB,EAAc7vB,MAEhClD,EAAM3H,IAAM06B,EAAc16B,IAC1B2H,EAAM/B,SAAW80B,EAAc90B,SAC/B+B,EAAM+T,OAASgf,EAAchf,OAC7B/T,EAAMqV,iBAAmB0d,EAAc1d,iBACvCrV,EAAMyoB,kBAAmB,EAEzBvQ,EAAQgS,0BAA0BnnB,OAOlDmoB,0BAA2B,SAASnoB,GAChC,GACIyvB,GAAgBO,EADhB/yB,EAAQkY,EAAQ4P,cAAc/kB,EAIlC,IAAIutB,GAAiBpY,EAAQnM,YAAYhJ,GAAK,CAC1C,GAAIsS,GAAmBU,EAAoBhT,EAE3CyvB,GAAiBta,EAAQ4V,mBAAmB/qB,GAE5CgwB,GACIpoC,KAAMke,EAAQ9F,GACdoB,KAAMoH,EAAQxI,GACdG,KAAM4I,EAAQ/I,GACd1K,IAAK2H,EAAM3H,IACX4F,SAAU+B,EAAM/B,SAChB8V,OAAQ/T,EAAM+T,OACdif,YAAa1L,KAAKkG,OAGlBnY,IACA0d,EAAc1d,iBAAmBA,EAGrC,KACI3Y,aAAaC,QAAQ61B,EAAgBr4B,KAAKmrB,UAAUyN,IAExD,MAAOhgC,GACHhE,EAAInG,GAAG8H,OAAO,0DAA2DqS,EAAIhQ,EAAMxD,YAAa,WAK5G0jC,yBAA0B,SAASlwB,EAAIwlB,EAAUhH,GAC7C,GAAIpN,GAAM+D,EAAQ8Y,QAAQjuB,EAAIwlB,GAC1B59B,EAAOke,EAAQ9F,GACfmwB,GACI5G,OAAQ,SAASvY,EAAQC,GACrB,GAAIie,GAAW1mB,EAAQxI,EAEnBgR,KAAWC,EACXF,EAAW/Q,EAAIpY,EAAMsnC,EAAUA,GAG/Bne,EAAW/Q,EAAIpY,EAAOopB,GAAUke,EAAWA,EAAW,EAAIle,EAASke,IAI3E3J,QAAS,SAASvU,EAAQC,GACtB,GAAI0U,GAAgBxQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK0vB,cAC/CyK,EAAiCjb,EAAQ4P,cAAc/kB,GAAIgR,OAC3Dqf,EAAmBrf,EACnBsf,EAAkBrf,EAClBwN,EAAgBjW,EAAQxI,GACxBuwB,EAAuBF,GAAoBC,EAAkB9R,GAC7DgS,EAAqBJ,CAEzBzK,GAAcH,GAAY+K,EAE1B1qC,GAAG+C,KAAK+8B,EAAe,SAASH,EAAUiL,GACtCD,GAAsBC,IAG1B1f,EAAW/Q,EAAIpY,EAAM4oC,EAAoB/R,IAIrDrN,GAAIvhB,OAAO4wB,WAAa,SAAS9rB,GAC7B,GAAIA,EAAE+tB,iBAAkB,CAGpByN,EADwB,MAAb3R,EAAoB,SAAW,WACjB7pB,EAAEqc,OAAQrc,EAAEsc,UAcjD+d,aAAc,SAAShvB,EAAI+uB,EAAa3d,EAAKsf,GACzC,GAAIC,GAAwB,MAAf5B,GAAsB,EAAKA,EACpCnB,EAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAW1C,OATA23B,GAAUC,KAAOD,EAAUC,SAC3BD,EAAUE,eAAiBF,EAAUE,mBAErCF,EAAUC,KAAK8C,GAAUvf,EAErBsf,IACA9C,EAAUE,eAAe6C,GAAUD,GAGhCtf,GAIX2Y,8BAA+B,WAC3B,GAAI6G,GAAiB50B,EAAO8iB,eAE5B3J,GAAQgZ,sBAAsB,SAAS74B,EAAKsQ,GACxC,GAAIirB,GAAiB,GAAItM,MAAK3e,EAAWqqB,YAGzCY,GAAeC,QAAQD,EAAeE,UAAYH,GAE9CC,EAAerM,WAAaD,KAAKkG,QACjCz+B,EAAI,2CAA6CsJ,GACjDqE,aAAao2B,WAAWz6B,OAWpCq1B,qBAAsB,SAAS3qB,GAC3B,GAAI/C,GAAQkY,EAAQ4P,cAAc/kB,EAGlC,IAAI/C,EAKA,MAJKA,GAAM/B,UACPia,EAAQuS,mBAAmB1nB,GAGxB/C,EAAM/B,SAASmL,YCziBtCxgB,GAAGinB,wBAA0B,SAASpP,GAClC,YAqBA,SAASszB,KACL,MAAqC,SAAjClzB,EAAQiP,OAAOC,eAEXikB,QAAS,aAtBrB,GAAIC,GACApzB,GACIiP,OAAQ,SACRG,cAAe,SACfK,iBACAN,eAAgB,EAChBI,cAAe,SAASrN,GAAK,UAC7BsN,eACAE,MACI8I,UAAU,EACV4I,iBAAiB,GAErBlzB,IAAK,SAAS4B,EAAK1B,KACnBuhB,SAAU,SAASzN,KACnB2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,KAGjDhoB,IAAG6B,OAAOoW,EAASJ,GAYnBwzB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdM,cAAe,OAAQ,UACvBrW,OAAQjP,EAAQiP,OAChBQ,cAAezP,EAAQyP,cACvBD,YAAaxP,EAAQwP,YACrBgU,eAAgB0P,IAChB/jB,eAAgBnP,EAAQmP,eACxBI,cAAe,SAASrN,GACpB,MAAOlC,GAAQuP,cAAcpF,IAAIjI,IAErChU,IAAK8R,EAAQ9R,IACb01B,OAAQ5jB,EAAQ2P,SAChB0D,WAAYrT,EAAQ6P,iBACpBH,KAAM1P,EAAQ0P,QAGlB3nB,GAAG6B,OAAOxB,MACN+zB,WAAY,SAASja,EAAIG,EAAM0Z,GAC3B,GAAInJ,GAAoBmJ,KAExB/b,GAAQ9R,IAAI,sCAAwCgU,GAE7B,WAAnBlC,EAAQiP,OACRmkB,EAAUxN,cAAc1jB,GACnB6jB,SAAS1jB,GACT4jB,WAAWrT,GACX0R,QAGL1R,EAAkB5S,EAAQoP,eAAiB/M,EAC3C+wB,EAAUxN,cAAc1jB,GACnB+jB,WAAWrT,GACX0R,YCpDrB,WAMI,QAAS+O,GAAkBC,GACvB,GAGIC,GAHAC,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTvnC,EAASsF,SAASC,cAAc,SAGpC,OAAI6hC,GAAKE,EAAK,UACVtnC,EAAOwnC,MAAQxnC,EAAO0U,OAAS,EAC/ByyB,EAAMnnC,EAAOynC,WAAW,MACxBN,EAAIO,UAAUR,GAAME,EAAK,EAAG,GAIoB,IAAzCD,EAAIQ,aAAa,EAAG,EAAG,EAAG,GAAGhnC,KAAK,IAUjD,QAASinC,GAAqBV,EAAKE,EAAIE,GACnC,GAIIH,GAAKxmC,EAAMknC,EAAOC,EAJlB9nC,EAASsF,SAASC,cAAc,UAChCwiC,EAAK,EACLC,EAAKV,EACLW,EAAKX,CAUT,KAPAtnC,EAAOwnC,MAAQ,EACfxnC,EAAO0U,OAAS4yB,EAChBH,EAAMnnC,EAAOynC,WAAW,MACxBN,EAAIO,UAAUR,EAAK,EAAG,GACtBvmC,EAAOwmC,EAAIQ,aAAa,EAAG,EAAG,EAAGL,GAAI3mC,KAG9BsnC,EAAKF,GACRF,EAAQlnC,EAAgB,GAAVsnC,EAAK,GAAS,GACd,IAAVJ,EACAG,EAAKC,EAELF,EAAKE,EAETA,EAAMD,EAAKD,GAAO,CAItB,OADAD,GAASG,EAAKX,EACI,IAAVQ,EAAe,EAAIA,EAM/B,QAASI,GAAqBhB,EAAKjgC,EAAM2M,EAASu0B,GAC9C,GAAInoC,GAASsF,SAASC,cAAc,UAChCtF,EAAO2T,EAAQ3T,MAAQ,aACvBqH,EAAU,GAAI3L,IAAG4L,OASrB,OAPA6gC,GAAoBlB,EAAKjgC,EAAMjH,EAAQ4T,EAASu0B,GAC3C11B,KAAK,WACFnL,EAAQG,QACJzH,EAAOI,UAAUH,EAAM2T,EAAQ1T,SAAW,OAI/CoH,EAGX,QAAS+gC,GAAoCtxB,GAGzC,IAAKpb,GAAGsO,MACJ,KAAM,IAAItO,IAAGwB,MAAM,kEAGvB,IAAI4Z,EAAKuxB,WAAavxB,EAAKwxB,UANX,OAOZ,OACIC,UAAWlrC,KAAKC,MAAMD,KAAKmrC,KARnB,QAQqC1xB,EAAKuxB,WAAavxB,EAAKwxB,aACpEG,SAAUprC,KAAKC,MAAMD,KAAKmrC,KATlB,QASoC1xB,EAAKwxB,UAAYxxB,EAAKuxB,eAQ9E,QAASF,GAAoBlB,EAAKjgC,EAAMjH,EAAQ4T,EAASu0B,GACrD,GAMIQ,GANAvB,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTC,EAAQ5zB,EAAQ4zB,MAChB9yB,EAASd,EAAQc,OACjByyB,EAAMnnC,EAAOynC,WAAW,MACxBngC,EAAU,GAAI3L,IAAG4L,OAKrB,OAFA4/B,GAAIyB,OAEAh1B,EAAQi1B,OACDC,GACH7hC,KAAMA,EACNjH,OAAQA,EACR+xB,MAAOmV,EACP6B,YAAazB,EACb0B,WAAY5B,EACZ6B,YAAar1B,EAAQq1B,YACrBJ,OAAQj1B,EAAQi1B,OAChBK,aAAcx0B,EACdy0B,YAAa3B,KAIhB7rC,GAAG8S,kBAAkBwD,2BACtB02B,EAAqBN,GACjBE,UAAWf,EACXc,WAAY5zB,IAGZi0B,IACAhtC,GAAGmG,IAAInG,GAAG8H,OAAO,iFACb+jC,EAAO9yB,EAAQi0B,EAAmBD,SAAUC,EAAmBH,WAC/D,QAEJhB,EAAQmB,EAAmBD,SAC3Bh0B,EAASi0B,EAAmBH,YAIpCY,EAAoBppC,EAAQwnC,EAAO9yB,EAAQd,EAAQq1B,aAI/CttC,GAAGsO,MACF,WACOg9B,EAAkBC,KAClBE,GAAM,EACNE,GAAM,EAGV,IAOI+B,GAAQC,EAAIC,EAPZC,EAAI,KACJC,EAAYnkC,SAASC,cAAc,UACnCmkC,EAAkBvB,EAAWP,EAAqBV,EAAKE,EAAIE,GAAM,EACjEqC,EAAKrsC,KAAKqoC,KAAK6D,EAAIhC,EAAQJ,GAC3BwC,EAAKtsC,KAAKqoC,KAAK6D,EAAI90B,EAAS4yB,EAAKoC,GACjC3B,EAAK,EACL8B,EAAK,CAMT,KAHAJ,EAAUjC,MAAQiC,EAAU/0B,OAAS80B,EACrCH,EAASI,EAAUhC,WAAW,MAEvBM,EAAKT,GAAI,CAGZ,IAFAgC,EAAK,EACLC,EAAK,EACED,EAAKlC,GACRiC,EAAOS,UAAU,EAAG,EAAGN,EAAGA,GAC1BH,EAAO3B,UAAUR,GAAMoC,GAAKvB,GAC5BZ,EAAIO,UAAU+B,EAAW,EAAG,EAAGD,EAAGA,EAAGD,EAAIM,EAAIF,EAAIC,GACjDN,GAAME,EACND,GAAMI,CAEV5B,IAAMyB,EACNK,GAAMD,EAEVzC,EAAI4C,UACJN,EAAYJ,EAAS,QAIzBlC,EAAIO,UAAUR,EAAK,EAAG,EAAGM,EAAO9yB,GAGpC1U,EAAOgqC,iBAAmBhqC,EAAOgqC,kBACjC1iC,EAAQG,UAEDH,GAGX,QAASwhC,GAAqCmB,GAC1C,GAAIhjC,GAAOgjC,EAAWhjC,KAClB8qB,EAAQkY,EAAWlY,MACnBgX,EAAckB,EAAWlB,YACzBC,EAAaiB,EAAWjB,WACxBC,EAAcgB,EAAWhB,YACzB3hC,EAAU,GAAI3L,IAAG4L,QACjBshC,EAASoB,EAAWpB,OACpBqB,EAAe5kC,SAASC,cAAc,UACtC4kC,EAAsBD,EAAazC,WAAW,MAC9C2C,EAAeH,EAAWjqC,OAC1BkpC,EAAee,EAAWf,aAC1BC,EAAcc,EAAWd,WAyB7B,OAvBAC,GAAoBc,EAAclB,EAAYD,EAAaE,GAE3DmB,EAAa11B,OAASw0B,EACtBkB,EAAa5C,MAAQ2B,EAErBgB,EAAoBzC,UAAU3V,EAAO,EAAG,GAExC8W,GACI5hC,KAAMA,EACNyN,OAAQw0B,EACRnX,MAAOA,EACPmY,aAAcA,EACdE,aAAcA,EACd5C,MAAO2B,IAEN12B,KACG,WACI23B,EAAaJ,iBAAmBI,EAAaJ,kBAC7C1iC,EAAQG,WAEZH,EAAQK,SAGTL,EAOX,QAAS8hC,GAAoBppC,EAAQwnC,EAAO9yB,EAAQu0B,GAChD,OAAQA,GACJ,IAAK,GACL,IAAK,GACL,IAAK,GACL,IAAK,GACDjpC,EAAOwnC,MAAQ9yB,EACf1U,EAAO0U,OAAS8yB,CAChB,MACJ,SACIxnC,EAAOwnC,MAAQA,EACfxnC,EAAO0U,OAASA,EAExB,GAAIyyB,GAAMnnC,EAAOynC,WAAW,KAC5B,QAAQwB,GACJ,IAAK,GAED9B,EAAIkD,UAAU7C,EAAO,GACrBL,EAAI/pB,OAAM,EAAI,EACd,MACJ,KAAK,GAED+pB,EAAIkD,UAAU7C,EAAO9yB,GACrByyB,EAAImD,OAAOhtC,KAAKitC,GAChB,MACJ,KAAK,GAEDpD,EAAIkD,UAAU,EAAG31B,GACjByyB,EAAI/pB,MAAM,GAAG,EACb,MACJ,KAAK,GAED+pB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAI/pB,MAAM,GAAG,EACb,MACJ,KAAK,GAED+pB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAIkD,UAAU,GAAI31B,EAClB,MACJ,KAAK,GAEDyyB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAIkD,UAAU7C,GAAQ9yB,GACtByyB,EAAI/pB,OAAM,EAAI,EACd,MACJ,KAAK,GAED+pB,EAAImD,QAAO,GAAOhtC,KAAKitC,IACvBpD,EAAIkD,WAAW7C,EAAO,IAUlC,QAASgD,GAAaC,EAAUC,GAC5B,GAAI52B,GAAO9X,IAEP6E,QAAOO,MAAQqpC,YAAoBrpC,OAClC,WACG,GAAI8lC,GAAM,GAAIyD,OACVC,EAAM/pC,OAAO+pC,KAAO/pC,OAAO+pC,IAAIC,gBAAkBhqC,OAAO+pC,IACpD/pC,OAAOiqC,WAAajqC,OAAOiqC,UAAUD,gBAAkBhqC,OAAOiqC,UAAY,IAClF,KAAKF,EAAO,KAAMztC,OAAM,uDACxB+pC,GAAI6D,IAAMH,EAAIC,gBAAgBJ,GAC9B32B,EAAK7M,KAAOwjC,EACZA,EAAWvD,KAGduD,EAASpD,cAAiBoD,EAASlD,gBACpCkD,EAASjjC,OAAS,WACd,GAAIwjC,GAAYl3B,EAAKm3B,kBACjBD,KACAl3B,EAAKm3B,mBAAqB,KAG1B3lB,WAAW,WACP,IAAK,GAAIjZ,GAAI,EAAG3D,EAAMsiC,EAAUtpC,OAAQ2K,EAAI3D,EAAK2D,IAC7C2+B,EAAU3+B,MAEf,KAGXo+B,EAAS/iC,QAAUgjC,EACnB1uC,KAAKivC,uBAETjvC,KAAKyuC,SAAWA,EAMpBD,EAAanoC,UAAU6oC,OAAS,SAASjjC,EAAQ2L,GAC7CA,EAAUA,KAEV,IASIu3B,GATAr3B,EAAO9X,KACPovC,EAAWpvC,KAAKyuC,SAASpD,aACzBgE,EAAYrvC,KAAKyuC,SAASlD,cAC1BC,EAAQ5zB,EAAQ4zB,MAChB9yB,EAASd,EAAQc,OACjBue,EAAWrf,EAAQqf,SACnBD,EAAYpf,EAAQof,UACpBmV,GAAYnsC,KAAKiL,MAA2B,eAAnBjL,KAAKiL,KAAK/K,KACnC+I,EAAUgD,EAAOhD,QAAQF,aAG7B,IAAI/I,KAAKivC,mBAEL,WADAjvC,MAAKivC,mBAAmBpsC,KAAK,WAAaiV,EAAKo3B,OAAOjjC,EAAQ2L,IAI9D4zB,KAAU9yB,EACVA,EAAU22B,EAAY7D,EAAQ4D,GAAa,EACpC12B,IAAW8yB,EAClBA,EAAS4D,EAAW12B,EAAS22B,GAAc,GAE3C7D,EAAQ4D,EACR12B,EAAS22B,GAETpY,GAAYuU,EAAQvU,IACpBuU,EAAQvU,EACRve,EAAU22B,EAAY7D,EAAQ4D,GAAa,GAE3CpY,GAAate,EAASse,IACtBte,EAASse,EACTwU,EAAS4D,EAAW12B,EAAS22B,GAAc,GAG/CF,GAAQ3D,MAAOA,EAAO9yB,OAAQA,GAC9B/Y,GAAG+C,KAAKkV,EAAS,SAAS03B,EAAYC,GAClCJ,EAAIG,GAAcC,IAGN,QAAZtmC,EACC,WACG,GAAIumC,GAAevjC,EAAO8iC,GAC1B7C,GAAqBp0B,EAAK22B,SAAU32B,EAAK7M,KAAMkkC,EAAKhD,GAC/C11B,KAAK,SAASpS,GACX4H,EAAO8iC,IAAM1qC,EACbmrC,IAAiBvjC,EAAO8iC,KAAO9iC,EAAOT,cAG/B,WAAZvC,GACPmjC,EAAoBpsC,KAAKyuC,SAAUzuC,KAAKiL,KAAMgB,EAAQkjC,EAAKhD,GAElC,kBAAlBnsC,MAAKyvC,UACZzvC,KAAKyvC,SAASxjC,IAItBtM,GAAG6uC,aAAeA,KCtYtB7uC,GAAG+5B,eAAiB,SAAS5zB,GACzB,YAEA,SAAS4pC,GAAMC,GACX,MAAoC,QAA7BA,EAAG1mC,QAAQF,cAGtB,QAAS6mC,GAASD,GACd,MAAoC,WAA7BA,EAAG1mC,QAAQF,cAGtB,QAAS8mC,KACL,MAAmC/rC,WAA5B,GAAI6qC,QAAQmB,YAGvB,QAASC,KACL,GAAI/rC,GAASsF,SAASC,cAAc,SAEpC,OAAOvF,GAAOynC,YAAcznC,EAAOynC,WAAW,MAMlD,QAASuE,GAAwBC,GAE7B,GAAIC,GAAeD,EAAa5qC,MAAM,KAClC3D,EAAOwuC,EAAaA,EAAaxqC,OAAS,GAAGL,MAAM,KAAK,GACxDmqB,EAAY7vB,GAAG0R,aAAa3P,EAIhC,QAFA8tB,EAAYA,GAAaA,EAAUzmB,eAG/B,IAAK,OACL,IAAK,MACD,MAAO,YACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,OACL,IAAK,MACD,MAAO,cASnB,QAASonC,GAAc7U,GACnB,GACI8U,GAAgBC,EAAgBC,EADhCC,EAAejnC,SAASC,cAAc,IAS1C,OANAgnC,GAAaC,KAAOlV,EAEpB8U,EAAiBG,EAAaE,SAC9BH,EAAaC,EAAaG,KAC1BL,EAAiBE,EAAaI,SAE1BP,EAAernC,gBAAkBlE,OAAO+rC,SAASH,SAAS1nC,gBAI1DsnC,EAAetnC,gBAAkBlE,OAAO+rC,SAASD,SAAS5nC,eAK1DunC,IAAezrC,OAAO+rC,SAASF,OAAS/wC,GAAGqN,MAOnD,QAAS6jC,GAAyB3F,EAAK5/B,GACnC4/B,EAAI1/B,OAAS,WACT0/B,EAAI1/B,OAAS,KACb0/B,EAAIx/B,QAAU,KACdJ,EAAQG,QAAQy/B,IAGpBA,EAAIx/B,QAAU,WACVw/B,EAAI1/B,OAAS,KACb0/B,EAAIx/B,QAAU,KACd5F,EAAI,6BAA8B,SAClCwF,EAAQK,QAAQu/B,EAAK,+BAI7B,QAAS4F,GAAgC9sC,EAAQsH,GAO7CtH,EAAOgqC,gBAAkB,WACrB1iC,EAAQG,QAAQzH,IAQxB,QAAS+sC,GAAkCnwB,EAAatV,GACpD,GAAI0lC,GAAatB,EAAM9uB,IAAgBgvB,EAAShvB,EAahD,OAXI8uB,GAAM9uB,GACNiwB,EAAyBjwB,EAAatV,GAEjCskC,EAAShvB,GACdkwB,EAAgClwB,EAAatV,IAG7CA,EAAQK,QAAQiV,GAChB9a,EAAInG,GAAG8H,OAAO,iDAAkDmZ,EAAY3X,SAAU,UAGnF+nC,EAKX,QAASC,GAAKzmC,EAAY8W,EAAW1J,GACjC,GAAIs5B,GAAc,GAAIvxC,IAAG4L,QACrB6c,EAAa,GAAIzoB,IAAGwxC,SAAS3mC,EAAY1E,GACzC+a,EAAUjJ,EAAQiJ,QAElBuY,EAA2B,MAAlBxhB,EAAQwhB,QAAwBxhB,EAAQwhB,OACjDgY,EAAsB,WAClB9vB,EAAU5V,QAAU,KACpB4V,EAAU9V,OAAS,KACnB1F,EAAI,mDAAoD,SACxDorC,EAAYvlC,QAAQ2V,EAAW,gCAiDvC,OA9CA8G,GAAWipB,gBAAgB56B,KACvB,SAASxS,GAGL,GAAIqtC,IACIngC,MAAO,WACH,OAAO,GAAIxR,IAAG4L,SAAUE,YAGhC8lC,EAAOnY,EAAS,GAAIz5B,IAAG6xC,KAAKhnC,EAAY1E,GAAOwrC,EAC/CG,EAAQ,GAAI9xC,IAAG6uC,aAAahkC,EAAY4mC,EAExCL,GAAkCzvB,EAAW4vB,IAC7CK,EAAKpgC,QAAQsF,KACT,SAAS86B,GACL,GAAItE,GAAcsE,GAAQA,EAAKG,WAE/BD,GAAMvC,OAAO5tB,GACT2V,SAAUpW,EACVmW,UAAWnW,EACXosB,YAAaA,EACbhpC,KAAMA,EACN4oC,OAAQj1B,EAAQmJ,wBAIxB,SAAS4wB,GACL7rC,EAAInG,GAAG8H,OAAO,iEAAkEkqC,IAEhFF,EAAMvC,OAAO5tB,GACT2V,SAAUpW,EACVmW,UAAWnW,EACX5c,KAAMA,EACN4oC,OAAQj1B,EAAQmJ,0BAOpC,WACIjb,EAAI,mBACJorC,EAAYvlC,QAAQ2V,EAAW,qBAIhC4vB,EAGX,QAASU,GAAyBtW,EAAKuW,EAAaZ,EAAMpwB,EAASE,GAC/D,GAAI+wB,GAAU,GAAInD,OACdoD,EAAgB,GAAIpyC,IAAG4L,OAE3BwlC,GAAkCe,EAASC,GAEvC5B,EAAc7U,KACdwW,EAAQhC,YAAc,aAG1BgC,EAAQ/C,IAAMzT,EAEdyW,EAAct7B,KACV,WACIs6B,EAAkCc,EAAaZ,GAEnC,GAAItxC,IAAG6uC,aAAasD,GAC1B5C,OAAO2C,GACT5a,SAAUpW,EACVmW,UAAWnW,EACX5c,KAAM+rC,EAAwB1U,GAC9BuR,OAAQ9rB,KAIhBkwB,EAAKtlC,SAIb,QAASqmC,GAA+B1W,EAAK4P,EAAK+F,EAAMpwB,GACpDkwB,EAAkC7F,EAAK+F,GAKvCtxC,GAAGurC,GAAKjqC,KACJg2B,SAAUpW,EAAU,KACpBmW,UAAWnW,EAAU,OAGzBqqB,EAAI6D,IAAMzT,EAWd,QAAS2W,GAAY3W,EAAKha,EAAW1J,GACjC,GAAIq5B,GAAO,GAAItxC,IAAG4L,QACd6V,EAAQxJ,EAAQwJ,MAChBP,EAAUO,EAAQxJ,EAAQiJ,QAAU,IA8BxC,OA3BIO,IAASsuB,EAAMpuB,GAGXyuB,IAIII,EAAc7U,KAASuU,IACvBmC,EAA+B1W,EAAKha,EAAW2vB,EAAMpwB,GAGrD+wB,EAAyBtW,EAAKha,EAAW2vB,EAAMpwB,GAInDmxB,EAA+B1W,EAAKha,EAAW2vB,EAAMpwB,GAIpD+uB,EAAStuB,GACdswB,EAAyBtW,EAAKha,EAAW2vB,EAAMpwB,GAG1CkwB,EAAkCzvB,EAAW2vB,KAClD3vB,EAAUytB,IAAMzT,GAGb2V,EAGXtxC,GAAG6B,OAAOxB,MAWNuhB,SAAU,SAAS2wB,EAAe5wB,EAAW1J,GACzC,MAAIjY,IAAGwH,SAAS+qC,IACZpsC,EAAI,4DACGmsC,EAAYC,EAAe5wB,EAAW1J,SAG7C9R,EAAI,iDACGmrC,EAAKiB,EAAe5wB,EAAW1J,WAMlD5X,KAAKmyC,YACLnyC,KAAKmyC,SAASzC,MAAQA,EACtB1vC,KAAKmyC,SAASvC,SAAWA,EACzB5vC,KAAKmyC,SAAShC,cAAgBA,EAC9BnwC,KAAKmyC,SAASnC,wBAA0BA,GChT5CrwC,GAAG6xC,KAAO,SAAShnC,EAAY1E,GAC3B,YAYA,SAASssC,GAAkBC,GAIvB,IAHA,GAAI/vC,GAAS,EACTgwC,EAAM,EAEHD,EAAI3sC,OAAS,GAChBpD,GAAU2gC,SAASoP,EAAIpqC,UAAU,EAAG,GAAI,IAAM3G,KAAKgxC,IAAI,EAAGA,GAC1DD,EAAMA,EAAIpqC,UAAU,EAAGoqC,EAAI3sC,QAC3B4sC,GAAO,CAGX,OAAOhwC,GAKX,QAASiwC,GAAWC,EAAQlnC,GACxB,GAAImnC,GAAYD,EACZE,EAAapnC,CAwBjB,OAvBkBxH,UAAd2uC,IACAA,EAAY,EACZC,EAAa,GAAI/yC,IAAG4L,SAGxB5L,GAAGqL,cAAcR,EAAYioC,EAAW,GAAGh8B,KAAK,SAAS47B,GACrD,GACIM,GADA3/B,EAAQ,cAAcpP,KAAKyuC,EAG3Br/B,GACiB,MAAbA,EAAM,IACN2/B,EAAgB1P,SAASoP,EAAIxqC,MAAM,EAAG,GAAI,IAC1C0qC,EAAWE,EAAYE,EAAgB,EAAGD,IAG1CA,EAAWjnC,QAAQgnC,GAIvBC,EAAW/mC,QAAQ,iCAIpB+mC,EAIX,QAASE,KACL,GAAItnC,GAAU,GAAI3L,IAAG4L,OAgBrB,OAdA5L,IAAGqL,cAAcR,EAAY,EAAG,GAAGiM,KAAK,SAAS47B,GACjB,IAAxBA,EAAI/sC,QAAQ,QACZgG,EAAQK,QAAQ,qBAGhB4mC,IAAa97B,KAAK,SAAS+7B,GACvBlnC,EAAQG,QAAQ+mC,IAEpB,SAAS1oC,GACLwB,EAAQK,QAAQ7B,OAKrBwB,EAIX,QAASunC,GAAeC,GACpB,GAAIxnC,GAAU,GAAI3L,IAAG4L,OAMrB,OAJA5L,IAAGqL,cAAcR,EAAYsoC,EAAY,GAAI,GAAGr8B,KAAK,SAAS47B,GAC1D/mC,EAAQG,QAAgB,SAAR4mC,KAGb/mC,EAIX,QAASynC,GAAiBD,EAAWE,GACjC,GAAI1nC,GAAU,GAAI3L,IAAG4L,OAWrB,OATA5L,IAAGqL,cAAcR,EAAYsoC,EAAY,GAAI,GAAGr8B,KAAK,SAAS47B,GAC1D,GAAIW,EACA,MAAO1nC,GAAQG,QAAQ2mC,EAAkBC,GAGzC/mC,GAAQG,QAAQw3B,SAASoP,EAAK,OAI/B/mC,EAIX,QAAS2nC,GAAOH,EAAWI,GACvB,GAAIV,GAASM,EAAY,GACrBjoC,EAAqB,GAAbqoC,CAEZ,OAAOvzC,IAAGqL,cAAcR,EAAYgoC,EAAQ3nC,GAIhD,QAASsoC,GAAcC,GAInB,IAHA,GAAIv5B,MACA24B,EAAS,EAENA,EAAS,IAAMY,EAAO1tC,QACzBmU,EAAQhX,KAAKuwC,EAAOvrC,MAAM2qC,EAAQA,EAAS,KAC3CA,GAAU,EAGd,OAAO34B,GAIX,QAASw5B,GAAaL,EAAcE,GAChC,GACII,GAAa3zC,GAAG6B,UAAW+xC,GAC3BC,IAsBJ,OApBA7zC,IAAG+C,KAAKwwC,EAAY,SAASvwC,EAAKm3B,GAC9B,GAGI2Z,GAAWxqC,EAASyqC,EAHpBC,EAAQ7Z,EAAMjyB,MAAM,EAAG,GACvBiS,EAAKk5B,EAAeZ,EAAkBuB,GAAS1Q,SAAS0Q,EAAO,IAC/DC,EAAgBN,EAAWhuC,QAAQwU,EAYvC,IATI85B,GAAiB,IACjB3qC,EAAU4qC,EAAS/5B,GAAIpY,KACvBgyC,EAAeG,EAAS/5B,GAAIjP,MAC5B4oC,EAAY3Z,EAAMjyB,MAbL,GAAA,GAa4D,EAAf6rC,GAC1DF,EAAKvqC,GAAW+pC,EAAeZ,EAAkBqB,GAAaxQ,SAASwQ,EAAW,IAElFH,EAAWt3B,OAAO43B,EAAe,IAGX,IAAtBN,EAAW5tC,OACX,OAAO,IAIR8tC,EApJX,GAAID,IAAW,KACXM,GACIC,KACIpyC,KAAM,cACNmJ,MAAO,GAmJnBlL,IAAG6B,OAAOxB,MAONmR,MAAO,WACH,GAAI4iC,GAAS,GAAIp0C,IAAG4L,QAChByoC,EAAiB,SAASjuC,GACtBD,EAAInG,GAAG8H,OAAO,kCAAmC1B,IACjDguC,EAAOpoC,QAAQ5F,GA0BvB,OAvBA6sC,KAAgBn8B,KAAK,SAASw9B,GAC1BnuC,EAAInG,GAAG8H,OAAO,mDAAwE3D,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,OAEtHmxC,EAAeoB,GAAYx9B,KAAK,SAASu8B,GAErCltC,EAAInG,GAAG8H,OAAO,+BAAgCurC,EAAe,SAAW,QAExED,EAAiBkB,EAAYjB,GAAcv8B,KAAK,SAASy9B,GAErDpuC,EAAInG,GAAG8H,OAAO,kCAAmCysC,IAEjDjB,EAAOgB,EAAYC,GAAez9B,KAAK,SAAS28B,GAC5C,GAAIF,GAAaC,EAAcC,GAC3Be,EAAYd,EAAaL,EAAcE,EAE3CptC,GAAI,sCAEJiuC,EAAOtoC,QAAQ0oC,IAChBH,IACJA,IACJA,IACJA,GAEID,KAKf/zC,KAAKmyC,YACLnyC,KAAKmyC,SAASC,kBAAoBA,GC7MtCzyC,GAAGwxC,SAAW,SAAS3mC,EAAY1E,GAC/B,YAEA,SAASsuC,GAAeC,EAAYC,GAChC,GAAIC,IAAe,EACfC,KAAuB7kC,OAAO0kC,EASlC,OAPA10C,IAAG+C,KAAK8xC,EAAmB,SAAS7xC,EAAK8xC,GACrC,GAAwD,IAApDH,EAAkBhvC,QAAQmvC,GAE1B,MADAF,IAAe,GACR,IAIRA,EAGX50C,GAAG6B,OAAOxB,MASNqxC,cAAe,WACX,GAAIv5B,GAAO9X,KACPooB,EAAa,GAAIzoB,IAAG4L,QACpBmpC,GAAc,EACdhzC,EAA2BoC,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,IAsC/D,OApCAoE,GAAInG,GAAG8H,OAAO,gEAAiE/F,IAE/EoE,EAAI,oDAEA9F,KAAK20C,qBACL7uC,EAAI,sDAEJnG,GAAGqL,cAAcR,EAAY,EAAG,GAAGiM,KAAK,SAAS47B,GAC7C1yC,GAAG+C,KAAKoV,EAAK88B,uBAAwB,SAAS3wC,EAAM4G,GAChD,GAAIupC,EAAevpC,EAAOwnC,GAQtB,OALa,eAATpuC,GAAyBtE,GAAG8S,kBAAkBuD,gBAC9C0+B,GAAc,EACdtsB,EAAW3c,QAAQxH,KAGhB,IAIf6B,EAAInG,GAAG8H,OAAO,iDAAkD/F,EAAMgzC,EAAc,GAAK,QAEpFA,GACDtsB,EAAWzc,WAGnB,WACI7F,EAAI,+BAAiCpE,EAAO,gDAC5C0mB,EAAWzc,aAIfyc,EAAWzc,UAGRyc,GAWXusB,kBAAmB,WACf,GAAIE,GAAWrqC,EAAWtK,KAEtB40C,EAAoBn1C,GAAG2F,QAAQc,OAAOu6B,KAAK3gC,KAAK40C,wBAAyBC,IAAa,EACtFH,GAAc,EACdhzC,EAA2BoC,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,IAa/D,OAXIozC,KAEIJ,EADa,eAAbG,GACcl1C,GAAG8S,kBAAkBuD,eAO1C0+B,GAAe5uC,EAAIpE,EAAO,gEAEpBgzC,MAKnB/0C,GAAGwxC,SAAS9qC,UAAUuuC,wBAClBG,aAAc,SACdC,YAAa,SACbC,YAAa,SACbC,YAAa,OACbC,cAAe,WAAY,aCpG/Bx1C,GAAGk2B,gBAAkB,SAAS5qB,EAAMnF,GAChC,YAMA,SAASsvC,GAAiBC,GACtB,GAAIC,IAAa,CASjB,OAPA31C,IAAG+C,KAAK2yC,EAAQ,SAASE,EAAO7uC,GAC5B,GAAIA,EAAQ,EAER,MADA4uC,IAAa,GACN,IAIRA,EAQX,QAASE,KACL,GAAIC,GAAoB,GAAI91C,IAAG4L,OA6B/B,OA3BA,IAAI5L,IAAGwxC,SAASlmC,EAAMnF,GAAKurC,gBAAgB56B,KAAK,WAC5C,GAAIsf,GAAQ,GAAI4Y,OACZrT,EAAMz2B,OAAO+pC,KAAO/pC,OAAO+pC,IAAIC,gBAAkBhqC,OAAO+pC,IAClD/pC,OAAOiqC,WAAajqC,OAAOiqC,UAAUD,gBAAkBhqC,OAAOiqC,UAC9D,IAENxT,IACAvF,EAAMrqB,QAAU,WACZ5F,EAAI,4DAA6D,SACjE2vC,EAAkB9pC,WAGtBoqB,EAAMvqB,OAAS,WACXiqC,EAAkBhqC,SACd+/B,MAAOxrC,KAAKwrC,MACZ9yB,OAAQ1Y,KAAK0Y,UAIrBqd,EAAMgZ,IAAMzT,EAAIuT,gBAAgB5jC,KAGhCnF,EAAI,+DAAgE,SACpE2vC,EAAkB9pC,YAEvB8pC,EAAkB9pC,SAEd8pC,EASX,QAASC,GAAgBL,EAAQM,GAC7B,GAAIC,EA0BJ,OAxBAj2C,IAAG+C,KAAK2yC,EAAQ,SAASQ,EAAWC,GAChC,GAAIA,EAAa,EAAG,CAChB,GAAIC,GAAe,0BAA0BnyC,KAAKiyC,GAC9CG,EAAoBD,EAAa,GAAGzmC,OAAO,GAAGvG,cAAgBgtC,EAAa,GAAGluC,MAAM,GACpFouC,EAAcN,EAAWK,EAG7B,QAAQD,EAAa,IACjB,IAAK,MACD,GAAIE,EAAcH,EAEd,MADAF,GAAeC,GACR,CAEX,MACJ,KAAK,MACD,GAAII,EAAcH,EAEd,MADAF,GAAeC,GACR,MAOpBD,EAWX51C,KAAK81B,SAAW,SAASuf,GACrB,GAAIa,GAAmB,GAAIv2C,IAAG4L,OAoB9B,OAlBAzF,GAAI,iCAEAsvC,EAAiBC,GACjBG,IAAiB/+B,KAAK,SAASk/B,GAC3B,GAAIC,GAAeF,EAAgBL,EAAQM,EAEvCC,GACAM,EAAiBvqC,QAAQiqC,GAGzBM,EAAiBzqC,WAEtByqC,EAAiBzqC,SAGpByqC,EAAiBzqC,UAGdyqC,IC7Hfv2C,GAAGo1B,QAAU,SAASha,GAClB,YAaA,SAASo7B,GAAoBrkB,GACzB,GAAInyB,GAAG8G,QAAQqrB,GACX,OAAO,CAGXla,GAAQ9R,IAAI,oCAAqC,SAGrD,QAASswC,GAAgBC,EAAW5qC,EAASic,EAAUpc,GACnD,GAAIgrC,IAAmB,CAEvB7qC,GAAUA,GAAW0qC,EAAoBE,GAErC5qC,GACA9L,GAAG+C,KAAK2zC,EAAW,SAAS1zC,EAAKg8B,GAE7B,GAAqB,MAAjBA,EAAS1kB,KACTq8B,GAAmB,EACnB1+B,EAAQ9R,IAAInG,GAAG8H,OAAO,oEAAqE9E,GAAM,aAEhG,IAAqB,MAAjBg8B,EAASj9B,KACd40C,GAAmB,EACnB1+B,EAAQ9R,IAAInG,GAAG8H,OAAO,oEAAqE9E,GAAM,aAGjG,KAEI,MADAiV,GAAQqd,cAAc0J,IACf,EAEX,MAAO4X,GACHD,GAAmB,EACnB1+B,EAAQ9R,IAAIywC,EAAIxwC,QAAS,SAIjC,OAAO,IAIfuF,EAAQG,IAAY6qC,EAAmB,UAAY,WAAWD,EAAW3uB,GAlD7E,GAAI9P,IACAkG,SAAU,KACVD,UACAsJ,iBACAG,QACA2N,cAAe,SAASjP,KACxBlgB,IAAK,SAASC,EAASC,KAG3BrG,IAAG6B,OAAOoW,EAASmD,GAAM,GA8CzB/a,KAAKk1B,QAAU,WAEX,GAAIshB,GAAgB,GAAI72C,IAAG4L,QACvBkrC,EAA0B,SAAS3kB,EAAUrmB,EAASic,GAClD0uB,EAAgBtkB,EAAUrmB,EAASic,EAAU8uB,IAEjDE,EAAmB/2C,GAAG6B,UAAWoW,EAOrC,OANgB,IAAIjY,IAAGg3C,qBACfh3C,GAAG6B,OAAOk1C,GAAmBzrB,WAAYwrB,KAGvCG,cAEHJ,ICrEf72C,GAAGg3C,qBAAuB,SAAS57B,GAC/B,YAiBA,SAASkQ,GAAWnR,EAAI4N,EAAUC,GAC9B,GAAImK,GAAW,IAGf,IAA6B,MAAzBpK,EAASmvB,aACT,IACI/kB,EAAWnyB,GAAGqR,UAAU0W,EAASmvB,cAErC,MAAON,GACH3+B,EAAQ9R,IAAI,qCAAuCywC,EAAIxwC,QAAS,SAChE4hB,GAAU,EAIlB/P,EAAQqT,WAAW6G,GAAWnK,EAASD,GA7B3C,GAAIsjB,GACApzB,GACIkG,SAAU,KACVqJ,iBACAtJ,UACAyJ,MACI8I,UAAU,EACV4I,iBAAiB,GAErB/N,WAAY,SAAS6G,EAAUrmB,EAASic,KACxC5hB,IAAK,SAAS4B,EAAK1B,KAG3BrG,IAAG6B,OAAOoW,EAASmD,GAmBnBiwB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdM,cAAe,OACfrW,OAAQ,MACRQ,eACItF,IAAK,WACD,MAAOnK,GAAQkG,WAGvBqJ,cAAevP,EAAQuP,cACvBrhB,IAAK8R,EAAQ9R,IACbmlB,WAAYA,EACZ3D,KAAM1P,EAAQ0P,QAGlB3nB,GAAG6B,OAAOxB,MACN42C,YAAa,WACT,GAAI/4B,GAASle,GAAG6B,UAAWoW,EAAQiG,OAEnCjG,GAAQ9R,IAAI,0BAEZklC,EAAUxN,cAAc,kBACnBK,WAAWhgB,GACXsgB,kBACAjC,WCzDjBv8B,GAAG0kB,OAAS,SAAStJ,EAAMjV,GACvB,YAEA,IACIib,GAAuBhG,EAAKme,cAC5B4d,EAAkB/7B,EAAKoe,aACvBC,EAASre,EAAKqe,OACdC,EAActe,EAAKse,YACnBC,EAAiBve,EAAKue,eAAiB,IACvCyd,EAAoBh8B,EAAKwe,YACzBC,EAAcze,EAAKye,YACnBC,EAAQz5B,KAAKg3C,gBAAgBj8B,EAAK0e,MAGtC95B,IAAG6B,OAAOxB,MAGNmgB,QAASxgB,GAAG8S,kBAAkBsD,SAAW0jB,EAAM/zB,OAAS,EAExDuxC,eAAgB,SAASC,EAAkBC,EAAkBC,GACzD,GAAIt/B,GAAO9X,KACPq3C,KACAC,EAAeF,EAAuBnsC,KAAOmsC,EAAuBnsC,KAAOmsC,CAkD/E,OAjDiB,IAAIz3C,IAAGwxC,SAASmG,EAAcxxC,GAGhC6uC,qBAEXh1C,GAAG+C,KAAK+2B,EAAO,SAAS92B,EAAK40C,GACzB,GAAIC,GAAa1/B,EAAK2/B,sBAClBpe,YAAaA,EACbqe,cAAeH,EAAWr3C,KAC1By3C,QAASL,EAAap3C,MAG1Bm3C,GAAQx0C,MACJoX,KAAMta,GAAGiN,cACTlL,KAAMoW,EAAK8/B,SAAST,GAChBz1C,KAAM61C,EAAW71C,KACjBxB,KAAMs3C,EACNG,QAASL,EAAap3C,OAE1B+K,KAAM,GAAItL,IAAGwX,UAAUmgC,EACvB33C,GAAG4P,KAAKuI,EAAK+/B,qBAAsB//B,GAC/BiJ,qBAAsBA,EACtBF,QAAS02B,EAAW12B,QACpBuY,OAAQA,EACRl5B,KAAMs3C,EACNtzC,QAASo1B,EACTwe,WAAYf,EACZvd,YAAaA,EACb1zB,IAAKA,SAKjBuxC,EAAQx0C,MACJoX,KAAMi9B,EACNx1C,KAAMy1C,EACNj8B,KAAMo8B,EAAap8B,KACnBjQ,KAAM6rC,EAAkBQ,EAAe,QAI3CD,EAAQx0C,MACJoX,KAAMi9B,EACNx1C,KAAMy1C,EACNj8B,KAAMo8B,EAAap8B,KACnBjQ,KAAMqsC,IAIPD,GAGXzd,cAAe,SAASze,EAAMzZ,EAAMuY,EAAMiB,EAAMoU,EAAUlU,EAAS4L,EAAe+wB,GAC9E,GAAIjgC,GAAO9X,KAEPg4C,GADW78B,EAAKmL,YAAenL,EAAKlQ,MAAQkQ,EAAKlQ,KAAKqb,eAEtD2xB,EAAa,KACb7oB,EAAmB2oB,EAAI3oB,iBACvB1P,EAAaq4B,EAAIr4B,WACjB0H,EAAc2wB,EAAI3wB,YAClB/L,EAAe1b,GAAGiN,aAEtBjN,IAAG+C,KAAKoV,EAAKm/B,eAAeh9B,EAAMvY,EAAMyZ,GAAO,SAASxY,EAAKgZ,GACzD,GACI7B,GADAo+B,EAAWv8B,EAAOT,IAGlBS,GAAO1Q,eAAgBtL,IAAGwX,YAC1B+gC,GAAW,GAGfp+B,EAAK4F,EAAW5E,SACZb,KAAM0B,EAAO1B,KACbvY,KAAMia,EAAOja,KACbwZ,KAAMg9B,EACN98B,QAASA,EACTC,aAAcA,IAGdM,EAAO1Q,eAAgBtL,IAAGwX,UAC1B6gC,EAAUn1C,KAAKiX,GAGfm+B,EAAan+B,EAGb6B,EAAO1Q,MACPmkB,EAAiBtV,EAAI6B,EAAO1Q,MAC5BqkB,EAASzsB,MAAMiX,GAAIA,EAAIqB,KAAMQ,EAAO1Q,QAGpCyU,EAAW9D,UAAU9B,EAAIna,GAAGya,OAAO0C,YAOxB,OAAfm7B,IACAt4C,GAAG+C,KAAKs1C,EAAW,SAASr1C,EAAKw1C,GAC7B,GAAIt6B,IACAu6B,aAAc14B,EAAWlE,UAAU1B,GAAIm+B,IAAah+B,KACpDo+B,aAAc34B,EAAWlE,UAAU1B,GAAIm+B,IAAa/8B,KAKxD2C,GAAOmJ,GAAiBtH,EAAWlE,UAAU1B,GAAIq+B,IAAWl+B,KAE5DyF,EAAWlD,YAAY27B,EAAUF,GACjC7wB,EAAY8B,YAAYivB,EAAUt6B,KAKlCm6B,EAAUtyC,QACT,WACG,GAAI4yC,KACJA,GAAMtxB,GAAiBtH,EAAWlE,UAAU1B,GAAIm+B,IAAah+B,KAC7DmN,EAAY8B,YAAY+uB,EAAYK,WAQ5D34C,GAAG6B,OAAO7B,GAAG0kB,OAAOhe,WAChB8d,WAAY,SAASrK,EAAIsK,EAAO2zB,GAC5B,YAEA,KAAKp4C,GAAG8S,kBAAkBsD,QACtB,KAAM,IAAIpW,IAAGwB,MAAM,4CAGvB,IAAIo3C,GAAgB,GAAI54C,IAAG4L,QACvBzF,EAAMiyC,EAAIjyC,IACVqV,EAAO48B,EAAI12B,QAAQvH,GACnB4F,EAAaq4B,EAAIr4B,WAAWlE,UAAU1B,GAAIA,IAC1CpY,EAAOge,GAAcA,EAAWhe,KAChCuY,EAAOyF,GAAcA,EAAWzF,KAChCu+B,GACItf,cAAe9U,EAAM8U,cACrBC,cAAc,EACdC,OAAQhV,EAAMgV,OACdC,YAAajV,EAAMlkB,MAAQ,KAC3Bo5B,eAAgBlV,EAAMlgB,QACtB6yC,kBAAmB,kBACnBtd,QAAS/3B,KAAM,GAAImf,QAASuD,EAAMvD,WAEtC43B,EAAS,GAAI94C,IAAG0kB,OAAOm0B,EAAgB1yC,EAuB3C,OArBKnG,IAAG0kB,QAAW1kB,GAAG8S,kBAAkBgD,eAAkB0F,EAOrDxb,GAAG4P,KAAK,WAEL,GAAIoM,GAAS88B,EAAOxB,eAAeh9B,EAAMvY,EAAMyZ,GAAM,EAEjDQ,IAAUA,EAAO1Q,eAAgBtL,IAAGwX,UACpCwE,EAAO1Q,KAAKqM,SAASb,KAAK8hC,EAAc9sC,QAAS8sC,EAAc5sC,UAG/D7F,EAAIgU,EAAK,4BAA6B,SACtCy+B,EAAc5sC,YAEnB3L,SAjBHu4C,EAAc5sC,UAEd7F,EAAI,iDAAmDgU,EAAK,uFAC6B,UAiBtFy+B,GAKXd,qBAAsB,SAAS18B,GAC3B,YAEA,IAAI28B,GAAgB38B,EAAK28B,cACrBre,EAActe,EAAKse,YACnBqf,EAAgB39B,EAAK48B,OAIzB,OAAKte,IAAgBqe,EAQhBA,GAKD/3C,GAAG2F,QAAQc,OAAOu6B,KAAKhhC,GAAGwxC,SAAS9qC,UAAUuuC,wBAAyB8C,IAAkB,EAClE,eAAlBA,EACO/3C,GAAG8S,kBAAkBuD,aAAe0hC,EAAgBre,EAGxDqe,EATAre,EARe,eAAlBqf,EACO,YAEJA,GAqBfd,SAAU,SAAS38B,EAAc09B,GAC7B,YAEA,IAAIC,GAAa39B,EAAazJ,YAAY,KACtCqnC,EAAcF,EAAwBz4C,MAAQ,YAC9Cw4C,EAAgBC,EAAwBhB,QACxCmB,EAAa,GACbC,EAAYp5C,GAAG0R,aAAa4J,GAC5B+9B,EAAgB,EAmBpB,OAjBIL,GAAwBj3C,MAAQi3C,EAAwBj3C,KAAK8F,OAAO9B,SACpEszC,EAAgB,KAAOL,EAAwBj3C,KAAO,KAGtDk3C,GAAc,GACdE,EAAa79B,EAAaxJ,OAAO,EAAGmnC,GAEhCF,IAAkBG,IAClBE,EAAYF,EAAYxzC,MAAM,KAAK,IAGvCyzC,GAAcE,EAAgB,IAAMD,GAGpCD,EAAa79B,EAAe+9B,EAGzBF,GAIX9B,gBAAiB,SAASvd,GACtB,YAIA,OAFAA,GAAQ95B,GAAG6B,UAAWi4B,GAEfA,EAAMwf,KAAK,SAASC,EAAGC,GAC1B,MAAID,GAAEr4B,QAAUs4B,EAAEt4B,QACP,EAEPq4B,EAAEr4B,QAAUs4B,EAAEt4B,SACP,EAEJ,KAIfg3B,qBAAsB,SAAS98B,EAAMq+B,GACjC,YAEA,IAAIthC,GAAO9X,KACP+gB,EAAuBhG,EAAKgG,qBAC5Bjb,EAAMiV,EAAKjV,IACX+a,EAAU9F,EAAK8F,QACfuY,EAASre,EAAKqe,OACdl5B,EAAO6a,EAAK7a,KACZgE,EAAU6W,EAAK7W,QACf4zC,EAAa/8B,EAAK+8B,WAClBte,EAAcze,EAAKye,aAAmC,eAApB4f,EAAWl5C,MAAkC,eAATA,EACtEq4C,EAAgB,GAAI54C,IAAG4L,QACvB8tC,EAAiB,GAAI15C,IAAG+5B,eAAe5zB,GACvC9B,EAASsF,SAASC,cAAc,SA8BpC,OA5BAzD,GAAI,6CAA+CszC,EAAW13C,MAE9D23C,EAAe93B,SAAS63B,EAAYp1C,GAAS6c,QAASA,EAASuY,OAAQA,EAAQrY,qBAAsBA,IAAuBtK,KAAK,WAC7H,GAAI6iC,GAAqBt1C,EAAOI,UAAUlE,EAAMgE,GAC5Cq1C,EAAgB,WACZzzC,EAAI,yCAA2CszC,EAAW13C,KAC1D,IAAIuJ,GAAOtL,GAAGwE,cAAcm1C,EAC5Bf,GAAc9sC,QAAQR,GAG1BuuB,GACA1hB,EAAK0hC,kBAAkBJ,EAAYE,EAAoBxzC,GAAK2Q,KAAK,SAASgjC,GACtEH,EAAqBG,EACrBF,KAEJ,WACIzzC,EAAI,wFAAyF,SAC7FyzC,MAIJA,KAEL,WACCzzC,EAAI,iDAAmDszC,EAAW13C,KAAM,SACxE62C,EAAc5sC,QAAQmsC,KAGnBS,GAIXiB,kBAAmB,SAASE,EAAeJ,EAAoBxzC,GAC3D,YAEA,IAAI6zC,GAAS,GAAItuC,YACbuuC,EAAkB,GAAIj6C,IAAG4L,QACzBsuC,EAAuB,EAc3B,OAZAF,GAAOnuC,OAAS,WACZquC,EAAuBF,EAAOr3C,OAC9Bs3C,EAAgBnuC,QAAQ9L,GAAGm6C,aAAa/L,QAAQ8L,EAAsBP,KAG1EK,EAAOjuC,QAAU,WACb5F,EAAI,mBAAqB4zC,EAAch4C,KAAO,2DAA4D,SAC1Gk4C,EAAgBjuC,WAGpBguC,EAAOI,cAAcL,GAEdE,GAGXI,eAAgB,SAAS31C,GACrB;YAEA,IAAIE,GAAYE,EAAYH,EAAaE,CAsBzC,OAlBID,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlC7F,KAAKi6C,YAAY31C,EAAaG,IAGzCw1C,YAAa,SAASt1C,EAAMV,GACxB,YAEA,IAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,OChZ3CtE,GAAGm6C,aAAe,WAGjB,GAAIA,KA+KD,OA7KAA,GAAaI,QAAU,oEAMvBJ,EAAaK,SAAW,SAAS9wC,GAE7B,GACI+wC,GAAMC,EACNC,EAAMC,EAAMC,EAFZC,EAAS,GACGC,EAAO,GACDC,EAAO,GACzBtqC,EAAI,CAER,GACI+pC,GAAO/wC,EAAMgH,KACbgqC,EAAOhxC,EAAMgH,KACbqqC,EAAOrxC,EAAMgH,KAEbiqC,EAAOF,GAAQ,EACfG,GAAgB,EAAPH,IAAa,EAAMC,GAAQ,EACpCG,GAAgB,GAAPH,IAAc,EAAMK,GAAQ,EACrCC,EAAc,GAAPD,EAEHE,MAAMP,GACPG,EAAOG,EAAO,GACNC,MAAMF,KACdC,EAAO,IAGVF,EAASA,EACNz6C,KAAKk6C,QAAQ5qC,OAAOgrC,GACpBt6C,KAAKk6C,QAAQ5qC,OAAOirC,GACpBv6C,KAAKk6C,QAAQ5qC,OAAOkrC,GACpBx6C,KAAKk6C,QAAQ5qC,OAAOqrC,GACvBP,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SACvBtqC,EAAIhH,EAAM3D,OAEnB,OAAO+0C,IAGXX,EAAa/L,QAAU,SAAS8M,EAAgBC,GAI5C,IAAKD,EAAe7nC,MAFO,2BAI1B,MAAO8nC,EAGR,IAAIC,GAAW/6C,KAAKg7C,SAASH,EAAe34C,QAPjB,0BAO+C,KACtE+4C,EAAWj7C,KAAKk7C,eAAeH,GAE/BhlB,EAAQ/1B,KAAKm7C,iBAAiBL,EAAmBG,EAErD,OAZ2B,0BAYGj7C,KAAKm6C,SAASpkB,IAKhD+jB,EAAaqB,iBAAmB,SAASL,EAAmBG,GAEpD,GAAIG,GAAYp7C,KAAKq7C,aAAaJ,GAC9BK,EAAgBt7C,KAAKu7C,WAAWT,EAAmBM,EAGvD,OAFc,IAAIz1C,YAAW21C,IAMrCxB,EAAauB,aAAe,SAASJ,GAG7B,IAAK,GADDO,GACKC,EAAI,EAAGA,EAAIR,EAASv1C,OAAQ+1C,IAGjC,GADAD,EAAMP,EAASQ,GACD,KAAVD,EAAI,GAAsB,KAAVA,EAAI,GAEpB,MAAOA,EAGf,WAIR1B,EAAayB,WAAa,SAAST,EAAmBM,GAE9C,GAAIM,GAAYZ,EAAkB54C,QAAQ,0BAA2B,IACjEy5C,EAAM37C,KAAKg7C,SAASU,GACpBE,EAAgBD,EAAIr2C,QAAQ,IAAI,GAChCu2C,EAAMF,EAAI9zC,MAAM,EAAG+zC,GACnBE,EAAMH,EAAI9zC,MAAM+zC,GAChBG,EAAQF,CAIb,OAFCE,GAAQA,EAAMpsC,OAAOyrC,GACrBW,EAAQA,EAAMpsC,OAAOmsC,IAM7BhC,EAAaoB,eAAiB,SAASc,GAKnC,IAHA,GAAIC,GAAO,EACPhB,OAGJ,CACI,GAA2B,KAAvBe,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAAW,KACjE,IAA2B,KAAvBD,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAElDA,GAAQ,MAGZ,CACI,GAAIv2C,GAAmC,IAA1Bs2C,EAAcC,EAAO,GAAWD,EAAcC,EAAO,GAC9DC,EAAWD,EAAOv2C,EAAS,EAC3B81C,EAAMQ,EAAcn0C,MAAMo0C,EAAMC,EACpCjB,GAASp4C,KAAK24C,GACdS,EAAOC,EAEX,GAAID,EAAOD,EAAct2C,OAAQ,MAGrC,MAAOu1C,IAKXnB,EAAakB,SAAW,SAAS3xC,GAE7B,GACI+wC,GAAMC,EACNC,EAAMC,EAAMC,EADAE,EAAO,GACDC,EAAO,GACzBtqC,EAAI,EACJsrC,IAIJ,IADiB,sBACF/3C,KAAKyF,GAChB,KAAM,IAAIlI,OAAM,uHAGpBkI,GAAQA,EAAMnH,QAAQ,sBAAuB,GAE7C,GACIo4C,GAAOt6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCkqC,EAAOv6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCmqC,EAAOx6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCsqC,EAAO36C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MAEzC+pC,EAAQE,GAAQ,EAAMC,GAAQ,EAC9BF,GAAgB,GAAPE,IAAc,EAAMC,GAAQ,EACrCE,GAAgB,EAAPF,IAAa,EAAKG,EAE3BgB,EAAI94C,KAAKu3C,GAEG,IAARI,GACDmB,EAAI94C,KAAKw3C,GAEA,IAARM,GACDgB,EAAI94C,KAAK63C,GAGZN,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SAEvBtqC,EAAIhH,EAAM3D,OAEnB,OAAOi2C,IAIJ7B,KC7KXn6C,GAAGk6B,cAAgB,SAAS7qB,EAAUsT,GAClC,YAEA,IAAI65B,MACAC,EAAc,EACdC,EAAY,EAEZC,GAAiB,EACjBC,GAAgB,EAChBC,EAAgB,SAAS1xB,EAAQC,GACzBD,IAAWwxB,GAAkBvxB,IAAUwxB,GACvCvtC,EAAS8b,EAAQC,GAGrBuxB,EAAiBxxB,EACjByxB,EAAgBxxB,GAQpB0xB,EAAmB,SAAShqB,EAAQiqB,GAChC,GAAIC,IAAO,CASX,OAPAh9C,IAAG+C,KAAK+vB,EAAQ,SAAS9vB,EAAKi6C,GAC1B,GAAIj9C,GAAG2F,QAAQo3C,EAAWE,IAAa,EAEnC,MADAD,IAAO,GACA,IAIRA,GAGXvxB,EAAW,SAAStR,GAChB+iC,EAAoB/iC,GAAI,GAAI,SACrBqiC,GAAgBriC,IAG3B4Y,EAAgB,SAASF,EAAYC,EAAQiqB,IACnB,IAAlBjqB,EAAO/sB,QAAgB+2C,EAAiBhqB,EAAQiqB,MAChDF,EAAcH,EAAWA,GACzBr8C,KAAKwZ,UAIbsjC,EAAQ,SAAShjC,GACb,GAAIoB,GAAOoH,EAAQxI,EAGfoB,GAAO,IACP2hC,EAAoB/iC,EAAI,EAAGoB,GAC3BihC,EAAgBriC,IAAOgR,OAAQ,EAAGC,MAAO7P,KAYjD2hC,EAAsB,SAAS/iC,EAAIijC,EAAWC,GAC1C,GAAIC,GAAYd,EAAgBriC,GAAMqiC,EAAgBriC,GAAIgR,OAAS,EAC/DoyB,EAAWf,EAAgBriC,GAAMqiC,EAAgBriC,GAAIiR,MAAQ,CAE7DgyB,MAAc,GAAMC,KAAa,GACjCZ,GAAea,EACfZ,GAAaa,IAGTH,IACAX,GAAeW,EAAYE,GAE3BD,IACAX,GAAaW,EAAWE,IAIhCV,EAAcJ,EAAaC,GAGnC18C,IAAG6B,OAAOxB,MAEN0yB,cAAeA,EAGfnX,eAAgB,SAASzB,EAAIgC,EAAWD,GAChCA,IAAclc,GAAGya,OAAO4C,UAAYnB,IAAclc,GAAGya,OAAO0C,SAC5DsO,EAAStR,GAEJ+B,IAAclc,GAAGya,OAAOY,YAC7B8hC,EAAMhjC,IAKdsZ,qBAAsB,SAAStZ,EAAIgR,EAAQC,GACvC8xB,EAAoB/iC,EAAIgR,EAAQC,GAChCoxB,EAAgBriC,IAAOgR,OAAQA,EAAQC,MAAOA,IAIlDsK,UAAW,SAASvb,GAChBgjC,EAAMhjC,IAGVN,MAAO,WACH2iC,KACAC,EAAc,EACdC,EAAY,MCzHxB18C,GAAGkoB,aAAe,SAASrQ,GACvB,YAYA,SAAS2lC,GAAQl2C,GACb,MAAOA,GAAK/G,MACwB,IAAhC+G,EAAK/G,KAAKoF,QAAQ,UAG1B,QAAS83C,KACLC,EAAqB19C,GAAGiY,EAAQkQ,eAAe7nB,OAAO,QAAS,SAAS40B,GACpE,GAAIyoB,GAAgBzoB,EAAMyoB,aAEtBA,IACA39C,GAAG+C,KAAK46C,EAAcrzC,MAAO,SAAStH,EAAKsE,GACvC,GAAIk2C,EAAQl2C,GAAO,CACf,GAAIgE,GAAOhE,EAAKs2C,WAChB3lC,GAAQ6O,UAAUuB,cAAc/c,QAOpD,QAASuyC,KACDH,GACAA,IAhCR,GAAIzlC,GAASylC,CAEbzlC,IACIkQ,cAAe,KACfrB,WACI3gB,IAAK,SAASC,EAASC,KACvBgiB,cAAe,SAAS/c,OA8BhCtL,GAAG6B,OAAOoW,EAASJ,GACnB4lC,IAEAz9C,GAAG6B,OAAOxB,MACNwZ,MAAO,WACHgkC,QCpCZ79C,GAAGkwB,YAAc,SAASjY,EAAS6lC,EAAa33C,GAC5C,YAgCA,SAAS43C,GAAqBC,GACtBA,EAAO95C,aAAa,YACpBiU,EAAKoY,YAAcytB,EAAO95C,aAAa,WAM/C,QAAS+5C,GAAaD,EAAQE,GAC1B,IAAIF,EAAOG,eAAkBH,EAAOG,gBAKhC,OAAO,CAJPh4C,GAAI,yDAA0D,SAC9D+3C,IAQR,QAASE,GAAoBJ,GACzB,GAAIE,GAAeF,EAAOK,MAG1Br+C,IAAGg+C,GAAQ19C,OAAO,SAAU,SAAS40B,GACjCA,EAAQA,GAAShwB,OAAOgwB,MAEpBA,EAAMrmB,eACNqmB,EAAMrmB,iBAGNqmB,EAAMnmB,aAAc,EAGxBkvC,EAAaD,EAAQE,IAAiBJ,MAK1CE,EAAOK,OAAS,WACZJ,EAAaD,EAAQE,IAAiBJ,KAM9C,QAASQ,GAAgBN,GAarB,MAZIA,KACIh+C,GAAGwH,SAASw2C,KACZA,EAASr0C,SAASs8B,eAAe+X,IAGjCA,IACA73C,EAAI,8BACJ43C,EAAqBC,GACrB1kB,GAAmB8kB,EAAoBJ,KAIxCA,EAzFX,GAAI7lC,GAAQ9X,KACRi5B,EAAkBrhB,EAAQqhB,gBAC1B0kB,EAAS/lC,EAAQhY,QACjBowB,EAAapY,EAAQoY,UAGzBrwB,IAAG6B,OAAOxB,MAINkwB,YAAa,KAIbD,cAAeD,EAGfF,gBAAgB,EAGhBC,sBAAuB,WAEnB,MAAc,OAAV4tB,EACO,KAGJ7lC,EAAKomC,UAAUP,MAkE9BA,EAASM,EAAgBN,GACzB39C,KAAK8vB,iBAAmB6tB,GAG5Bh+C,GAAG6B,OAAO7B,GAAGkwB,YAAYxpB,WAGrB63C,UAAW,SAASrtC,GAChB,YACA,IAAIf,MACAquC,EAAoB,SAASj+C,GACzB,GAAIk+C,IACA,SACA,QACA,QACA,SAGJ,OAAOz+C,IAAG2F,QAAQ84C,EAAiBl+C,EAAK6I,eAAiB,GAE7Ds1C,EAAkB,SAASn+C,GACvB,MAAOP,IAAG2F,SAAS,WAAY,SAAUpF,EAAK6I,gBAAkB,GAEpEu1C,EAAc,SAAS3O,GACnB,SAAI0O,EAAgB1O,EAAGzvC,OAAUyvC,EAAG4O,UAI7B5O,EAAG98B,UAAsC,WAA1B88B,EAAGzvC,KAAK6I,eAElCy1C,EAAc,SAASC,GACnB,GAAI/3C,GAAQ,IASZ,OAPA/G,IAAG+C,KAAK/C,GAAG8+C,GAAQ17C,WAAY,SAASJ,EAAKK,GACzC,GAAoC,WAAhCA,EAAMiG,QAAQF,eAA8B/F,EAAM07C,SAElD,MADAh4C,GAAQ1D,EAAM0D,OACP,IAIRA,EAmBf,OAhBA/G,IAAG+C,KAAKmO,EAAK8tC,SAAU,SAASh8C,EAAKgtC,GACjC,IAAKhwC,GAAG+I,QAAQinC,GAAI,IAAsC,aAA7BA,EAAG1mC,QAAQF,gBACpCo1C,EAAkBxO,EAAGzvC,OACpBo+C,EAAY3O,IAIZ,GAAiC,WAA7BA,EAAG1mC,QAAQF,gBAA+Bu1C,EAAY3O,GAAK,CAChE,GAAIjpC,GAAQ83C,EAAY7O,EAEV,QAAVjpC,IACAoJ,EAAI6/B,EAAGjuC,MAAQgF,QANnBoJ,GAAI6/B,EAAGjuC,MAAQiuC,EAAGjpC,QAWnBoJ,KCzJfnQ,GAAGgkC,YAAchkC,GAAGgkC,gBACpBhkC,GAAGgkC,YAAY0B,kBAAoB,SAASztB,EAAS6mB,GACjD,YAUA,SAASmgB,GAAqB9kC,EAAI6rB,GAG9B,GAAI7T,GAAU+sB,EAAKC,CAGnB,KAEID,EAAMlZ,EAAOe,iBAAmBf,EAAOoZ,cAAcz1C,SACrDw1C,EAAYD,EAAI5Y,KAAKn3B,UAErBhJ,EAAI,yCACJA,EAAI,eAAiBg5C,GAEjBA,GAAaA,EAAU9rC,MAAM,YAC7B8rC,EAAYD,EAAI5Y,KAAKhjC,WAAWA,WAAW+7C,WAG/CltB,EAAW7C,EAAQoX,mBAAmByY,GAE1C,MAAOh1C,GACHhE,EAAI,wDAA0DgE,EAAM/D,QAAU,IAAK,SACnF+rB,GAAYrmB,SAAS,GAGzB,MAAOqmB,GAMX,QAASmtB,GAAWnlC,EAAI6rB,GACpB,GAAI9nB,GAASjG,EAAQwP,YAAYrF,IAAIjI,GACjC+M,EAA0C,QAAjCjP,EAAQiP,OAAO9d,cAA0B,MAAQ,OAC1D+U,EAAWlG,EAAQyP,cAActF,IAAIjI,GACrCpY,EAAOke,EAAQ9F,EAKnB,OAHA+D,GAAOjG,EAAQsP,UAAYrE,EAAQ/I,GACnC+D,EAAOjG,EAAQ8e,eAAiBh1B,EAEzButB,EAAQ2X,oBACX/f,OAAQA,EACR/I,SAAUA,EACVD,OAAQA,EACRgZ,aAAcjf,EAAQif,aACtBgQ,WAAYlB,EAAOjkC,OArD3B,GAAIutB,GAAUjvB,KACV4f,EAAU6e,EAAM7e,QAChBiD,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,GAsDhB9F,MAAKsjC,WAAa,SAASxpB,GACvB,GAGIjJ,GAHAxH,EAAQ4lB,EAAQ/V,SAASY,GACzB6rB,EAAS1W,EAAQ0X,cAAc7sB,GAC/BxO,EAAU,GAAI3L,IAAG4L,OA8BrB,OA3BAsF,GAAOouC,EAAWnlC,EAAI6rB,GACtB90B,EAAKE,YAAY1H,GAEjB4lB,EAAQuX,iBAAiBb,EAAQ,SAASuZ,GACtCp5C,EAAI,gBAEJ,IAAIgsB,GAAWotB,EAAsBA,EAAsBN,EAAqB9kC,EAAI6rB,EAEpF1W,GAAQqX,iBAAiBxsB,GAGpBlC,EAAQ0P,KAAK8I,UACdzwB,GAAGgmC,GAAQ5kC,SAGX+wB,EAASrmB,QACTH,EAAQG,QAAQqmB,GAGhBxmB,EAAQK,QAAQmmB,KAIxBhsB,EAAI,8BAAgCgU,GACpCjJ,EAAKmtC,SACLr+C,GAAGkR,GAAM9P,SAEFuK,GAGX3L,GAAG6B,OAAOxB,KAAM,GAAIL,IAAG0lC,mBACnBztB,SACI4tB,OAAQ5tB,EAAQ0P,KAAK8I,SACrBjG,UAAWvS,EAAQuS,WAGvBsU,OACIrT,SAAUxT,EAAQwT,SAClBxL,QAASA,EACTiD,QAASA,EACT/c,IAAKA,OC5GjBnG,GAAGgkC,YAAchkC,GAAGgkC,gBACpBhkC,GAAGgkC,YAAYoD,iBAAmB,SAAShsB,EAAM0jB,GAC7C,YAEA,IAAIxP,GAAUjvB,KACV4f,EAAU6e,EAAM7e,QAChB0C,EAAUmc,EAAMnc,QAChBO,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,IACZq5C,EAAYpkC,EAAK4b,gBAAkB5b,EAAK8b,aAExCuoB,EAA4B,SAAStlC,EAAI+D,EAAQgO,GAC7C,GAAI3Q,GAAOoH,EAAQxI,GACfpY,EAAOke,EAAQ9F,EAEdiB,GAAK6b,oBACN/Y,EAAO9C,EAAK/F,SAASojB,WAAWpM,WAAaH,EAAUsd,KACvDtrB,EAAO9C,EAAK/F,SAASojB,WAAWC,gBAAkBxM,EAAUphB,MAC5DoT,EAAO9C,EAAK/F,SAASojB,WAAWE,WAAazM,EAAU3Q,KACvD2C,EAAO9C,EAAK/F,SAASojB,WAAWI,YAAc3M,EAAUud,MACxDvrB,EAAO9C,EAAKgc,mBAAqB7b,GAOjCikC,IAAcpkC,EAAK6b,oBACnB/Y,EAAO9C,EAAK2b,eAAiBh1B,IAIrC29C,EAAyB,GAAI1/C,IAAGgkC,YAAY2b,4BACxCh4B,KAAMvM,EAAKuM,KACXxJ,SAAU/C,EAAK/F,SAASvJ,QAAQqS,SAChCyG,QAASxJ,EAAK/F,SAASvJ,QAAQ8Y,QAC/BmU,YAAa3d,EAAK/F,SAASvJ,QAAQitB,YACnC5yB,IAAKA,EACL+gB,OAAQ9L,EAAK/F,SAASvJ,QAAQob,OAC9BhJ,OAAQ9C,EAAK/F,SAASvJ,QAAQoS,SAGlC0hC,EAAiC,SAASzlC,EAAIoR,GAC1C,GAAI5f,GAAU,GAAI3L,IAAG4L,OAerB,OAbA2f,GAAI2Q,mBAAqB,WACrB,GAAuB,IAAnB3Q,EAAIqR,WAAkB,CACtB,GAAIj6B,GAASk9C,EAAwB1lC,EAAIoR,EAErC5oB,GAAOmJ,QACPH,EAAQG,QAAQnJ,EAAOwvB,SAAU5G,GAGjC5f,EAAQK,QAAQrJ,EAAOwvB,SAAU5G,KAKtC5f,GAGXm0C,EAA0B,SAAS3lC,GAC/B,GAAI+D,GAAS9C,EAAKqM,YAAYrF,IAAIjI,GAC9BpY,EAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,EAOnB,OALA+D,GAAO9C,EAAKmM,UAAYrE,EAAQ/I,GAChC+D,EAAO9C,EAAK2b,eAAiBh1B,EAC7Bmc,EAAO9C,EAAKgc,mBAAqB7b,EACjC2C,EAAO9C,EAAK/F,SAASojB,WAAWI,YAAcvJ,EAAQsS,gBAAgBznB,GAE/D+D,GAGX6hC,EAAwB,SAASx0B,EAAK4G,GAClC,MAAOnyB,IAAG2F,SAAS,IAAK,IAAK,IAAK,IAAK,KAAM4lB,EAAI9Q,QAAU,GACtDW,EAAK+b,qBAAuBhF,EAASrmB,SACtCqmB,EAAStY,OAGjBgmC,EAA0B,SAAS1lC,EAAIoR,GACnC,GAAI4G,EAOJ,OALAhsB,GAAI,sCAAwCgU,GAC5ChU,EAAI,kBAAoBolB,EAAI2rB,cAE5B/kB,EAAW6tB,GAAc,EAAMz0B,IAG3Bzf,SAAUi0C,EAAsBx0B,EAAK4G,GACrCA,SAAUA,IAKlB6tB,EAAgB,SAASh2C,EAAQuhB,GAC7B,GAAI4G,KAEJ,KACIhsB,EAAInG,GAAG8H,OAAO,4CAA6CyjB,EAAI9Q,OAAQ8Q,EAAI2rB,eAC3E/kB,EAAWnyB,GAAGqR,UAAUka,EAAI2rB,cAEhC,MAAO/sC,GACHH,GAAUoR,EAAK+b,oBAAsBhxB,EAAI,qDAAuDgE,EAAM/D,QAAU,IAAK,SAGzH,MAAO+rB,IAGX8tB,EAA4B,SAAS9lC,GACjC,GAAIxO,GAAU,GAAI3L,IAAG4L,OAcrB,OAZA8zC,GAAuBQ,SACf/lC,EACAmV,EAAQ2Z,WAAW9uB,GACnB2lC,EAAwB3lC,GACxBiB,EAAKoM,cAAcpF,IAAIjI,IAE1BrD,KAAK,SAASyU,GACX5f,EAAQG,QAAQk0C,GAAc,EAAOz0B,GAAMA,IAC5C,SAASA,GACR5f,EAAQK,QAAQg0C,GAAc,EAAOz0B,GAAMA,KAG5C5f,GAGXw0C,EAA8B,SAASC,GACnC,GAOIliC,GAPArT,EAAau1C,EAAmBv1C,WAChCsP,EAAKimC,EAAmBjmC,GACxBoR,EAAM60B,EAAmB70B,IACzB80B,EAAeD,EAAmBC,iBAClCC,EAAeF,EAAmBE,iBAClCC,EAAgBH,EAAmBliC,WACnCsiC,EAAoBH,EAAaniC,WAGjCnN,EAAWyuC,EAAY,GAAI11C,UAAa,KACxCod,EAASm5B,EAAan5B,QAAU9L,EAAK8L,OACrC/I,EAAWkiC,EAAaliC,UAAY/C,EAAKsM,cAActF,IAAIjI,GAC3DpY,EAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,EAiCnB,OA/BIiB,GAAK6b,mBACL/Y,EAASle,GAAG6B,UAAWy+C,GACvBtgD,GAAG6B,OAAOqc,EAAQsiC,KAGlBtiC,EAASle,GAAG6B,UAAWy+C,GACvBtgD,GAAG6B,OAAOqc,EAAQsiC,GAClBxgD,GAAG6B,OAAOqc,EAAQqiC,GAElBriC,EAAO9C,EAAKmM,UAAYrE,EAAQ/I,GAChC+D,EAAO9C,EAAK2b,eAAiBh1B,EAEzBy9C,EACAthC,EAAO9C,EAAKgc,mBAAqB7b,EAE3BH,EAAK8b,eACXhZ,EAAO9C,EAAKoP,WAAazoB,IAK5BqZ,EAAK8b,eACN/Y,EAAWne,GAAGkQ,QAAQgO,EAAQC,IAGlCoN,EAAI8Q,KAAKnV,EAAQ/I,GAAU,GAEvB/C,EAAKuM,KAAK8I,UAAYrV,EAAKuM,KAAK0R,kBAChC9N,EAAIhY,iBAAkB,GAGtBisC,GACIpkC,EAAK8b,cACLl3B,GAAG8Q,aAAaoN,EAAQnN,GAG5BA,EAASxL,OAAO6V,EAAKoP,UAAW3f,GACzBkG,GAGJlG,GAGX41C,EAAmB,SAASC,GACxB,GAAIC,GAAkBD,EAAeC,gBACjCxmC,EAAKumC,EAAevmC,GACpBoR,EAAMm1B,EAAen1B,GAEzB,IAAIo1B,EACA3gD,GAAG+C,KAAK49C,EAAiB,SAASC,EAAYC,GAC1Ct1B,EAAI2R,iBAAiB0jB,EAAYC,SAGpC,CACD,GAAIC,GAAe1lC,EAAKoM,cAAcpF,IAAIjI,GACtCtP,EAAaykB,EAAQ5N,QAAQvH,EAEjCoR,GAAI2R,iBAAiB,SAAU,oBAC/B3R,EAAI2R,iBAAiB,mBAAoB,kBACzC3R,EAAI2R,iBAAiB,gBAAiB,YAEjCsiB,IACDj0B,EAAI2R,iBAAiB,eAAgB,4BAErC3R,EAAI2R,iBAAiB,cAAeryB,EAAWtK,OAGnDP,GAAG+C,KAAK+9C,EAAc,SAAS/+C,EAAMkB,GACjCsoB,EAAI2R,iBAAiBn7B,EAAMkB,MAK3CjD,IAAG6B,OAAOxB,MACN+hC,YAAa,SAAS2e,GAClB,GAOIp1C,GAASq1C,EAAQV,EAPjBnmC,EAAK4mC,EAAkB5mC,GACvBwlB,EAAWohB,EAAkBphB,SAC7BwC,EAAY4e,EAAkB5e,cAC9BjJ,EAAW6nB,EAAkB7nB,SAE7BhN,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCpU,EAAM+D,EAAQ2Z,WAAW9uB,EAAIwlB,GACEzhB,IA4BnC,OA1BAvS,GAAUi0C,EAA+BzlC,EAAIoR,GAC7C+D,EAAQ+a,yBAAyBlwB,EAAIwlB,EAAUzT,EAAU3Q,MACzD+kC,EAAellC,EAAKqM,YAAYrF,IAAIjI,GACpCslC,EAA0BtlC,EAAI+D,EAAQgO,GAElCgN,IACAhb,EAAO9C,EAAKjF,OAAOsiB,WAAWS,WAAY,GAG9C8nB,EAASb,GACLt1C,WAAYqhB,EAAU5gB,KACtB6O,GAAIA,EACJmmC,aAAcA,EACdpiC,OAAQA,EACRqN,IAAKA,EACL80B,aAAcle,IAGlBse,GACIE,gBAAiBxe,EAAUvd,QAC3BzK,GAAIA,EACJoR,IAAKA,IAGTA,EAAIgR,KAAKykB,GAEFr1C,GAGXg4B,WAAY,SAASxpB,GACjB,GACIxO,GAAS4f,EAAK+0B,EAAcU,EAD5Bn2C,EAAaykB,EAAQ5N,QAAQvH,EAsBjC,OAnBAoR,GAAM+D,EAAQ2Z,WAAW9uB,GACzBmV,EAAQ+a,yBAAyBlwB,GACjCxO,EAAUi0C,EAA+BzlC,EAAIoR,GAC7C+0B,EAAellC,EAAKqM,YAAYrF,IAAIjI,GAEpC6mC,EAASb,GACLt1C,WAAYA,EACZsP,GAAIA,EACJmmC,aAAcA,EACd/0B,IAAKA,IAGTk1B,GACItmC,GAAIA,EACJoR,IAAKA,IAGTA,EAAIgR,KAAKykB,GAEFr1C,KAIf3L,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGonC,kBACnBnvB,QAASjY,GAAG6B,QAAQipB,UAAW,eAAgB1P,GAC/C0jB,MAAO9+B,GAAG6B,QAAQqgB,YAAa9G,EAAKsM,cAActF,KAAM0c,MAG5D9+B,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OACIyzB,eAAgB,SAAS9lB,GAGrB,MAFA2kB,GAAMmF,aAAa9pB,GAEfiB,EAAK/F,SAASvJ,QAAQqS,SACf8hC,EAA0B9lC,GAG1B3N,EAAOyzB,eAAe9lB,EAAIna,GAAG4P,KAAKowC,EAAe3/C,MAAM,SCzSlFL,GAAGgkC,YAAY2b,2BAA6B,SAAS9nC,GACjD,YAEA,IAAIwzB,GACApzB,GACI0P,MACI+I,UAAU,EACVD,UAAU,EACV4I,iBAAiB,GAErBlb,SAAU,KACVhY,IAAK,SAAS4B,EAAK1B,KACnB6gB,OAAQ,QAEZ+5B,KACAC,GACI9+B,IAAK,SAASjI,GACV,MAAIna,IAAG6G,WAAWoR,EAAQkG,UACflG,EAAQkG,SAAShE,GAGrBlC,EAAQkG,UAI3Bne,IAAG6B,OAAOoW,EAASJ,GAEnBwzB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdR,YAAaxkB,EAAQ8gB,YAAc,mBAAqB,oCACxDwE,cAAetlB,EAAQiP,QACvBA,OAAQjP,EAAQiP,OAChBQ,cAAew5B,EACf/jB,oCAAoC,EACpCxV,KAAM1P,EAAQ0P,KACdxhB,IAAK8R,EAAQ9R,IACbmlB,WAAY,SAASnR,EAAIoR,EAAKvD,GAC1B,GAAIrc,GAAUs1C,EAAS9mC,SAEhB8mC,GAAS9mC,GAEZ6N,EACArc,EAAQK,QAAQuf,GAGhB5f,EAAQG,QAAQyf,OAK5BvrB,GAAG6B,OAAOxB,MACN6/C,SAAU,SAAS/lC,EAAIoR,EAAKrN,EAAQ0G,GAChC,GAAIjZ,GAAU,GAAI3L,IAAG4L,OAWrB,OATAqM,GAAQ9R,IAAI,0CAA4CgU,GAExD8mC,EAAS9mC,GAAMxO,EAEf0/B,EAAUxN,cAAc1jB,GACnB+jB,WAAWjmB,EAAQiG,OAAO/D,IAAO+D,GACjCmgB,YAAYpmB,EAAQ2M,QAAQzK,IAAOyK,GACnC2X,KAAKhR,GAEH5f,MCtEnB3L,GAAGmhD,YAAc,SAAStpC,GACtB,YAoBA,SAASupC,GAAmB1hC,EAAO2hC,GAE/B,GAAIC,GAAer5C,MAAMvB,UAAUwB,MAAMtB,KAAK8Y,EAE9CzH,GAAQ6O,UAAUy6B,QAAQ,WAAa7hC,EAAM3Z,OAAS,mBACtDs7C,EAAeG,cAAa,GAC5BvpC,EAAQ6O,UAAU26B,+BAA+BH,EAAcD,EAAeK,cAGlF,QAASC,GAAiBxnB,GACtB,GAAIynB,GAAoB,GAAI5hD,IAAG4L,OAwC/B,OAtCIuuB,GAAM5xB,OACN4xB,EAAM3e,KAAK,SAASA,GAChBA,EAAKqmC,OAASC,EAAqB3nB,GACnC4nB,EAAa7+C,KAAKsY,GAClBomC,EAAkB91C,WAEtB,SAASk2C,GACL/pC,EAAQ6O,UAAUy6B,QAAQ,oBAAsBpnB,EAAM8nB,SAAW,sBAAwBD,EAAUjxB,KAAO,IAAK,SAC/G6wB,EAAkB51C,YAGjBmuB,EAAM+nB,aACXC,EAAoBhoB,GAAOrjB,KACvB,SAAwBoD,GACpB,GAAIkoC,GAAcloC,EAAQnU,MAE1B/F,IAAG+C,KAAKmX,EAAS,SAASlX,EAAKm3B,GAC3BwnB,EAAiBxnB,GAAO5iB,KAAK,WACzB6qC,GAAe,EAEK,IAAhBA,GACAR,EAAkB91C,cAKzBoO,EAAQnU,QACT67C,EAAkB91C,WAI1B,SAAqBk2C,GACjB/pC,EAAQ6O,UAAUy6B,QAAQ,oBAAsBpnB,EAAM8nB,SAAW,sBAAwBD,EAAUjxB,KAAO,IAAK,SAC/G6wB,EAAkB51C,YAKvB41C,EAGX,QAASE,GAAqB3nB,GAC1B,GAAIp4B,GAAOo4B,EAAMp4B,KACbkgD,EAAW9nB,EAAM8nB,SACjBI,EAAwBJ,EAASpwC,YAAY9P,EAUjD,OAPAkgD,GAAWA,EAASnwC,OAAO,EAAGuwC,GAGH,MAAvBJ,EAAStyC,OAAO,KAChBsyC,EAAWA,EAASnwC,OAAO,IAGxBmwC,EAIX,QAASE,GAAoBhoB,EAAO6f,EAAQsI,EAAcC,GACtD,GAAI52C,GAAU42C,GAAmB,GAAIviD,IAAG4L,QACpC42C,EAAYxI,GAAU7f,EAAMsoB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqBxoC,GACjB,GAAIyoC,GAAaL,EAAeA,EAAatyC,OAAOkK,GAAWA,CAE3DA,GAAQnU,OACR4jB,WAAW,WACPw4B,EAAoBhoB,EAAOqoB,EAAWG,EAAYh3C,IACnD,GAGHA,EAAQG,QAAQ62C,IAIxBh3C,EAAQK,SAGLL,EAGX,QAASi3C,GAAmBv4C,EAAcg3C,GACtC,GAAIwB,MACAC,EAA4B,GAAI9iD,IAAG4L,OA4CvC,OA1CAqM,GAAQ6O,UAAUi8B,yBAClB1B,EAAeG,cAAa,GAExBn3C,EAAaqV,MAAM3Z,OAAS,IAAMkS,EAAQ+qC,oBAC1C/qC,EAAQ6O,UAAU26B,mCAClBxpC,EAAQ6O,UAAUm8B,UAAU,oBAAqB,IACjD5B,EAAeG,cAAa,GAC5BsB,EAA0B92C,YAG1B+1C,KAEI/hD,GAAGoK,sBAAsBC,GACzBrK,GAAG+C,KAAKsH,EAAaC,MAAO,SAAStH,EAAKsE,GACtC,GAAI6yB,GAAQ7yB,EAAKiD,kBAEb4vB,KAEIA,EAAM5xB,OACNw5C,EAAa7+C,KAAKoE,EAAKs2C,aAIvBiF,EAAsB3/C,KAAKy+C,EAAiBxnB,GAAO5iB,KAAK,WACpDsrC,EAAsBrf,MACe,IAAjCqf,EAAsB98C,QACtB+8C,EAA0Bh3C,gBAQ9Ci2C,EAAe13C,EAAaqV,MAGK,IAAjCmjC,EAAsB98C,QACtB+8C,EAA0Bh3C,WAI3Bg3C,EAGX,QAASI,GAAcC,GACnB,GAAIC,GAAW,GAAIpjD,IAAGqjD,gBAClBC,sBAlKoB,eAmKpBrjD,QAASkjD,EACTI,QAAS,SAASz0C,GACd9O,GAAGmjD,GAAU9gD,SAAS4V,EAAQmS,QAAQo5B,YACtC10C,EAAE20C,mBAENC,sBAAuB,SAAS50C,GAC5B9O,GAAGmjD,GAAU7gD,YAAY2V,EAAQmS,QAAQo5B,aAE7CG,OAAQ,SAAS70C,GACb8zC,EAAmB9zC,EAAEzE,aAAc+4C,GAAUtsC,KACzC,WACIsqC,EAAmBW,EAAcqB,IAErC,WACInrC,EAAQ6O,UAAUy6B,QAAQ,sEAAuE,aAcjH,OARAvoC,GAAezG,YAAY,WACvB6wC,EAAShxC,YAGbpS,GAAGmjD,GAAUr/C,aA1LY,qBA0L4B9D,GAAGmjD,GAAUjjD,OAElE0jD,EAAgB1gD,KAAKkgD,GAEdA,EAGX,QAASS,GAAWC,GAChB,GAAIC,EASJ,OAPA/jD,IAAG+C,KAAK+gD,EAAUz5C,aAAa25C,MAAO,SAASv0C,EAAKxM,GAChD,GAAY,UAARA,EAEA,MADA8gD,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBn1C,GACxB,MAAI9O,IAAG6N,SACIiB,EAAEgtC,EAAI,GAAKhtC,EAAEo1C,EAAI,EAGb,IAARp1C,EAAEgtC,GAAmB,IAARhtC,EAAEo1C,EAG1B,QAASC,KACL,GAAIC,GAAYnsC,EAAQosC,iBAEpBC,EAAqB,WACjB36B,WAAW,WACP3pB,GAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAC7BpjD,GAAGojD,GAAUt/C,aApOJ,qBAoO4C9D,GAAGojD,GAAUljD,OAClEF,GAAGojD,GAAU9gD,YAAY2V,EAAQmS,QAAQo5B,eAE9C,IAGXxjD,IAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAC7B,GAAI/B,GAAiB6B,EAAcE,EAG/BgB,GAAUr+C,QAAU/F,GAAG8S,kBAAkB6C,UACzCqD,EAAe1Y,OAAOqJ,SAAU,YAAa,SAASmF,IAC7CuyC,EAAeG,gBAAkBqC,EAAW/0C,IAC7C9O,GAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAGzBA,YAAoBmB,cACpBvkD,GAAGojD,GAAUt/C,aArPZ,qBAuPD9D,GAAGojD,GAAU9hD,KAAKlB,QAAS,gBAQnD4Y,EAAe1Y,OAAOqJ,SAAU,YAAa,SAASmF,GAC9Cm1C,EAAmBn1C,IACnBw1C,MAORtrC,EAAe1Y,OAAON,GAAG2J,UAAUvG,WAAW,GAAI,aAAc,SAAS0L,GACrEw1C,MAGJtrC,EAAe1Y,OAAOqJ,SAAU,OAAQ,SAASmF,GACzC+0C,EAAW/0C,KACXA,EAAED,iBACFy1C,OAIRtrC,EAAe1Y,OAAOqJ,SApRE,eAoR+B26C,GArR3D,GAAIrsC,GAGA2rC,KACA7B,KACA/oC,EAAiB,GAAIhZ,IAAGkS,cAE5B+F,IACIosC,oBACArB,oBAAoB,EACpB54B,SACIo5B,WAAY,MAEhB18B,UAAW,GAAI9mB,IAAGmhD,YAAYr6B,WAGlC9mB,GAAG6B,OAAOoW,EAASJ,GAAG,GAwQtBssC,IAEAnkD,GAAG6B,OAAOxB,MACNmkD,mBAAoB,SAASvkD,GACzBgY,EAAQosC,iBAAiBnhD,KAAKjD,GAC9BijD,EAAcjjD,IAGlBwkD,eAAgB,SAASxkD,GACrB,GAAIyQ,GACAg0C,EAAMzsC,EAAQosC,gBAElB,KAAK3zC,IAAKg0C,GACN,GAAIA,EAAIh0C,KAAOzQ,EACX,MAAOykD,GAAIroC,OAAO3L,EAAG,IAKjC0B,QAAS,WACL4G,EAAe5G,UACfpS,GAAG+C,KAAK6gD,EAAiB,SAAS5gD,EAAKogD,GACnCA,EAAShxC,eAKrB/R,KAAKmyC,YACLnyC,KAAKmyC,SAASsP,qBAAuBA,GAGzC9hD,GAAGmhD,YAAYr6B,UAAY,WACvB,YAEA,QACIi8B,uBAAwB,aACxBtB,+BAAgC,SAAS/hC,EAAOilC,KAChD1B,UAAW,SAASlyB,EAAM6zB,GACtB5kD,GAAGmG,IAAI,2BAA6B4qB,EAAO,2BAA6B6zB,EAAiB,IAAK,UAElGrD,QAAS,SAASn7C,EAASC,GACvBrG,GAAGmG,IAAIC,EAASC,MAK5BrG,GAAGqjD,eAAiB,SAASxrC,GACzB,YAiBA,SAASgtC,KACL,MAAO7kD,IAAG6N,UAAa7N,GAAGiO,WAAajO,GAAGkO,UAG9C,QAAS42C,GAAmBh2C,GAEnBi2C,IAGGF,EACA7rC,EAAe1Y,OAAOqJ,SAAU,WAAY,SAASmF,GACjDA,EAAED,mBAGNmK,EAAe1Y,OAAOqJ,SAAU,WAAY,SAASmF,GAC7CA,EAAEzE,eACFyE,EAAEzE,aAAa26C,WAAa,OAC5Bl2C,EAAED,oBAKdk2C,GAAsB,GAI9B,QAASE,GAAgBn2C,GAGrB,IAAK9O,GAAG8S,kBAAkB6C,SACtB,OAAO,CAGX,IAAIuvC,GAAYC,EAAKr2C,EAAEzE,aAEvB+6C,EAAWplD,GAAG6N,QAOd,OADAq3C,MAAallD,GAAGqN,OAAQrN,GAAG8S,kBAAkB6C,WAAuC,SAArBwvC,EAAGE,cAC3DF,GAAMD,IAEAC,EAAGzlC,OAASylC,EAAGzlC,MAAM3Z,SACpBq/C,GAAYD,EAAGnB,MAAMljD,UAAYqkD,EAAGnB,MAAMljD,SAAS,UACpDqkD,EAAGnB,MAAMsB,UAAYH,EAAGnB,MAAMsB,SAAS,UAIxD,QAASC,GAAoBC,GAIzB,MAHmBrhD,UAAfqhD,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiBj8C,SAASk8C,YAAY,SACtCD,EAAeE,UAAU7tC,EAAQqrC,uBAAuB,GAAM,GAJlE,GAAIsC,EAOJ,IAAI1gD,OAAO6gD,YACP,IACIH,EAAiB,GAAIG,aAAY9tC,EAAQqrC,uBAE7C,MAAO1M,GACH+O,QAIJA,IAGJh8C,UAASq8C,cAAcJ,GAG3B,QAASK,KACLjtC,EAAe1Y,OAAOL,EAAS,WAAY,SAAS6O,GAChD,GAAKm2C,EAAgBn2C,GAArB,CAMA,GAAIo3C,GAASlmD,GAAGqN,MAAQrN,GAAG8S,kBAAkB6C,SAAW,KAAO7G,EAAEzE,aAAag7C,aAE1Ev2C,GAAEzE,aAAa26C,WADJ,SAAXkB,GAAgC,aAAXA,EACO,OAEA,OAGhCp3C,EAAE20C,kBACF30C,EAAED,oBAGNmK,EAAe1Y,OAAOL,EAAS,YAAa,SAAS6O,GACjD,IAAKy2C,IAAuB,CACxB,IAAKN,EAAgBn2C,GACjB,MAEJmJ,GAAQsrC,QAAQz0C,MAIxBkK,EAAe1Y,OAAOL,EAAS,YAAa,SAAS6O,GACjD,GAAKm2C,EAAgBn2C,GAArB,CAIAmJ,EAAQkd,QAAQrmB,EAEhB,IAAIq3C,GAAgBx8C,SAASy8C,iBAAiBt3C,EAAEu3C,QAASv3C,EAAEw3C,QAEvDtmD,IAAGK,MAAMS,SAASqlD,IAItBluC,EAAQyrC,sBAAsB50C,MAGlCkK,EAAe1Y,OAAOL,EAAS,OAAQ,SAAS6O,GAC5C,IAAKy2C,IAAuB,CACxB,IAAKN,EAAgBn2C,GACjB,MAGJA,GAAED,iBACFC,EAAE20C,kBACFxrC,EAAQ0rC,OAAO70C,GAEf42C,OArJZ,GACIztC,GAAShY,EAASwlD,EAAaV,EAD/B/rC,EAAiB,GAAIhZ,IAAGkS,cAG5B+F,IACIhY,QAAS,KACTsjD,QAAS,SAASz0C,KAClBqmB,QAAS,SAASrmB,KAElB40C,sBAAuB,SAAS50C,KAChC60C,OAAQ,SAAS70C,MAGrB9O,GAAG6B,OAAOoW,EAASJ,GACnB5X,EAAUgY,EAAQhY,QA6IlB6kD,IACAmB,IAEAjmD,GAAG6B,OAAOxB,MACNmhD,aAAc,SAASgE,GACnB,MAAOD,GAAoBC,IAG/BpzC,QAAS,WACL4G,EAAe5G,WAGnBsvC,WAAY,WACR,MAAOzhD,MAIfI,KAAKmyC,YACLnyC,KAAKmyC,SAASyS,gBAAkBA,GCrfnC,WACG,YAEAjlD,IAAGumD,aACCloC,gBAAiB,SAASC,GACtBje,KAAKmmD,QAAQ9/C,UAAU2X,gBAAgBpO,MAAM5P,KAAM8H,WACnD9H,KAAKomD,YAAYC,iBAGrBpmC,iBAAkB,WACdjgB,KAAKmmD,QAAQ9/C,UAAU4Z,iBAAiBrQ,MAAM5P,KAAM8H,WACpD9H,KAAKomD,YAAYE,cAGrBC,iBAAkB,SAAS3mD,GACvBI,KAAKwmD,MAAQxmD,KAAKwmD,KAAKrC,mBAAmBvkD,IAG9C6mD,oBAAqB,SAAS7mD,GAC1B,GAAII,KAAKwmD,KACL,MAAOxmD,MAAKwmD,KAAKpC,eAAexkD,IAIxC8mD,gBAAiB,SAAS5sC,GACtB,IAAK9Z,KAAKomD,YAAYO,gBAAgB7sC,GAClC,MAAO9Z,MAAKomD,YAAYQ,iBAAiB9sC,IAIjDN,MAAO,WACHxZ,KAAKmmD,QAAQ9/C,UAAUmT,MAAM5J,MAAM5P,KAAM8H,WACzC9H,KAAKomD,YAAY5sC,SAEZxZ,KAAKye,SAAS8E,QAAUvjB,KAAKomD,YAAY1kC,cAC1C1hB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKomD,YAAY1kC,YAC1B7J,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGHnZ,KAAKwmD,OACLxmD,KAAKwmD,KAAKz0C,UACV/R,KAAKwmD,KAAOxmD,KAAK6mD,qBAGrB7mD,KAAK8mD,mBAAqB,EAC1B9mD,KAAK+mD,uBAAyB,EAE9B/mD,KAAKgnD,mCAGTzhC,QAAS,SAASzL,EAAIuC,GAClB,GAAI4qC,GAAoBjnD,KAAKye,SAAS0S,eAAe9U,EAErDrc,MAAKmmD,QAAQ9/C,UAAUkf,QAAQ3V,MAAM5P,KAAM8H,WAC3C9H,KAAKomD,YAAYc,eAAeptC,EAAImtC,IAGxChkC,YAAa,SAASnJ,GAClB,GAAIyuB,GAASvoC,KAAKmmD,QAAQ9/C,UAAU4c,YAAYrT,MAAM5P,KAAM8H,UAG5D,OADAygC,IAAUvoC,KAAKomD,YAAYe,aAAartC,GACjCyuB,GAGXroB,eAAgB,SAASpG,GACrB,GAAIstC,GAAYpnD,KAAKmmD,QAAQ9/C,UAAU6Z,eAAetQ,MAAM5P,KAAM8H,UAGlE,OADAs/C,IAAapnD,KAAKomD,YAAYiB,gBAAgBvtC,GACvCstC,GAGXE,MAAO,SAASC,GACZ,MAAOvnD,MAAKomD,YAAYoB,UAAUD,IAGtCE,cAAe,SAAS9mC,GAGpB,MAFW3gB,MAAKqhB,QAAQV,GAEZ+mC,eAOpB/nD,GAAGgoD,cACChmC,WAAY,SAAShK,GACjB,GAAI4L,GAASvjB,KAAKmmD,QAAQ9/C,UAAUsb,WAAW/R,MAAM5P,KAAM8H,UAQ3D,OANKyb,IACG5L,IAAa3X,KAAK6tB,mBAClBtK,EAASvjB,KAAKomD,YAAY1kC,aAI3B6B,GAGXqkC,gBAAiB,SAASjnC,GACtB3gB,KAAKomD,YAAYyB,WAAWlnC,IAGhCqmC,gCAAiC,WAC7BhnD,KAAK8nD,yBAA2BnoD,GAAGooD,yBAA2B/nD,KAAKgoD,6BAInEhoD,KAAKioD,wBAA0BtoD,GAAGiO,UAE9B5N,KAAKkoD,2BAELloD,KAAKmoD,sBAAwBnoD,KAAKooD,0BAClCpoD,KAAKqoD,6BAA+BroD,KAAKsoD,iCACzCtoD,KAAKuoD,2BAA6BvoD,KAAKwoD,iCAI/C3B,kBAAmB,WACf,GAAI/uC,GAAO9X,KACPgkD,EAAmBhkD,KAAKye,SAASgqC,YAAYC,eAC7CC,EAAa3oD,KAAKomD,YAClBwC,EAAkBD,EAAWE,aAIjC,OAFAD,IAAmB5E,EAAiBnhD,KAAK+lD,GAElC,GAAIjpD,IAAGmhD,aACVkD,iBAAkBA,EAClBrB,mBAAoB3iD,KAAKye,SAASjV,SAClCugB,SACIo5B,WAAYnjD,KAAKye,SAASsL,QAAQo5B,YAEtC18B,WACIi8B,uBAAwB,WACpBiG,EAAWG,sBAEf1H,+BAAgC,SAAS/hC,EAAOilC,GAC5CqE,EAAWI,qBAEXppD,GAAG+C,KAAK2c,EAAO,SAAS1c,EAAKwY,GACzBA,EAAKusC,aAAepD,IAGpBjlC,EAAM3Z,QACNoS,EAAKiG,SAASsB,EAAO,KAAM,OAGnCujC,UAAW,SAASlyB,EAAMs4B,GACtBlxC,EAAK+N,WAAW6K,EAAMs4B,IAE1B9H,QAAS,SAASn7C,EAASC,GACvB8R,EAAKhS,IAAIC,EAASC,QAMlCgiD,2BAA4B,WACxB,GAAIlwC,GAAO9X,IAEX,OAAO,IAAIL,IAAGooD,yBACVY,WAAY3oD,KAAKomD,YAEjBtgD,IAAK,SAASC,EAASkjD,GACnBnxC,EAAKhS,IAAIC,EAASkjD,IAGtBC,aAAc,SAASvoC,GACnB7I,EAAKuI,WAAWM,IAGpByK,SAAU,SAASzK,GACf7I,EAAK2H,OAAOkB,IAGhBwoC,QAAS,SAASxoC,GACd7I,EAAKmM,MAAMtD,IAGfyoC,QAAS,SAASzoC,GACd7I,EAAKmL,YAAYtC,IAGrB0oC,WAAY,SAAS1oC,GACjB7I,EAAKoI,eAAeS,IAGxB2oC,UAAW,SAAS3oC,GAChB,MAAO7I,GAAK8H,QAAQe,OAKhCunC,uBAAwB,WAEpB,MAAOloD,MAAKomD,YAAYmD,2BAChBvpD,KAAKye,SAASuR,YACfrwB,GAAG6pD,sBACH7pD,GAAG8pD,2BACH9pD,GAAG8pD,2BAGdC,qBAAsB,WAClB,GAAI5xC,GAAO9X,KACP2oD,EAAa3oD,KAAKomD,WAEtB,QACIuC,WAAYA,EACZ7iD,IAAK,SAASC,EAASkjD,GACnBnxC,EAAKhS,IAAIC,EAASkjD,IAEtBU,kBAAmB,SAAShpC,GACxB,MAAO7I,GAAKsK,YAAYtI,GAAI6G,IAASvG,QAEzCkvC,UAAW,SAAS3oC,GAChB,MAAO7I,GAAK8H,QAAQe,IAExBipC,UAAW,SAAS9vC,EAAIuC,GACpBvE,EAAKyN,QAAQzL,EAAIuC,IAErBwtC,sBAAuB,SAAS/vC,EAAIgwC,GAChC,GAAIC,GAAUpqD,GAAGgpD,EAAWqB,aAAalwC,IACrCmwC,EAAkBtqD,GAAGgpD,EAAW/B,iBAAiB9sC,GAEjDgwC,IACAC,EAAQ/nD,SAAS,cACjB2mD,EAAWuB,aAAapwC,GACxB6uC,EAAWwB,aAAarwC,KAGxBiwC,EAAQ9nD,YAAY,cACpB0mD,EAAWyB,aAAatwC,GACxB6uC,EAAW0B,aAAavwC,IAI5BmwC,EAAgBjoD,SAAS,WAAWC,YAAY,cAK5DmnB,sBAAuB,SAAStP,EAAIgC,EAAWD,GAC3C7b,KAAKmmD,QAAQ9/C,UAAU+iB,sBAAsBxZ,MAAM5P,KAAM8H,WAErD9H,KAAKkoD,0BAEDloD,KAAKomD,YAAYQ,iBAAiB9sC,IAAO+B,IAAclc,GAAGya,OAAOyC,YACjE7c,KAAKomD,YAAYkE,qBAAqBxwC,GACtC9Z,KAAKomD,YAAY+D,aAAarwC,IAIlCgC,IAAcnc,GAAGya,OAAOgD,iBAAmBvB,IAAclc,GAAGya,OAAO8C,WACnEld,KAAKomD,YAAYmE,UAAUzwC,GAC3B9Z,KAAKomD,YAAYoE,cAAc1wC,GAC/Bna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK7X,YAAYjC,KAAKyqD,SAASC,WAE/D7uC,IAAclc,GAAGya,OAAOkD,eAC7Btd,KAAKomD,YAAYuE,UAAU7wC,IAInCwuC,+BAAgC,WAC5B,GAAIvtC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAGirD,4BAA4B7vC,IAG9CytC,6BAA8B,WAC1B,GAAIztC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAG8pD,0BAA0B1uC,IAG5CqtC,wBAAyB,WACrB,GAAIrtC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAG6pD,qBAAqBzuC,IAGvC0Y,eAAgB,SAAS3Z,GACrB9Z,KAAKmmD,QAAQ9/C,UAAUotB,eAAe7jB,MAAM5P,KAAM8H,WAClD9H,KAAKomD,YAAYyE,YAAY/wC,IAGjC2X,eAAgB,SAASe,EAAYC,GACjCzyB,KAAKmmD,QAAQ9/C,UAAUorB,eAAe7hB,MAAM5P,KAAM8H,WAClD9H,KAAKomD,YAAY0E,sBAGrBz3B,UAAW,SAASvZ,EAAIpY,GACpB,GAAIyZ,GAAOnb,KAAKqhB,QAAQvH,EAEpBqB,IAAQA,EAAKqmC,QAAUxhD,KAAKye,SAASgqC,YAAYsC,sBACjD/qD,KAAKwjB,aAAa0F,YAAYpP,GAC1BkxC,OAAQ7vC,EAAKqmC,SAIrBxhD,KAAKmmD,QAAQ9/C,UAAUgtB,UAAUzjB,MAAM5P,KAAM8H,WAC7C9H,KAAKirD,WAAWnxC,EAAIpY,IAIxB6xB,aAAc,SAASzZ,GAEf9Z,KAAKkoD,2BACLloD,KAAKomD,YAAYkE,qBAAqBxwC,GACtC9Z,KAAKomD,YAAYiE,aAAavwC,GAGzB9Z,KAAKioD,wBACNjoD,KAAKuoD,2BAA2B2C,WAAWlrD,KAAKomD,YAAY4D,aAAalwC,MAMrFkR,YAAa,SAASlR,EAAIpY,EAAMopB,EAAQC,GACpC/qB,KAAKmmD,QAAQ9/C,UAAU2kB,YAAYpb,MAAM5P,KAAM8H,WAE/C9H,KAAKomD,YAAY+E,eAAerxC,EAAIgR,EAAQC,GAE9B,IAAVA,GAAoD,MAArCzpB,KAAKC,MAAMupB,EAASC,EAAQ,MAC3C/qB,KAAKomD,YAAYgF,WAAWtxC,GAC5B9Z,KAAKomD,YAAYuE,UAAU7wC,GAC3B9Z,KAAKomD,YAAYiF,aAAavxC,GAC9B9Z,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAASpb,KAAKioD,oBAGtDtrD,KAAKurD,iBAAiBzxC,IAItB9Z,KAAKurD,iBAAiBzxC,EAAIgR,EAAQC,IAI1CiJ,iBAAkB,SAASlJ,EAAQC,GAC/B/qB,KAAKmmD,QAAQ9/C,UAAU2tB,iBAAiBpkB,MAAM5P,KAAM8H,WACpD9H,KAAKomD,YAAYvJ,oBAAoB/xB,EAAQC,IAGjDI,YAAa,SAASrR,EAAIpY,EAAMY,EAAQ4oB,GAMpC,QAASsgC,GAAelpD,GAGfid,IAILopC,EAAW6B,cAAc1wC,GAEzBna,GAAG4f,GAAetd,YAAY6V,EAAK2yC,SAASC,UAC5C/B,EAAW0C,aAAavxC,GAEpBhC,EAAKsK,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAOkD,eAC/CqrC,EAAWyC,WAAWtxC,GAE1B6uC,EAAWkC,YAAY/wC,GAEnBxX,EAAOmJ,QACPqM,EAAK2zC,sBAAsB3xC,IAG3Bna,GAAG4f,GAAevd,SAAS8V,EAAK2yC,SAASiB,MACzC/C,EAAWgD,WAAW7xC,GAElB6uC,EAAWiD,oBAAsB9zC,EAAKuL,gBAAgBvJ,KACtDna,GAAG4f,GAAevd,SAAS8V,EAAK2yC,SAAS/N,WACzCiM,EAAWkD,UAAU/xC,IAEzBhC,EAAKg0C,2BAA2BhyC,EAAIxX,KAjC5C,GAAIypD,GAAe/rD,KAAKmmD,QAAQ9/C,UAAU8kB,YAAYvb,MAAM5P,KAAM8H,WAC9D6gD,EAAa3oD,KAAKomD,YAClB7mC,EAAgBopC,EAAW/B,iBAAiB9sC,GAC5ChC,EAAO9X,IA6CX,OAVI+rD,aAAwBpsD,IAAG4L,QAC3BwgD,EAAa70C,KAAK,SAAS80C,GACvBR,EAAeQ,KAKnBR,EAAelpD,GAGZypD,GAGXN,sBAAuB,SAAS3xC,GAC5B,GAAI6uC,GAAa3oD,KAAKomD,WAElBpmD,MAAKmwB,qBACLw4B,EAAWsD,iBAAiBnyC,GAGhCna,GAAGgpD,EAAW/B,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAASh/C,SAE3DzL,KAAKksD,sBAAsBpyC,IAG/B0R,cAAe,SAAS1R,GACpB9Z,KAAKmmD,QAAQ9/C,UAAUmlB,cAAc5b,MAAM5P,KAAM8H,WACjD9H,KAAKomD,YAAY+F,YAAYryC,IAGjC4R,UAAW,SAAS5R,EAAIpY,GACpB,GAAIqqD,GAAe/rD,KAAKmmD,QAAQ9/C,UAAUqlB,UAAU9b,MAAM5P,KAAM8H,UAIhE,OAFA9H,MAAKomD,YAAY+F,YAAYryC,GAEtBiyC,GAGXjgC,eAAgB,SAAShS,EAAI+R,GACzB7rB,KAAKmmD,QAAQ9/C,UAAUylB,eAAelc,MAAM5P,KAAM8H,WAI9C+jB,EAAUG,UAAY,GAAKhsB,KAAK6f,SAASiD,YAAYhJ,IACrD9Z,KAAKomD,YAAYgG,WAAWtyC,IAIpCwR,UAAW,SAASxR,EAAIpY,GACpB1B,KAAKmmD,QAAQ9/C,UAAUilB,UAAU1b,MAAM5P,KAAM8H,WAC7C9H,KAAK4nD,gBAAgB9tC,GAEU,IAA3B9Z,KAAKkuB,mBACLluB,KAAKomD,YAAY0E,sBAIzBh4B,mBAAoB,SAAShZ,GACzB,GAAIuyC,GAAoBC,EAASC,CAEjCvsD,MAAKmmD,QAAQ9/C,UAAUysB,mBAAmBljB,MAAM5P,KAAM8H,WAEtD9H,KAAKwsD,gBAAgB1yC,GAEjB9Z,KAAKye,SAASwF,MAAMwoC,oBACpBJ,EAAqBrsD,KAAKmjB,aAAarJ,GACvCwyC,EAAUtsD,KAAKye,SAASwF,MAAMqR,gBAE9Bi3B,EAAYvsD,KAAKye,SAASwF,MAAMyoC,cAAcxqD,QAAQ,gBAAiBmqD,GACvEE,EAAYA,EAAUrqD,QAAQ,eAAgBoqD,GAE9CtsD,KAAKomD,YAAYoE,cAAc1wC,EAAIyyC,GACnC5sD,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAASC,YAKzEn5B,qBAAsB,SAASzX,GAC3B,MAAI9Z,MAAKmmD,QAAQ9/C,UAAUkrB,qBAAqB3hB,MAAM5P,KAAM8H,YACxD9H,KAAKomD,YAAYuG,cAAc7yC,GAC/Bna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK7X,YAAYjC,KAAKyqD,SAASiB,MACpE1rD,KAAKomD,YAAYoE,cAAc1wC,GAC/B9Z,KAAKomD,YAAY+F,YAAYryC,GAC7B9Z,KAAKwsD,gBAAgB1yC,IACd,IAGPna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAAS/N,WACjE18C,KAAKomD,YAAYyF,UAAU/xC,IACpB,IAIfwG,gBAAiB,SAASxG,GACtB,GAAI4Z,GAAoB/zB,GAAG4P,KAAKvP,KAAK4sD,uBAAwB5sD,KAE7DA,MAAKmmD,QAAQ9/C,UAAUia,gBAAgB/Z,KAAKvG,KAAM8Z,EAAI4Z,IAG1Dk5B,uBAAwB,SAAS9yC,EAAIG,EAAM0Z,GACnC3zB,KAAKye,SAAS4B,WAAWwsC,aACzB7sD,KAAK8sD,mBAAmBl9C,MAAM5P,KAAM8H,WAGpC9H,KAAK+sD,mBAAmBn9C,MAAM5P,KAAM8H,YAI5C4d,kBAAmB,SAAS5L,EAAIoR,EAAKvD,GACjC3nB,KAAKmmD,QAAQ9/C,UAAUqf,kBAAkB9V,MAAM5P,KAAM8H,WAErD9H,KAAKomD,YAAYyE,YAAY/wC,GAEzB6N,GACA3nB,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAAS4B,WAAW2sC,oBAC5DhtD,KAAKomD,YAAY6F,iBAAiBnyC,IAGlC9Z,KAAK4nD,gBAAgB9tC,IAI7BizC,mBAAoB,SAASjzC,EAAIG,EAAM0Z,GACnC3zB,KAAKomD,YAAY6G,iBAAiBnzC,GAClC9Z,KAAKomD,YAAY+F,YAAYryC,GAC7B9Z,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAAS4B,WAAW6sC,oBAC5DltD,KAAK8zB,eAAeC,WAAWnkB,MAAM5P,KAAM8H,YAG/CglD,mBAAoB,SAAShzC,EAAIG,EAAMmhB,GAEnC,GAKIlsB,GALA0C,EAAW5R,KAAK4f,QAAQ9F,GACxBqzC,EAAiBntD,KAAKye,SAAS4B,WAAW8sC,eAAejrD,QAAQ,gBAAiB0P,GAElFw7C,GADOptD,KAAK6iB,QAAQ/I,GACAhS,WACpBgQ,EAAO9X,IAGXkP,GAASlP,KAAKye,SAAS4uC,YAAYF,GAE/BxtD,GAAG4W,iBAAiBrH,GACpBA,EAAOuH,KAAK,WACRqB,EAAKi1C,mBAAmBn9C,MAAMkI,EAAMs1C,KAGnCl+C,KAAW,GAChB4I,EAAKi1C,mBAAmBn9C,MAAMkI,EAAMs1C,IAI5CnC,WAAY,SAASnxC,EAAIpY,EAAM4rD,GAC3B,GAAIC,GAGA5xC,EAFA6xC,EAAe,EACfC,EAAcztD,KAAK6f,SAAS+kB,UAAU9qB,IAAO9Z,KAAKye,SAAS1I,QAAQ23C,UAGnE1tD,MAAKye,SAAS1e,QAAQ4tD,eAClB3tD,KAAK8mD,mBAAqB,GAAK9mD,KAAK+mD,uBAAyB,IAC7DyG,EAAextD,KAAK+mD,uBAAyB,GAGjDwG,GACIhzC,MAAOizC,IAIVF,IACGttD,KAAKye,SAAS+X,8BAAgC72B,GAAG8S,kBAAkBoC,eACnE7U,KAAKomD,YAAYwH,gBAMhB5tD,KAAKye,SAASjV,WACfmS,EAAS3b,KAAKoiB,YAAYtI,GAAIA,IAE9B9Z,KAAK6tD,mBAAqB7tD,KAAK6tD,oBAAsBlyC,EAAON,aAExDM,EAAON,eAAiBrb,KAAK6tD,oBAAuBlyC,EAAON,eAC3Drb,KAAK6f,SAASC,YACd9f,KAAK8tD,aACL9tD,KAAK6tD,mBAAqB,QAKlCP,GACAttD,KAAKomD,YAAY2H,eAAej0C,EAAI9Z,KAAKye,SAAS0S,eAAezvB,GAAO6rD,EAAaE,GACrFztD,KAAKomD,YAAY4H,gBAAgBl0C,EAAI9Z,KAAKmhB,eAAerH,IAAK,EAAM9Z,KAAKye,SAASwvC,WAAW/0B,iBAG7Fl5B,KAAKomD,YAAYtrC,QAAQhB,EAAI9Z,KAAKye,SAAS0S,eAAezvB,GAAO6rD,EAAaE,GAC9EztD,KAAKomD,YAAY8H,gBAAgBp0C,EAAI9Z,KAAKqhB,QAAQvH,GAAK9Z,KAAKye,SAASwvC,WAAW/0B,gBAGpFl5B,KAAK+mD,wBAA0B,GAE3BuG,GACCttD,KAAKye,SAAS1e,QAAQouD,kBAAoBxuD,GAAG8S,kBAAkBoC,gBAEhE7U,KAAKurD,iBAAiBzxC,IAI9Bg0C,WAAY,WACR9tD,KAAKomD,YAAYE,aACjBtmD,KAAKigB,oBAGTsrC,iBAAkB,SAASzxC,EAAIs0C,EAAY/R,GACvC,GAAInhC,GAAOlb,KAAKsiB,QAAQxI,GACpBu0C,EAAiBruD,KAAKktB,YAAYhS,EAElCA,IAAQ,IACWpX,SAAfsqD,GAA0CtqD,SAAdu4C,IAC5BgS,EAAiBruD,KAAKsuD,gBAAgBF,EAAY/R,IAGtDr8C,KAAKomD,YAAY9pC,WAAWxC,EAAIu0C,KAIxCC,gBAAiB,SAASC,EAAclS,GAEpC,QAASvvC,GAAEpL,EAAMkvB,GAAe7qB,EAAUA,EAAQ7D,QAAQR,EAAMkvB,GADhE,GAAI7qB,GAAU/F,KAAKye,SAASpb,KAAKmrD,cAKjC,OAFA1hD,GAAE,YAAaxL,KAAKC,MAAMgtD,EAAelS,EAAY,MACrDvvC,EAAE,eAAgB9M,KAAKktB,YAAYmvB,IAC5Bt2C,GAGX+lD,2BAA4B,SAAShyC,EAAIgY,GACrC,GAAI28B,GAAMC,EAAkBC,CAE5BF,GAAOzuD,KAAKye,SAASmwC,wBAAwBH,KAC7CC,EAAmB1uD,KAAKye,SAASmwC,wBAAwBF,iBAE5C,WAATD,GACAE,EAAgB78B,EAAS48B,GACpBC,IACDA,EAAgB3uD,KAAKye,SAASpb,KAAKwrD,YAGvC7uD,KAAKomD,YAAYoE,cAAc1wC,EAAI60C,GAE/B3uD,KAAKye,SAASmwC,wBAAwBE,eACtC9uD,KAAK+uD,aAAaj1C,EAAI60C,IAGZ,YAATF,EACLzuD,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAASpb,KAAKwrD,YAExC,SAATJ,GACLzuD,KAAK8F,IAAI,0CAA4C2oD,EAAO,iBAAkB,SAItFM,aAAc,SAASj1C,EAAIzW,GACvBrD,KAAKomD,YAAYQ,iBAAiB9sC,GAAIjC,MAAQxU,GAGlDmpD,gBAAiB,SAAS1yC,GACjB9Z,KAAKye,SAAS+X,8BAA+B72B,GAAG8S,kBAAkBoC,eACnE7U,KAAKomD,YAAYuF,WAAW7xC,IAIpC+L,WAAY,SAAS6K,EAAMhvB,EAAMuF,GAC7B,GAAIlB,GAAU/F,KAAKmmD,QAAQ9/C,UAAUwf,WAAWjW,MAAM5P,KAAM8H,UAC5D9H,MAAKye,SAASuwC,YAAYjpD,IAG9BygB,YAAa,SAASzgB,GAClB/F,KAAKmmD,QAAQ9/C,UAAUmgB,YAAY5W,MAAM5P,KAAM8H,WAC/C9H,KAAKye,SAASuwC,YAAYjpD,IAG9BkpD,kBAAmB,WACf,GAAIn3C,GAAO9X,IAEXA,MAAKye,SAASgI,UAAUyB,gBAAkB,WACtC,GAAIniB,GAAU+R,EAAK2G,SAASsJ,MAAMmnC,kBAC9BC,EAAar3C,EAAK2G,SAASsJ,MAAMpJ,WAErC,OAAO7G,GAAK2G,SAAS2wC,WAAWrpD,EAASopD,KAIjDliC,oBAAqB,SAASnT,EAAIpY,GAC9B1B,KAAK8mD,oBAAsB,EAC3B9mD,KAAKmmD,QAAQ9/C,UAAU4mB,oBAAoBrd,MAAM5P,KAAM8H,YAG3D0X,uBAAwB,SAASvV,EAAO4T,EAAQC,GAC5C9d,KAAK8mD,mBAAqB78C,EAAMvE,OAChC1F,KAAK+mD,uBAAyB,EAC9B/mD,KAAKmmD,QAAQ9/C,UAAUmZ,uBAAuB5P,MAAM5P,KAAM8H,YAG9DokD,sBAAuB,SAASvrC,GAC5B,GAAIwF,GAAenmB,KAAKmhB,eAAeR,EACtB3gB,MAAKoiB,YAAYtI,GAAI6G,IAASvG,SAE5Bza,GAAGya,OAAOqD,UACxB0I,IACDnmB,KAAKye,SAASwvC,WAAWoB,aAAaC,mBACrC3vD,GAAG8S,kBAAkBgD,eAItBzV,KAAKomD,YAAY4H,gBAAgBrtC,EAAQwF,EAAcnmB,KAAKye,SAASwvC,WAAW/0B,gBAIxF/a,eAAgB,SAAS6H,GACrB,GAAIlM,GAAK9Z,KAAKmmD,QAAQ9/C,UAAU8X,eAAevO,MAAM5P,KAAM8H,UAO3D,OALA9H,MAAKirD,WAAWnxC,EAAI9Z,KAAK4f,QAAQ9F,IAAK,GACtC9Z,KAAKomD,YAAYyE,YAAY/wC,GAC7B9Z,KAAKomD,YAAYgF,WAAWtxC,GAC5B9Z,KAAKyrD,sBAAsB3xC,GAEpBA,GAGX4S,SAAU,SAAS5S,EAAIyC,GACnBvc,KAAKmmD,QAAQ9/C,UAAUqmB,SAAS9c,MAAM5P,KAAM8H,WAE5C9H,KAAKomD,YAAY9pC,WAAWxC,EAAI9Z,KAAKktB,YAAY3Q,KAGrD4Y,wBAAyB,WACrBn1B,KAAKomD,YAAYC,gBACjBrmD,KAAKmmD,QAAQ9/C,UAAU8uB,wBAAwBvlB,MAAM5P,KAAM8H,gBC7sBvEnI,GAAG4vD,aAAe,SAAS/3C,EAAGiT,GAC1B,YAEA,IAAI3S,GAAO9X,IAKXA,MAAKmmD,QAAU17B,EAAY9qB,GAAG8qB,GAAW8L,kBAAoB52B,GAAG42B,kBAChEv2B,KAAKmmD,QAAQv2C,MAAM5P,KAAM8H,WAGzBnI,GAAG6B,OAAOxB,KAAKye,UACX7e,QAAS,KAET2jB,OAAQ,KAERisC,YAAa,KAEb/G,aACIC,kBACAqC,sBAAsB,GAG1B1nD,MACImrD,eAAgB,6BAChBK,WAAY,gBACZvD,mBAAoB,gBACpB/iB,OAAQ,UAGZknB,SAAU,cAEV1lC,SACI2gC,SAAU,qBACVhO,UAAW,sBACXjxC,QAAS,oBACTigD,KAAM,iBACNgE,SAAU,cACV7vD,KAAM,UACNsjD,WAAY,8BAGhByL,yBACIH,KAAM,UACNC,iBAAkB,QAClBI,eAAe,GAGnB/9B,UACI4+B,kBAAmB,6BACnBC,mBAAoB,kFAGxB3rC,OACIwoC,mBAAmB,EACnBC,cAAe,oCAGnBrsC,YACIwsC,cAAc,EACdM,eAAgB,8CAChBD,mBAAoB,cACpBF,mBAAoB,iBAIxBjtD,SACIouD,kBAAkB,EAClBR,cAAc,GAGlB5lC,OACI8nC,eAAe,EACfX,kBAAmB,0BAGvBjB,YACI/0B,cAAe,KACf42B,SAAU,EACVT,cACIC,mBAAmB,EACnBS,iBAAkB,KAClBC,YAAa,MAEjBC,kBAAmB,KAGvBl6C,SACI23C,YAAY,GAGhBsB,YAAa,SAASjpD,GAClB,GAAI+R,EAAKsuC,YAAY8J,UAAU,SAC3B,MAAOp4C,GAAKsuC,YAAY+J,WAAW,QAASpqD,EAG5CujB,YAAW,WACPzkB,OAAO8sB,MAAM5rB,IACd,IAIXsnD,YAAa,SAAStnD,GAClB,MAAI+R,GAAKsuC,YAAY8J,UAAU,WACpBp4C,EAAKsuC,YAAY+J,WAAW,UAAWpqD,GAGvClB,OAAOurD,QAAQrqD,IAI9BqpD,WAAY,SAASrpD,EAASsqD,GAC1B,MAAIv4C,GAAKsuC,YAAY8J,UAAU,UACpBp4C,EAAKsuC,YAAY+J,WAAW,SAAUpqD,EAASsqD,GAG/CxrD,OAAOyrD,OAAOvqD,EAASsqD,MAGvC,GAGH1wD,GAAG6B,OAAOxB,KAAKye,SAAUjH,GAAG,GAE5BxX,KAAKomD,YAAc,GAAIzmD,IAAG4wD,YACtBzqD,IAAKnG,GAAG4P,KAAKvP,KAAK8F,IAAK9F,MACvBwwD,eAAgBxwD,KAAKye,SAASgxC,SAC9BgB,YAAazwD,KAAKye,SAAS7e,QAC3B8wD,gBAAiB1wD,KAAKye,SAAS+wC,YAC/BjsC,OAAQvjB,KAAKye,SAAS8E,OACtB81B,eAAgBr5C,KAAKkhB,gBACrB6I,SACIlqB,KAAMG,KAAKye,SAASsL,QAAQlqB,KAC5B6vD,SAAU1vD,KAAKye,SAASsL,QAAQ2lC,UAEpCra,QACIsb,UAAW3wD,KAAKye,SAASwvC,WAAW6B,SACpCG,kBAAmBjwD,KAAKye,SAASwvC,WAAWgC,mBAEhDZ,cACIuB,gBAAiB5wD,KAAKye,SAASwvC,WAAWoB,aAAaC,kBACvDuB,sBAAuB7wD,KAAKye,SAASwvC,WAAWoB,aAAaU;6EAC7De,oBAAqB9wD,KAAKye,SAASwvC,WAAWoB,aAAaW,aAE/D3sD,KAAMrD,KAAKye,SAASpb,OAGpBrD,KAAKye,SAASgL,YAAYiI,mBAAqB/xB,GAAGyO,UAAYzO,GAAG2O,YACjEtO,KAAKomD,YAAY2K,cAAc/wD,KAAKye,SAASsS,SAASa,+BAEhDjyB,GAAG8S,kBAAkByD,WAAclW,KAAKye,SAAS6I,KAAK8I,WAAazwB,GAAG8S,kBAAkB0D,WAC9FnW,KAAKomD,YAAY2K,cAAc/wD,KAAKye,SAASsS,SAAS6+B,qBAGtD5vD,KAAKi2B,iBAELj2B,KAAKomD,YAAYlX,SAEjBlvC,KAAKyqD,SAAWzqD,KAAKye,SAASsL,SAEzB/pB,KAAKye,SAAS8E,QAAUvjB,KAAKomD,YAAY1kC,cAC1C1hB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKomD,YAAY1kC,YAC1B7J,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGPnZ,KAAKgnD,kCAEDrnD,GAAGmhD,aAAenhD,GAAG8S,kBAAkB6C,WACvCtV,KAAKwmD,KAAOxmD,KAAK6mD,qBAGjB7mD,KAAKye,SAASsJ,MAAMD,eAAiB9nB,KAAKye,SAASsJ,MAAM8nC,gBACrDlwD,GAAGkoB,aACH7nB,KAAKivD,oBAGLjvD,KAAK8F,IAAI,kCAAmC,UAIpD9F,KAAK8mD,mBAAqB,EAC1B9mD,KAAK+mD,uBAAyB,IAKtCpnD,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAG+d,eACxC/d,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGomB,gBAGxCpmB,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGumD,aACxCvmD,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGgoD,cC5LxChoD,GAAG4wD,WAAa,SAASx1C,GACrB,YAEA,IA4EIjV,GACAkrD,EACAC,EACAC,EACA5vC,EACAgO,EACA6hC,EACAC,EA1EAC,GACIC,QAAShoD,SAASioD,yBAClBC,QAEJC,GAAmB,EACnBC,EAAsB,EACtBC,GAA+B,EAC/BC,KACAC,GAAmB,EACnBj6C,GACI9R,IAAK,KACLuvC,QACIsb,UAAW,EACXV,kBAAmB,KAEvBO,eAAgB,cAChBC,YAAa,KACbC,gBAAiB,KACjBntC,OAAQ,KACR81B,eAAgB,KAChBtvB,SACIlqB,KAAM,UACN6vD,SAAU,eAEdL,cACIuB,iBAAiB,EACjBC,sBAAuB,KACvBC,oBAAqB,MAEzBztD,MACIklC,OAAQ,WAGhBupB,GACIvuC,OAAQ,4BACRwuC,YAAa,2BACbC,mBAAoB,4BACpBC,cAAe,6BACfC,cAAe,6BACfC,eAAgB,wBAChBC,aAAc,4BACdC,SAAU,uBACVC,KAAM,+BACNC,KAAM,0BACNC,qBAAsB,qCACtB38C,YAAa,2BACb48C,0BAA2B,2CAC3BC,iBAAkB,iCAClBv3C,KAAM,0BACNw3C,QAAS,6BACTz3C,KAAM,0BACNuE,OAAQ,4BACR7J,MAAO,2BACPg9C,eAAgB,8BAChBC,aAAc,4BACd5uC,MAAO,2BACP6uC,WAAY,iCACZC,kBAAmB,4BACnBC,aAAc,iCACdC,SAAU,oCACVC,eAAgB,8BAChBC,sBAAuB,sCACvBC,UAAW,yBAEfC,KACAC,EAAiC,GAAI3zD,IAAG4L,QACxCgoD,EAA+B,GAAI5zD,IAAG4L,QAatCioD,EAA6B,WACzB,GAAIC,GAAmB77C,EAAQy3C,aAAawB,sBACxC6C,EAAa97C,EAAQy3C,aAAayB,oBAClC/1C,GACI8F,QAASgxC,EACTzwC,MAAOgwC,EAGXD,KACIsC,EACA77C,EAAQyhC,eAAe93B,SAASkyC,EAAiB,GAAI9kB,OAAS5zB,GAAMtE,KAChE,SAASk9C,GACLL,EAA+B7nD,QAAQkoD,IAE3C,WACIL,EAA+B3nD,UAC/B7F,EAAI,wDAA0D2tD,EAAiB,WAKvFH,EAA+B3nD,UAG/B+nD,EACA97C,EAAQyhC,eAAe93B,SAASmyC,EAAY,GAAI/kB,OAAS5zB,GAAMtE,KAC3D,SAASk9C,GACLJ,EAA6B9nD,QAAQkoD,IAEzC,WACIJ,EAA6B5nD,UAC7B7F,EAAI,gEAAkE4tD,EAAY,WAK1FH,EAA6B5nD,YAOzCioD,EAAoB,SAASR,GACzB,GAAIS,GAAsB,GAAIl0D,IAAG4L,OAwBjC,OAtBAgoD,GAA6B98C,KAAK,SAASy0B,GACvC4oB,EAA4B5oB,EAAKkoB,GAE5BA,EAAUrkB,IASX8kB,EAAoBpoD,WARpB2nD,EAAUrkB,IAAM7D,EAAI6D,IACpBqkB,EAAU5nD,OAAS,WACf4nD,EAAU5nD,OAAS,KACnBuoD,EAAKX,GACLS,EAAoBpoD,aAM7B,WAIC5L,EAAKuzD,GACLS,EAAoBpoD,YAGjBooD,GAGXG,EAAqB,SAASl6C,EAAI7O,EAAM8P,GACpC,GAAIq4C,GAAYa,EAAan6C,EAK7B,OAHAhU,GAAI,gCAAkCgU,GACtC7O,EAAKipD,cAAgBp6C,EAEdlC,EAAQyhC,eAAe93B,SAAStW,EAAMmoD,EAAWr4C,GAAMtE,KAC1D,WACIi7C,IACAqC,EAAKX,GACLC,EAAkBv5C,GAAIrO,WAE1B,WACI4nD,EAAkBv5C,GAAInO,UAIjBiM,EAAQy3C,aAAauB,iBACtBuD,EAA+Br6C,EAAIs5C,MAKnDgB,EAA4B,WACxB,GAAIxC,EAAqBlsD,OAAQ,CAC7BisD,GAA+B,CAE/B,IAAI0C,GAAqBzC,EAAqB3/C,OAE1CoiD,GAAmBC,OACnBC,EAAkCF,GAGlCG,EAA+BH,OAInC1C,IAA+B,GAIvC8C,EAAY,SAAS36C,GACjB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBryC,SAGtDk1C,EAAc,SAAS76C,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBc,iBAGtDgC,EAAY,SAAS10D,GACjB,MAAOw0D,GAAcpzC,EAAWwwC,EAAgB5xD,EAAO,YAG3D20D,EAAY,SAAS/6C,GACjB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBe,eAGtDiC,EAAoB,WAChB,MAAOJ,GAAcpzC,EAAWwwC,EAAgBoB,iBAGpD6B,EAAc,SAASj7C,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBkB,eAGtD3xC,EAAU,SAASvH,GACf,MAAOu3C,GAAUG,IAAI13C,IAAOna,GAAG2vB,GAAUxsB,gBAhOzB,cAgO6DgX,IAGjFpI,EAAc,SAASoI,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB32C,OAGtD65C,EAAW,SAASl7C,GAChB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBl8C,QAGtDq/C,EAAc,SAASn7C,GAGnB,MAAU,OAANA,EACO46C,EAAcpzC,EAAWwwC,EAAgBW,4BAC5CiC,EAAcpzC,EAAWwwC,EAAgBY,kBAI1CgC,EAAcrzC,EAAQvH,GAAKg4C,EAAgBU,uBAC9CkC,EAAcrzC,EAAQvH,GAAKg4C,EAAgBj8C,cAGnDq/C,EAAW,SAASp7C,GAChB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB7tC,QAGtD3B,EAAU,SAASxI,GACf,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB52C,OAGtDi6C,EAAa,SAASr7C,GAClB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBa,UAGtD+B,EAAgB,SAASjlD,EAAS2lD,GAC9B,MAAO3lD,IAAW9P,GAAG8P,GAAS3M,gBAAgBsyD,IAGlDnB,EAAe,SAASn6C,GACpB,MAAOq3C,IAAkBuD,EAAcrzC,EAAQvH,GAAKg4C,EAAgBsB,YAGxEvzD,EAAO,SAAS8vC,GACZA,GAAMhwC,GAAGgwC,GAAI3tC,SAAS4V,EAAQmS,QAAQlqB,OAM1Ci0D,EAA8B,SAASxiC,EAAa8hC,GAChD,GAAIn8B,GAAW3F,EAAYxxB,MAAMm3B,SAC7BD,EAAY1F,EAAYxxB,MAAMk3B,SAE9BA,IAAaC,IAAam8B,EAAUtzD,MAAMm3B,WAAam8B,EAAUtzD,MAAMk3B,WACvEr3B,GAAGyzD,GAAWnyD,KACVg2B,SAAUA,EACVD,UAAWA,KAQvBm9B,EAAiC,SAASr6C,EAAIs5C,GAC1C,GAAIiC,GAAahC,EAAkBv5C,KAAO,GAAIna,IAAG4L,SAAUI,UACvD2pD,EAA2B,GAAI31D,IAAG4L,OAqBtC,OAnBA+nD,GAA+B78C,KAAK,SAASy0B,GACzCmqB,EAAW5+C,KACP,WACI6+C,EAAyB7pD,WAE7B,WACIqoD,EAA4B5oB,EAAKkoB,GAEjCA,EAAU5nD,OAAS,WACf4nD,EAAU5nD,OAAS,KACnB8pD,EAAyB7pD,WAG7B2nD,EAAUrkB,IAAM7D,EAAI6D,IACpBglB,EAAKX,OAKVkC,GAWXC,EAAsB,WAClB,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACA/S,EACAsQ,EACAF,EACA4C,EACAC,CAKJ,IAHAjwD,EAAI,oBAG0B,MAA1B8R,EAAQ44C,eACR,KAAM,IAAIrvD,OAAM,oDAIpB,IAAIxB,GAAGwH,SAASyQ,EAAQ44C,gBAAiB,CAGrC,GAFAgF,EAAWlsD,SAASs8B,eAAehuB,EAAQ44C,gBAE1B,OAAbgF,EACA,KAAM,IAAIr0D,OAAMxB,GAAG8H,OAAO,0CAA2CmQ,EAAQ44C,gBAGjFiF,GAAaD,EAAS1mD,cAErB,CACD,GAAyChL,SAArC8T,EAAQ44C,eAAe1hD,UACvB,KAAM,IAAI3N,OAAM,gGAIpBs0D,GAAa79C,EAAQ44C,eAAe1hD,UA4ExC,GAzEA2mD,EAAa91D,GAAG0H,QAAQouD,GACxBE,EAAiBrsD,SAASC,cAAc,OACxCosD,EAAe5kD,YAAYpR,GAAGgP,UAAU8mD,IACxCM,EAAap2D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBO,UAI5Dz6C,EAAQ2L,SACRsyC,EAAgBl2D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBvuC,QAC/DsyC,GACAl2D,GAAGk2D,GAAe90D,UASrBpB,GAAGmhD,aAAgBnhD,GAAG8S,kBAAkB6C,WACzC49C,EAAiBvzD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBoB,gBAChEA,GACAvzD,GAAGuzD,GAAgBnyD,UAI3B+hD,EAAWnjD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBQ,MAI1DxP,IAAanjD,GAAGmhD,cAChBh7C,EAAI,0BAA2B,QAC/BnG,GAAGmjD,GAAU/hD,UAGZpB,GAAG8S,kBAAkB6C,SAajB3V,GAAGo2D,GAAYtyD,aAtZN,sBAsZ2Cq/C,IACzDgT,EAAan2D,GAAGmjD,GAAUhgD,gBAAgBgvD,EAAgBmB,UAC1D6C,GAAcn2D,GAAGm2D,GAAY/0D,WAb7Bg1D,EAAWz8C,gBA3YG,qBA6YVwpC,GAAYnjD,GAAGmjD,GAAUr/C,aA9YhB,qBAkZT9D,GAAGmjD,GAAU7hD,KACTlB,QAAS,UAWrBqzD,EAAYzzD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBsB,WAC1DjC,EAGIiC,IACLvB,EAAmB5uB,SAASmwB,EAAUvvD,aAtapB,gBAwalBguD,EAAmBA,EAAmB,EAAIA,EAAmB,KAE7DT,EAAczxD,GAAGyzD,GAAW3vD,aAzaN,oBAkatB2vD,GAAazzD,GAAGyzD,GAAWryD,SAS/BowD,EAAiBA,GAAkBiC,EAEnCpC,EAAsBrxD,GAAGg2D,GAAgBxzD,WAAW2vD,EAAgBiB,mBAAmBrtD,OAAS,EAChGurD,EAAsBtxD,GAAGg2D,GAAgBxzD,WAAW2vD,EAAgB7tC,OAAOve,OAAS,EAEpFgwD,EAAe/1D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBS,MAE9C,MAAhBmD,EACA,KAAM,IAAIv0D,OAAM,0DAapB,OAVAy0D,GAAaF,EAAa3yD,SAAS,GAAGizD,WAAU,GAChDN,EAAa5mD,UAAY,GAGrB6mD,EAAelzD,qBAAqB,UAAUiD,QAC9C4D,SAASC,cAAc,UAG3BzD,EAAI,8BAGA2pD,SAAUkG,EACVM,aAAcL,IAItBM,EAAc,SAASvmB,EAAIp1B,EAAO+U,GAC9B,GAAI6mC,GAAW7mC,EACX8mC,EAAWD,EAASlzD,UAEpBsX,GAAQ,IACR67C,EAAWz2D,GAAGw2D,GAAUpzD,WAAWwX,GAAOpX,aAI9CgzD,EAASv1D,aAAa+uC,EAAIymB,IAG9B5B,EAAiC,SAASH,GACtC,GAAIv6C,GAAKu6C,EAAmBv6C,GACxBu8C,EAAgBhC,EAAmBgC,cACnCC,EAAqBD,GAAiBA,EAAcnC,cACpDd,EAAYa,EAAan6C,GACzBiB,GACIgG,qBAAsBszC,EAAmBtzC,qBACzCF,QAASgxC,EACTz4B,QAAQ,EACRhY,OAAO,EAGXzhB,IAAG8S,kBAAkBgD,cACjB29C,EACIx7C,EAAQy9B,OAAOsb,WAAa/4C,EAAQy9B,OAAOsb,WAAae,GACxDyC,EAA+Br6C,EAAIs5C,GACnCgB,KAGAR,EAAkBR,GAAWl8C,KAAK,WAC9Bm8C,EAAkBv5C,GAAM,GAAIna,IAAG4L,QAE/B8nD,EAAkBv5C,GAAI5C,KAAK,WACvBoS,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,qBAM/B,MAAtBqG,EACAC,EAAiBz8C,EAAIw8C,GAGrBtC,EAAmBl6C,EAAIu8C,EAAet7C,KAOlDq5C,IAGChB,IACLQ,EAAkBR,GAClBgB,MAIRG,EAAoC,SAASF,GACzC,GAAIv6C,GAAKu6C,EAAmBv6C,GACxBqM,EAAekuC,EAAmBluC,aAClCqwC,EAAiBnC,EAAmBmC,eACpCpD,EAAYa,EAAan6C,GACzBiB,GACIgG,qBAAsBszC,EAAmBtzC,qBACzCK,MAAOgwC,EACPvwC,QAASgxC,EAGjB,IAAIuB,EACA,GAAIjtC,EAAc,CACd,KAAIvO,EAAQy9B,OAAOsb,WAAa/4C,EAAQy9B,OAAOsb,WAAae,GASxD,MAJI8E,IACA5C,EAAkBR,GAGfx7C,EAAQyhC,eAAe93B,SAAS4E,EAAcitC,EAAWr4C,GAAMtE,KAClE,WACIs9C,EAAKX,GACL1B,IACApoC,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,oBAGzD,WACIkE,EAA+Br6C,EAAIs5C,GACnC9pC,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,oBAjB7DkE,GAA+Br6C,EAAIs5C,GACnCgB,QAsBJD,GAA+Br6C,EAAIs5C,GACnCgB,KAKZqC,EAAsB,SAAS38C,EAAI48C,GAC/B,GAAIC,GAAM1B,EAAYn7C,GAElB88C,EAA4B,MAAN98C,EAAag4C,EAAgBY,iBAAmBZ,EAAgBj8C,WAEtF8gD,KAAQh3D,GAAGg3D,GAAKl1D,SAASm1D,KACzBD,EAAMh3D,GAAGg3D,GAAK7zD,gBAAgB8zD,IAG9BD,IACAh3D,GAAGg3D,GAAK11D,KAAKuqC,MAAOkrB,EAAU,MAC9BC,EAAI7lD,aAAa,gBAAiB4lD,KAI1C3C,EAAO,SAASpkB,GACZA,GAAMhwC,GAAGgwC,GAAI1tC,YAAY2V,EAAQmS,QAAQlqB,OAG7C02D,EAAmB,SAASM,EAAmBC,GAC3C,GAAIC,GAAkB9C,EAAa4C,GAC/BG,EAAkB/C,EAAa6C,EAEnChxD,GAAInG,GAAG8H,OAAO,qFAAsFovD,EAAmBC,EAAmBA,IAG1IzD,EAAkByD,GAAmBrgD,KAAK,WACtCi7C,IACA2B,EAAkBwD,GAAmBprD,UACrC3F,EAAInG,GAAG8H,OAAO,uEAAwEqvD,EAAmBD,IACzGE,EAAgBhoB,IAAMioB,EAAgBjoB,IACtCglB,EAAKgD,IAET,WACI1D,EAAkBwD,GAAmBlrD,UAChCiM,EAAQy3C,aAAauB,iBACtBuD,EAA+B0C,EAAmBE,KAKlEp3D,IAAG6B,OAAOoW,EAASmD,GACnBjV,EAAM8R,EAAQ9R,IAITnG,GAAG8S,kBAAkBgD,gBACtBmC,EAAQy9B,OAAO4a,kBAAoB,EACnCr4C,EAAQy9B,OAAOsb,UAAY,GAG/BrvC,EAAY1J,EAAQ64C,YACpBU,EAA4CrtD,SAA3B8T,EAAQyhC,eACzB6X,EAAcqE,IAEd/B,IAEA7zD,GAAG6B,OAAOxB,MACNkvC,OAAQ,WACJppC,EAAI,8BAEJ4rD,EAAsB,EAEtBpwC,EAAUvQ,YAAYmgD,EAAYzB,SAASuG,WAAU,IACrDn2D,EAAKi1D,KACL90D,KAAKi3D,oBACL3nC,EAAW1X,EAAQ84C,iBAAmBgE,EAAcpzC,EAAWwwC,EAAgBS,MAE/EzsD,EAAI,gCAGRirD,cAAe,SAAShrD,GACpB,GAAImxD,GAAev3D,GAAGgP,UAAU5I,EAChCub,GAAUxS,UAAY,GACtBwS,EAAUvQ,YAAYmmD,IAG1B19C,MAAO,WACH8H,EAAUxS,UAAY,GACtB9O,KAAKkvC,UAGToX,WAAY,WACRh3B,EAASxgB,UAAY,IAGzB8+C,cAAe,WACX6D,GAAmB,GAGvB32C,QAAS,SAAShB,EAAIpY,EAAMy1D,EAAaC,EAAaC,GAClD,GAIIC,GAJAC,EAASrG,EAAY+E,aAAaD,WAAU,GAC5CwB,EAAa9C,EAAc6C,EAAQzF,EAAgB32C,MACnD46C,EAAarB,EAAcpzC,EAAWwwC,EAAgBO,UACtD9yC,EAAgB83C,EAAQhG,EAAUC,QAAUhiC,CAG5C+nC,KACAhG,EAAUG,IAAI13C,GAAMy9C,GAGxB53D,GAAG43D,GAAQv1D,SArpBK,cAqpBwB8X,GACxCi8C,EAAWz8C,gBAjpBO,qBAmpBdk+C,IACA73D,GAAG63D,GAAYp0D,QAAQ1B,GACvB81D,EAAW1mD,aAAa,QAASpP,IAGrC61D,EAAOzmD,aA9pBI,aA8pBuBgJ,GAE9Bq9C,EACAjB,EAAYqB,EAAQJ,EAAY58C,MAAOgF,GAGvCA,EAAcxO,YAAYwmD,GAG1BH,GACAG,EAAOz3D,MAAMC,QAAU,OACvBJ,GAAG43D,GAAQv1D,SAjqBI,uBAoqBfnC,EAAKo1D,EAAYn7C,IACjBja,EAAKyiB,EAAQxI,IACbja,EAAKg1D,EAAU/6C,IACfja,EAAKq1D,EAASp7C,IACdja,EAAKm1D,EAASl7C,IACdja,EAAK80D,EAAY76C,IAEb23C,GACAzxD,KAAKorD,WAAWtxC,GAGpBw9C,EAAQrD,EAAan6C,GACjBw9C,IAAUA,EAAMvoB,KAChBwkB,EAA6B98C,KAAK,SAASghD,GACvCH,EAAMvoB,IAAM0oB,EAAW1oB,IACnB0oB,EAAW33D,MAAMk3B,WAAaygC,EAAW33D,MAAMm3B,UAC/Ct3B,GAAG23D,GAAOr2D,KACN+1B,UAAWygC,EAAW33D,MAAMk3B,UAC5BC,SAAUwgC,EAAW33D,MAAMm3B,WAInC88B,EAAKuD,OAMrBvJ,eAAgB,SAASj0C,EAAIpY,EAAMy1D,EAAaC,GAC5Cp3D,KAAK8a,QAAQhB,EAAIpY,EAAMy1D,EAAaC,GAAa,IAGrD/Q,cAAe,WACX/2B,EAASve,YAAYsgD,EAAUC,SAC/BD,EAAUC,QAAUhoD,SAASioD,yBAC7BF,EAAUG,QAGd3J,WAAY,SAAS/tC,GACjBna,GAAG0hB,EAAQvH,IAAK/Y,UAGpBymD,UAAW,SAAS7X,GAChB,GAAI+nB,GAAc/nB,CAElB,IAAI+nB,EAAa,CAEb,KAAiD,MAA1CA,EAAY7zD,aA3tBZ,eA4tBH6zD,EAAcA,EAAY52D,UAG9B,OAAOmiC,UAASy0B,EAAY7zD,aA/tBrB,iBAmuBf8zD,YAAa,WACT,MAAOroC,IAGXg7B,qBAAsB,SAASxwC,GAC3B,GAAIxI,GAAWI,EAAYoI,EAE3BxI,IAAY3R,GAAG2R,GAAUtP,SAAS4V,EAAQmS,QAAQ2lC,WAGtDxI,eAAgB,SAASptC,EAAIpY,GACzB,GAAIk2D,GAAalmD,EAAYoI,EAEzB89C,KACAj4D,GAAGi4D,GAAYx0D,QAAQ1B,GACvBk2D,EAAW9mD,aAAa,QAASpP,KAIzCwoD,aAAc,SAASpwC,GACnBja,EAAK6R,EAAYoI,KAGrBswC,aAAc,SAAStwC,GACnBi6C,EAAKriD,EAAYoI,KAGrB+9C,WAAY,SAASloB,GACjB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgB32C,OAG3CuG,UAAW,WACP,MAAO9J,GAAQ2L,QAAUmxC,EAAcpzC,EAAWwwC,EAAgBvuC,SAGtEwlC,mBAAoB,WAChBlpD,EAAKi1D,MAGThM,mBAAoB,WAChBiL,EAAKe,MAGTjM,YAAa,WACT,MAAO6L,GAAcpzC,EAAWwwC,EAAgBQ,OAGpD/I,uBAAwB,WACpB,MAAOyH,IAGXzG,UAAW,SAASzwC,GAChBja,EAAKq1D,EAASp7C,KAGlB8xC,gBAAiB,WACb,MAAOqF,IAGXpF,UAAW,SAAS/xC,GAChBi6C,EAAKmB,EAASp7C,KAGlB8sC,iBAAkB,SAAS9sC,GACvB,MAAOuH,GAAQvH,IAGnBuwC,aAAc,SAASvwC,GACnB,GAAIg+C,GAAO/C,EAAYj7C,EAEvBg+C,IAAQn4D,GAAGm4D,GAAM91D,SAAS4V,EAAQmS,QAAQ2lC,WAG9C/I,gBAAiB,SAAS7sC,GACtB,MAAOna,IAAG0hB,EAAQvH,IAAKrY,SAryBJ,sBAwyBvB0oD,aAAc,SAASrwC,GACnB,GAAIg+C,GAAO/C,EAAYj7C,EAEvBg+C,IAAQn4D,GAAGm4D,GAAM71D,YAAY2V,EAAQmS,QAAQ2lC,WAGjDqI,WAAY,SAASpoB,GACjB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBkB,cAAc,IAGzDhJ,aAAc,SAASlwC,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBiB,oBAGtDiF,YAAa,SAASroB,GAClB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBiB,mBAAmB,IAG9D5H,eAAgB,SAASrxC,EAAIgR,EAAQC,GACjC,GACI2rC,GADAC,EAAM1B,EAAYn7C,EAGlB68C,IAAO5rC,EAAQ,IACf2rC,EAAUp1D,KAAKC,MAAMupB,EAASC,EAAQ,KAEtB,MAAZ2rC,EACA72D,EAAK82D,GAGL5C,EAAK4C,GAGTF,EAAoB38C,EAAI48C,KAIhC7Z,oBAAqB,SAAS/xB,EAAQC,GAClC/qB,KAAKmrD,eAAe,KAAMrgC,EAAQC,IAGtCsgC,aAAc,SAASvxC,GACnB,GAAI68C,GAAM1B,EAAYn7C,EAEtB68C,IAAO92D,EAAK82D,IAGhBM,kBAAmB,WACfj3D,KAAKqrD,gBAGTsB,cAAe,SAAS7yC,GACpB28C,EAAoB38C,EAAI,GACxB9Z,KAAKi3D,kBAAkBn9C,IAG3BgxC,mBAAoB,WAChB9qD,KAAK2sD,iBAGThB,WAAY,SAAS7xC,GACjB,IAAK23C,EAAkB,CACnB,GAAIhyC,GAASg1C,EAAU36C,EAEvB2F,IAAU9f,GAAG8f,GAAQxd,YAAY2V,EAAQmS,QAAQlqB,QAIzDurD,WAAY,SAAStxC,GACjBja,EAAK40D,EAAU36C,KAGnBm+C,SAAU,SAAStoB,GACf,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBryC,QAAQ,IAGnD2sC,WAAY,SAAStyC,GACjBi6C,EAAKiB,EAASl7C,IACdja,EAAK80D,EAAY76C,KAGrBqtC,aAAc,SAASrtC,GACnB9Z,KAAKwqD,cAAc1wC,EAAIlC,EAAQvU,KAAKklC,QACpCvoC,KAAKk4D,oBAAoBp+C,GACzBja,EAAKs1D,EAAWr7C,KAGpB6wC,UAAW,SAAS7wC,GAChBja,EAAKm1D,EAASl7C,KAGlBq+C,QAAS,SAASxoB,GACd,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBl8C,OAAO,IAGlDwiD,iBAAkB,SAASzoB,GACvB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBc,gBAAgB,IAG3DsF,oBAAqB,SAASp+C,GAC1Bi6C,EAAKY,EAAY76C,IACjBja,EAAKm1D,EAASl7C,KAGlButC,gBAAiB,SAASvtC,GACtB9Z,KAAKwqD,cAAc1wC,EAAI,IACvB9Z,KAAKosD,WAAWtyC,GAChBi6C,EAAKoB,EAAWr7C,KAGpBmyC,iBAAkB,SAASnyC,GACvBi6C,EAAKc,EAAU/6C,KAGnBmzC,iBAAkB,SAASnzC,GACvBja,EAAKg1D,EAAU/6C,KAGnBu+C,eAAgB,SAAS1oB,GACrB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBe,cAAc,IAGzDyF,QAAS,SAAS3oB,GACd,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgB7tC,OAAO,IAGlD3H,WAAY,SAASxC,EAAIzW,GACrB,GAAI6X,GAAOoH,EAAQxI,EAEfoB,KACA64C,EAAK74C,GACLvb,GAAGub,GAAM9X,QAAQC,KAIzBmnD,cAAe,SAAS1wC,EAAIzW,GACxB,GAAIk1D,GAAS7D,EAAcrzC,EAAQvH,GAAKg4C,EAAgBgB,WAEpDyF,KAEY,MAARl1D,EACA1D,GAAG44D,GAAQ/0D,YAGX7D,GAAG44D,GAAQn1D,QAAQC,KAK/BwnD,YAAa,SAAS/wC,GAClBna,GAAG0hB,EAAQvH,IAAK7X,YA97BA,kBA+7BhBpC,EAAKs1D,EAAWr7C,KAGpBqyC,YAAa,SAASryC,GAClBna,GAAG0hB,EAAQvH,IAAK9X,SAn8BA,kBAo8BhB+xD,EAAKoB,EAAWr7C,KAGpBo0C,gBAAiB,SAASp0C,EAAIu8C,EAAet1C,GACpC/gB,KAAK2mD,gBAAgB7sC,KACtB83C,EAAqB/uD,MAAMiX,GAAIA,EAAIiH,qBAAsBA,EAAsBs1C,cAAeA,KAC7F1E,GAAgCyC,MAIzCpG,gBAAiB,SAASl0C,EAAIqM,EAAcqwC,EAAgBz1C,GACnD/gB,KAAK2mD,gBAAgB7sC,KACtB83C,EAAqB/uD,MAAMke,qBAAsBA,EAAsBuzC,QAAQ,EAAMx6C,GAAIA,EAAIqM,aAAcA,EAAcqwC,eAAgBA,KACxI7E,GAAgCyC,MAIzClE,UAAW,SAAShwD,GAChB,MAAOP,IAAG8S,kBAAkB2C,iBAAmBw/C,EAAU10D,IAG7DiwD,WAAY,SAASjwD,EAAM6F,EAASsqD,GAChC,GAAImI,GAAS5D,EAAU10D,GACnBu4D,EAAY/D,EAAc8D,EAAQ1G,EAAgBI,eAClDwG,EAAUF,EAAO/1D,qBAAqB,SAAS,GAC/Ck2D,EAAYjE,EAAc8D,EAAQ1G,EAAgBE,oBAClD4G,EAAQlE,EAAc8D,EAAQ1G,EAAgBK,gBAC9C7mD,EAAU,GAAI3L,IAAG4L,QAEjBstD,EAAe,WACXF,EAAUp4D,oBAAoB,QAASu4D,GACvCF,GAASA,EAAMr4D,oBAAoB,QAASw4D,GAC5CztD,EAAQK,WAGZmtD,EAAqB,WACjBH,EAAUp4D,oBAAoB,QAASu4D,GACvCN,EAAOQ,SAGXD,EAAiB,WACbP,EAAOj4D,oBAAoB,QAASs4D,GACpCD,EAAMr4D,oBAAoB,QAASw4D,GACnCP,EAAOQ,QAEP1tD,EAAQG,QAAQitD,GAAWA,EAAQhyD,OAc3C,OAXA8xD,GAAOp4D,iBAAiB,QAASy4D,GACjCF,EAAUv4D,iBAAiB,QAAS04D,GACpCF,GAASA,EAAMx4D,iBAAiB,QAAS24D,GAErCL,IACAA,EAAQhyD,MAAQ2pD,GAEpBoI,EAAUl1D,YAAcwC,EAExByyD,EAAOS,YAEA3tD,MChhCnB3L,GAAGu5D,eAAiB,SAASC,EAAGC,GAC5B,YAqBA,SAASlO,GAAWtrD,GAChBoS,EAAS/R,OAAOL,EAASmb,EAAKs+C,UAAW,SAASxkC,GAE9CA,EAAQA,GAAShwB,OAAOgwB,KAGxB,IAAI5oB,GAAS4oB,EAAM5oB,QAAU4oB,EAAMykC,UAEnCv+C,GAAKw+C,UAAUttD,EAAQ4oB,KA3B/B,GAAI7iB,GAAW,GAAIrS,IAAGkS,eAClBkJ,GACIs+C,UAAW,QACXG,SAAU,KACVD,UAAW,SAASttD,EAAQ4oB,KAKpCl1B,IAAG6B,OAAOxB,MACNkrD,WAAY,SAAStrD,GACjBsrD,EAAWtrD,IAGfmS,QAAS,WACLC,EAASD,aAiBjBpS,GAAG6B,OAAO43D,GACNK,kBAAmB,SAASxyD,GACxB,MAAOA,GAAKyyD,UAGhBC,kBAAmB,WACf,MAAO3nD,MAIfrS,GAAG6B,OAAOuZ,EAAMo+C,GAEZp+C,EAAKy+C,UACLtO,EAAWnwC,EAAKy+C,WClDxB75D,GAAGooD,wBAA0B,SAASoR,GAClC,YAqBA,SAASS,GAAa3tD,EAAQ4oB,GAC1Bl1B,GAAG+C,KAAKm3D,EAAgB,SAASC,EAAY7qC,GACzC,GACItO,GADAo5C,EAA2BD,EAAWxqD,OAAO,GAAGwX,cAAgBgzC,EAAWjyD,MAAM,EAGrF,IAAIkT,EAAK4tC,WAAW,KAAOoR,GAA0B9tD,GAKjD,MAJA0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,GACnCtM,GAAG6O,eAAeqmB,GAClB9Z,EAAKjV,IAAInG,GAAG8H,OAAO,+DAAgEsT,EAAKuuC,UAAU3oC,GAASA,IAC3GsO,EAAQtO,IACD,IA7BnB,GAAIq5C,MACAj/C,GACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBC,aAAc,SAASvoC,KACvByK,SAAU,SAASzK,KACnBwoC,QAAS,SAASxoC,KAClByoC,QAAS,SAASzoC,KAClB0oC,WAAY,SAAS1oC,KACrB2oC,UAAW,SAAS3oC,MAExBk5C,GACIp6C,OAAQ,SAAS3F,GAAMiB,EAAKqQ,SAAStR,IACrCmK,MAAQ,SAASnK,GAAMiB,EAAKouC,QAAQrvC,IACpC+4C,aAAc,SAAS/4C,GAAMiB,EAAKmuC,aAAapvC,IAC/ClE,MAAO,SAASkE,GAAMiB,EAAKquC,QAAQtvC,IACnC84C,eAAgB,SAAS94C,GAAMiB,EAAKsuC,WAAWvvC,IAkBvDna,IAAG6B,OAAOuZ,EAAMo+C,GAEhBp+C,EAAKs+C,UAAY,QACjBt+C,EAAKw+C,UAAYK,EACjB7+C,EAAKy+C,SAAWz+C,EAAK4tC,WAAWgP,cAEhCh4D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu5D,eAAen+C,EAAMi/C,KC1ChDr6D,GAAG6pD,qBAAuB,SAAS2P,GAC/B,YAiBA,SAASS,GAAa3tD,EAAQ4oB,GAC1B,GAAI9Z,EAAK4tC,WAAWkP,WAAW5rD,IAAW8O,EAAK4tC,WAAWoP,WAAW9rD,GAAS,CAC1E,GAAI0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,EAC1B8O,GAAK4uC,kBAAkBhpC,KAGrBhhB,GAAGya,OAAOyC,YACrB9B,EAAKjV,IAAInG,GAAG8H,OAAO,4DAA6DsT,EAAKuuC,UAAU3oC,GAASA,IACxGhhB,GAAG6O,eAAeqmB,GAElBmlC,EAAqBC,mBAAmBt5C,EAAQ1U,GAAQ,KAzBpE,GAAI+tD,MACAj/C,GACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBl/B,SACI5O,KAAM,iBACN63C,aAAc,yBAElBrJ,kBAAmB,SAAShpC,KAC5B2oC,UAAW,SAAS3oC,KAG5BhhB,IAAG6B,OAAOuZ,EAAMo+C,GAkBhBp+C,EAAKs+C,UAAY,QACjBt+C,EAAKw+C,UAAYK,EAEjBj6D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu6D,oBAAoBn/C,EAAMi/C,KCpCrDr6D,GAAGirD,4BAA8B,SAASuO,EAAGa,GACzC,YAaA,SAASG,GAAiBluD,EAAQ4oB,GAC9B,GAAI9Z,EAAK4tC,WAAWqP,YAAY/rD,GAAS,CACrC,GAAI0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,EAC1B8O,GAAK4uC,kBAAkBhpC,KAErBhhB,GAAGya,OAAOyC,YACrB9B,EAAKjV,IAAInG,GAAG8H,OAAO,kEAAmEsT,EAAKuuC,UAAU3oC,GAASA,IAC9Gq5C,EAAqBC,mBAAmBt5C,EAAQ1U,KAlB5D,GAAI8O,IACI4tC,WAAY,KACZgB,kBAAmB,SAAShpC,KAC5B7a,IAAK,SAASC,EAASkjD,KAG1B+Q,KACDA,MAgBJj/C,EAAKs+C,UAAY,UACjBt+C,EAAKw+C,UAAYY,EAEjBx6D,GAAG6B,OAAOuZ,EAAMo+C,GAChBx5D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu6D,oBAAoBn/C,EAAMi/C,KCzBrDr6D,GAAG8pD,0BAA4B,SAAS1uC,GACpC,YAEAA,GAAKs+C,UAAY,QACjBt+C,EAAKy+C,SAAW,KAEhB75D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGirD,4BAA4B7vC,QCVvDpb,GAAGu6D,oBAAsB,SAASf,EAAGa,GACjC,YAWA,SAASI,GAAyBz5C,GAC9B,GAAI05C,GAAkBt/C,EAAKuuC,UAAU3oC,GACjCpP,EAAS8oD,EAAgB7oD,YAAY,IAMzC,OAJID,GAAS,IACT8oD,EAAkBA,EAAgB5oD,OAAO,EAAGF,IAGzC8oD,EAGX,QAASC,GAAqB35C,GAC1B,GAAI45C,GAAWx/C,EAAKuuC,UAAU3oC,EAC9B,OAAOhhB,IAAG0R,aAAakpD,GAI3B,QAASC,GAAiBC,EAAoB95C,GAC1C,GACI+5C,GADAr+C,EAAUo+C,EAAmB/zD,KAGjB5C,UAAZuY,GAAyB1c,GAAG0H,QAAQgV,GAAS3W,OAAS,IACtDg1D,EAAgBJ,EAAqB35C,GAEf7c,SAAlB42D,IACAr+C,EAAUA,EAAU,IAAMq+C,GAG9B3/C,EAAK6uC,UAAUjpC,EAAQtE,IAG3BtB,EAAK8uC,sBAAsBlpC,GAAQ,GAIvC,QAASg6C,GAAyBjC,EAAS/3C,GACvCq5C,EAAqBL,oBAAoB15D,OAAOy4D,EAAS,OAAQ,WAC7D8B,EAAiB9B,EAAS/3C,KAKlC,QAASi6C,GAA6BlC,EAAS/3C,GAC3Cq5C,EAAqBL,oBAAoB15D,OAAOy4D,EAAS,QAAS,SAAS7jC,GAI1D,MAFFA,EAAMgmC,SAAWhmC,EAAMimC,QAG9BN,EAAiB9B,EAAS/3C,KAzDtC,GAAI5F,IACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBU,kBAAmB,SAAShpC,KAC5B2oC,UAAW,SAAS3oC,KACpBipC,UAAW,SAASjpC,EAAQtE,KAC5BwtC,sBAAuB,SAASlpC,EAAQmpC,KAwDhDnqD,IAAG6B,OAAOuZ,EAAMo+C,GAEhBp+C,EAAKy+C,SAAWz+C,EAAK4tC,WAAWgP,cAEhCh4D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu5D,eAAen+C,EAAMi/C,IAE5Cr6D,GAAG6B,OAAOw4D,GACNC,mBAAoB,SAASngD,EAAI7N,EAAQ8uD,GACrC,GAAIN,GAAqB1/C,EAAK4tC,WAAWqB,aAAalwC,EAEtDiB,GAAK8uC,sBAAsB/vC,GAAI,GAE/B2gD,EAAmB/zD,MAAQ0zD,EAAyBtgD,GAEhDihD,GACAN,EAAmBO,QAGvBL,EAAyBF,EAAoB3gD,GAC7C8gD,EAA6BH,EAAoB3gD,Q3CvF9BjV","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA,QCEV,GAAIC,IAAK,SAASC,GACd,YAEA,QACIC,KAAM,WAEF,MADAD,GAAQE,MAAMC,QAAU,OACjBC,MAIXC,OAAQ,SAASC,EAAMC,GAMnB,MALIP,GAAQQ,iBACRR,EAAQQ,iBAAiBF,EAAMC,GAAI,GAC5BP,EAAQS,aACfT,EAAQS,YAAY,KAAOH,EAAMC,GAE9B,WACHR,GAAGC,GAASU,OAAOJ,EAAMC,KAIjCG,OAAQ,SAASJ,EAAMC,GAMnB,MALIP,GAAQW,oBACRX,EAAQW,oBAAoBL,EAAMC,GAAI,GAC/BP,EAAQS,aACfT,EAAQY,YAAY,KAAON,EAAMC,GAE9BH,MAGXS,SAAU,SAASC,GAKf,QAAKA,IAKDd,IAAYc,IAIZd,EAAQa,SACDb,EAAQa,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwBf,OAOrDgB,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAahB,EAASiB,GACnCb,MAGXe,OAAQ,WAEJ,MADAnB,GAAQkB,WAAWE,YAAYpB,GACxBI,MAOXiB,IAAK,SAASC,GAEV,GAAqB,MAAjBtB,EAAQE,MACR,KAAM,IAAIH,IAAGwB,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1BxB,GAAQE,MAAMsB,SAAqD,mBAArBxB,GAAe,UACpEsB,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9EzB,GAAG6B,OAAO5B,EAAQE,MAAOoB,GAElBlB,MAGXyB,SAAU,SAASC,EAAMC,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAUH,EAAO,QACrC,OAAOE,GAAGE,KAAKlC,EAAQmC,eAAiBJ,IAAkBC,EAAGE,KAAKlC,EAAQkB,WAAWiB,aAGzFC,SAAU,SAASN,GAIf,MAHK/B,IAAGC,GAAS6B,SAASC,KACtB9B,EAAQmC,WAAa,IAAML,GAExB1B,MAGXiC,YAAa,SAASP,GAClB,GAAIE,GAAK,GAAIC,QAAO,QAAUH,EAAO,QAErC,OADA9B,GAAQmC,UAAYnC,EAAQmC,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtElC,MAGXmC,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASxC,EAAQ2C,cACV3C,EAAQ2C,cAAc,IAAMR,GAE9BnC,EAAQ4C,iBACN5C,EAAQ4C,iBAAiB,IAAMT,IAG1CM,EAAazC,EAAQ6C,qBAAqB,KAE1C9C,GAAG+C,KAAKL,EAAY,SAASM,EAAKC,GAC1BjD,GAAGiD,GAAKnB,SAASM,IACjBO,EAAOO,KAAKD,KAGbR,EAAQE,EAAO,GAAKA,IAG/BQ,gBAAiB,SAASf,GACtB,MAAOpC,IAAGC,GAASuC,WAAWJ,GAAW,IAG7CgB,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQpD,EAAQqD,WAEbD,GACoB,IAAnBA,EAAME,UACNH,EAASF,KAAKG,GAElBA,EAAQA,EAAMG,WAGlB,OAAOJ,IAGXK,QAAS,SAASC,GAGd,MAFAzD,GAAQ0D,UAAYD,EACpBzD,EAAQ2D,YAAcF,EACfrD,MAGXwD,UAAW,WACP,MAAO7D,IAAGC,GAASwD,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAI/D,GAAQ6D,eAEH7D,EAAQ6D,aAAaC,IAKkC,MAArD,WAAaE,KAAKhE,EAAQiE,aAAaH,KAG9CC,EAAU/D,EAAQ8D,GAEFI,SAAZH,GAKiC,MAA9B,WAAaC,KAAKD,QAMxC,WACG,YAEAhE,IAAGoE,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAOvE,IAAGwE,cAAcH,EAAOI,UAAUH,EAAMC,KAGnDvE,GAAGwE,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAASC,EAAMV,GACxB,GAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,IAyB3C,OAlBIM,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlCnB,EAAWJ,EAAaG,IAGnC9E,GAAGmG,IAAM,SAASC,EAASC,GACnBnB,OAAOoB,UACFD,GAAmB,SAAVA,EAKNnB,OAAOoB,QAAQD,GACfnB,OAAOoB,QAAQD,GAAOD,GAGtBlB,OAAOoB,QAAQH,IAAI,IAAME,EAAQ,KAAOD,GAR5ClB,OAAOoB,QAAQH,IAAIC,KAc/BpG,GAAGuG,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAASjD,UAAyD,oBAA7CkD,OAAOC,UAAUC,SAASC,KAAKJ,IAG5ExG,GAAG6G,WAAa,SAASL,GACrB,MAA6B,kBAAf,IASlBxG,GAAG8G,QAAU,SAASC,GAClB,MAAiD,mBAA1CN,OAAOC,UAAUC,SAASC,KAAKG,IACjCA,GAAS7B,OAAOY,aAAeiB,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBnB,aAIrF9F,GAAGkH,WAAa,SAASC,GACrB,MAAyD,kCAAlDV,OAAOC,UAAUC,SAASC,KAAKO,IAK1CnH,GAAGoH,WAAa,SAASC,GACrB,MAAyD,sBAAlDZ,OAAOC,UAAUC,SAASC,KAAKS,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CvH,GAAGwH,SAAW,SAASC,GACnB,MAAuD,oBAAhDhB,OAAOC,UAAUC,SAASC,KAAKa,IAG1CzH,GAAG0H,QAAU,SAASC,GAClB,MAAIC,QAAOlB,UAAUmB,KACVF,EAAOE,OAGXF,EAAOpF,QAAQ,aAAc,KAOxCvC,GAAG8H,OAAS,SAASC,GAEjB,GAAIC,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,GAC9CC,EAASL,EACTM,EAAmBD,EAAOzC,QAAQ,KAetC,OAbA3F,IAAG+C,KAAKiF,EAAM,SAAShF,EAAKC,GACxB,GAAIqF,GAAYF,EAAOG,UAAU,EAAGF,GAChCG,EAAWJ,EAAOG,UAAUF,EAAmB,EAMnD,IAJAD,EAASE,EAAYrF,EAAMuF,EAC3BH,EAAmBD,EAAOzC,QAAQ,KAAM0C,EAAmBpF,EAAI8C,QAG3DsC,EAAmB,EACnB,OAAO,IAIRD,GAGXpI,GAAGyI,OAAS,SAASC,GACjB,MAAOxD,QAAOyD,MAAsD,kBAA9ClC,OAAOC,UAAUC,SAASC,KAAK8B,IAGzD1I,GAAG4I,WAAa,SAASC,GACrB,MAAO3D,QAAO4D,UAA8D,sBAAlDrC,OAAOC,UAAUC,SAASC,KAAKiC,IAG7D7I,GAAG+I,cAAgB,SAASC,GACxB,MAAOhJ,IAAGyI,OAAOO,IAAqBhJ,GAAGiJ,QAAQD,IAGrDhJ,GAAGiJ,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAAS7I,GACxB,GAAI8I,GAAiB9I,EAAK+I,aAE1B,OAAIH,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAInE,OAAOqE,kBAC4C,8BAA/C9C,OAAOC,UAAUC,SAASC,KAAKsC,IAC3BA,EAAW3I,MAAQ6I,EAAaF,EAAW3I,WAKnD2I,EAAWM,SAC8B,UAArCN,EAAWM,QAAQF,eACfJ,EAAW3I,MAAQ6I,EAAaF,EAAW3I,QAS3DP,GAAGyJ,OAAS,SAASC,GACjB,GAAIxE,OAAOO,MAAsD,kBAA9CgB,OAAOC,UAAUC,SAASC,KAAK8C,GAC9C,OAAO,GAIf1J,GAAG2J,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAMrJ,KAAO,OAGU4D,SAAnByF,EAAMG,UACc,mBAATpB,OACa,mBAAbqB,WACoC,mBAAnChK,IAAGiK,oBAAqBC,QAI5ClK,GAAGiK,kBAAoB,WACnB,GAAI/E,OAAOiF,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOC,GAEH,MADArK,IAAGmG,IAAI,wCAAyC,SACzC,OAIfnG,GAAGsK,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMzE,OAAS,GAC5BwE,EAAaC,MAAM,GAAGC,kBAG9BzK,GAAG0K,wBAA0B,WACzB,OAAQ1K,GAAG2K,gBACP3K,GAAG2J,yBACuBxF,SAAzBwE,KAAKjC,UAAUwB,OAAsD/D,SAA/BwE,KAAKjC,UAAUkE,aAAyDzG,SAA5BwE,KAAKjC,UAAUmE,WAG1G7K,GAAG8K,UAAY,SAASC,EAAYC,EAAOC,GACvC,GAAIC,GAASH,EAAW7C,OAAS6C,EAAWF,UAAYE,EAAWH,WAEnE,OAAOM,GAAOtE,KAAKmE,EAAYC,EAAOC,IAG1CjL,GAAGmL,iBAAmB,SAASnE,GAC3B,GAAIoE,GAAa,GACbC,EAAQ,GAAIrF,YAAWgB,EAY3B,OAVAhH,IAAG+C,KAAKsI,EAAO,SAASrI,EAAKsI,GACzB,GAAIC,GAAeD,EAAI3E,SAAS,GAE5B4E,GAAaxF,OAAS,IACtBwF,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXpL,GAAGwL,cAAgB,SAASC,EAAMC,EAAa3F,GAC3C,GAAI4F,GAAc3L,GAAG8K,UAAUW,EAAMC,EAAaA,EAAc3F,GAC5D6F,EAAa,GAAIC,YACjBC,EAAU,GAAI9L,IAAG+L,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQjM,GAAGmL,iBAAiBS,EAAWjJ,UAGnDiJ,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGX9L,GAAG6B,OAAS,SAASY,EAAO4J,EAAQC,GAahC,MAZAtM,IAAG+C,KAAKsJ,EAAQ,SAASE,EAAMtJ,GACvBqJ,GAAgBtM,GAAGuG,SAAStD,IACRkB,SAAhB1B,EAAM8J,KACN9J,EAAM8J,OAEVvM,GAAG6B,OAAOY,EAAM8J,GAAOtJ,GAAK,IAG5BR,EAAM8J,GAAQtJ,IAIfR,GAaXzC,GAAGwM,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACAC,EAASF,EAASC,EAUtB,OARA3M,IAAG+C,KAAK6J,EAAQ,SAASC,EAAaC,GACN3I,SAAxBsI,EAAOI,KACPF,EAAOE,GAAeJ,EAAOI,IAGjCJ,EAAOI,GAAeC,IAGnBL,GAMXzM,GAAG2F,QAAU,SAASoH,EAAKC,EAAKC,GAC5B,GAAIF,EAAIpH,QACJ,MAAOoH,GAAIpH,QAAQqH,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAIhH,MAMd,KAJIkH,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIXjN,GAAGoN,YAAc,WACb,MAAO,uCAAuC7K,QAAQ,QAAS,SAAS8K,GAEpE,GAAIC,GAAoB,GAAhB3L,KAAK4L,SAAgB,EAAGC,EAAS,KAALH,EAAWC,EAAS,EAAJA,EAAU,CAC9D,OAAOE,GAAE7G,SAAS,OAM1B3G,GAAGyN,GAAK,WACJ,MAAOC,WAAUC,UAAUhI,QAAQ,WAAY,GAC3C+H,UAAUC,UAAUhI,QAAQ,cAAe,GAGnD3F,GAAG4N,IAAM,WACL,MAAOF,WAAUC,UAAUhI,QAAQ,aAAc,GAGrD3F,GAAG6N,IAAM,WACL,MAAOH,WAAUC,UAAUhI,QAAQ,aAAc,GAGrD3F,GAAG8N,KAAO,WACN,MAAOJ,WAAUC,UAAUhI,QAAQ,cAAe,GAGtD3F,GAAG+N,KAAO,WACN,MAAO/N,IAAGyN,MAAQC,UAAUC,UAAUhI,QAAQ,YAAa,GAG/D3F,GAAGgO,KAAO,WACN,MAAON,WAAUC,UAAUhI,QAAQ,SAAW,GAGlD3F,GAAGiO,OAAS,WACR,MAA4B9J,UAArBuJ,UAAUQ,QAAwBR,UAAUQ,OAAOvI,QAAQ,YAAa,GAGnF3F,GAAGmO,OAAS,WACR,MAA4BhK,UAArBuJ,UAAUQ,QAAwBR,UAAUQ,OAAOvI,QAAQ,aAAc,GAGpF3F,GAAGoO,MAAQ,WACP,MAA4BjK,UAArBuJ,UAAUQ,QAAwBR,UAAUQ,OAAOvI,QAAQ,YAAa,GAGnF3F,GAAGqO,QAAU,WACT,OAASrO,GAAGgO,SAAWhO,GAAG+N,QAAUL,UAAUC,UAAUhI,QAAQ,cAAe,GAA2BxB,SAArBuJ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrIlO,GAAGsO,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrBvO,GAAGwO,QAAU,WACT,MAAOd,WAAUC,UAAUrE,cAAc3D,QAAQ,cAAe,GAKpE3F,GAAG2K,aAAe,WACd,MAAO3K,IAAGwO,WAAad,UAAUC,UAAUrE,cAAc3D,QAAQ,UAAY,GAGjF3F,GAAGyO,KAAO,WACN,MAAOzO,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,aAAc,GAGjE3F,GAAG2O,KAAO,WACN,MAAO3O,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,aAAc,GAGjE3F,GAAG4O,KAAO,WACN,MAAO5O,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,aAAc,GAIjE3F,GAAG6O,OAAS,WACR,MAAO7O,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,eAAgB,GAGnE3F,GAAG0O,IAAM,WAEL,MAAOhB,WAAUC,UAAUhI,QAAQ,WAAY,GACxC+H,UAAUC,UAAUhI,QAAQ,WAAY,GACxC+H,UAAUC,UAAUhI,QAAQ,aAAc,GAGrD3F,GAAG8O,UAAY,WACX,MAAO9O,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,YAAa,GAGhE3F,GAAG+O,UAAY,WACX,MAAO/O,IAAG0O,QAAU1O,GAAG8O,aAAepB,UAAUC,UAAUhI,QAAQ,aAAc,GAGpF3F,GAAGgP,iBAAmB,WAClB,MAAOhP,IAAG0O,QAAU1O,GAAG8O,cAAgB9O,GAAG+O,aAM9C/O,GAAGiP,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxBnP,GAAGoP,UAAa,WACZ,GAAIC,GAAMxF,SAASC,cAAc,MACjC,OAAO,UAASwF,GACZD,EAAIE,UAAYD,CAChB,IAAIrP,GAAUoP,EAAI/L,UAElB,OADA+L,GAAIhO,YAAYpB,GACTA,MAKfD,GAAG+C,KAAO,SAASyM,EAAcC,GAC7B,GAAIC,GAAYC,CAEhB,IAAIH,EAEA,GAAItK,OAAO0K,SAAWJ,EAAavI,cAAgB/B,OAAO0K,QACtD,IAAKF,EAAa,EAAGA,EAAaF,EAAazJ,SAC3C4J,EAASF,EAASD,EAAaK,IAAIH,GAAaF,EAAaM,QAAQN,EAAaK,IAAIH,KAClFC,KAAW,GAFoCD,SAStD,IAAI1P,GAAG8G,QAAQ0I,IAAiBxP,GAAGkH,WAAWsI,IAAiBxP,GAAGoH,WAAWoI,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAazJ,SAC3C4J,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GAFoCD,SAOtD,IAAI1P,GAAGwH,SAASgI,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAazJ,SAC3C4J,EAASF,EAASC,EAAYF,EAAaO,OAAOL,IAC9CC,KAAW,GAFoCD,SAQvD,KAAKA,IAAcF,GACf,GAAI/I,OAAOC,UAAUyG,eAAevG,KAAK4I,EAAcE,KACnDC,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GACX,OASxB3P,GAAGgQ,KAAO,SAASC,EAASC,GACxB,GAAIlQ,GAAG6G,WAAWoJ,GAAU,CACxB,GAAIjI,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,EAElD,OAAO,YACH,GAAIgI,GAAUnQ,GAAG6B,UAAWmG,EAI5B,OAHIG,WAAUpC,SACVoK,EAAUA,EAAQC,OAAOnI,MAAMvB,UAAUwB,MAAMtB,KAAKuB,aAEjD8H,EAAQI,MAAMH,EAASC,IAItC,KAAM,IAAI3O,OAAM,wCAmBpBxB,GAAGsQ,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQrO,KAAKqO,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAWxN,KACa,gBAAZ2N,GACF7Q,GAAGsQ,QAAQO,EAASE,GAAU,GACe,sBAA5CtK,OAAOC,UAAUC,SAASC,KAAKiK,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAKxO,KAAKqO,GAAU,MAAMrO,KAAKqO,GAAS,GAAK,IAAM,IAC7DE,EAAWxN,KAAKsN,GAChBE,EAAWxN,KAAKlD,GAAGsQ,QAAQC,KACqB,mBAAxC9J,OAAOC,UAAUC,SAASC,KAAK2J,IAA8C,mBAARA,GAC7EvQ,GAAG+C,KAAKwN,EAAK,SAASvN,EAAKC,GACvB2N,EAAI3N,EAAKD,KAEU,mBAARuN,IAAiC,OAARA,GAAiC,gBAARA,GACjEvQ,GAAG+C,KAAKwN,EAAK,SAAShE,EAAMtJ,GACxB2N,EAAI3N,EAAKsJ,KAGbmE,EAAWxN,KAAK8N,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBpO,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7BvC,GAAGkR,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAInH,WAGnBhK,GAAG+C,KAAKwN,EAAK,SAASV,EAAK5M,GACvB4M,EAAMuB,EAAeA,EAAe,IAAMvB,EAAM,IAAMA,EAElD7P,GAAGuG,SAAStD,GACZjD,GAAGkR,aAAajO,EAAKkO,EAAUtB,GAE1B7P,GAAG6G,WAAW5D,GACnBkO,EAAS5L,OAAOsK,EAAK5M,KAGrBkO,EAAS5L,OAAOsK,EAAK5M,KAItBkO,GAGXnR,GAAGqR,WAAa,SAASd,EAAKe,GAC1B,GAAI1H,EAeJ,OAbK0H,KACDA,EAAOzH,SAASC,cAAc,SAGlC9J,GAAGkR,aAAaX,GACZhL,OAAQ,SAASsK,EAAK5M,GAClB2G,EAAQC,SAASC,cAAc,SAC/BF,EAAM2H,aAAa,OAAQ1B,GAC3BjG,EAAM2H,aAAa,QAAStO,GAC5BqO,EAAKE,YAAY5H,MAIlB0H,GAOXtR,GAAGyR,UAAY,SAASC,MAEpB,MAAIxM,QAAOyM,MAAQ3R,GAAG6G,WAAW8K,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjC1R,GAAG8R,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAAShM,OAASiM,IAIzDhS,GAAGmS,YAAc,SAASC,GAGtB,MAAIpS,IAAGiJ,QAAQmJ,GAEJA,EAAgBrL,MAAMxE,QAAQ,YAAa,IAE7CvC,GAAGyI,OAAO2J,IACkB,OAA7BA,EAAgBC,UAAkDlO,SAA7BiO,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgBrQ,MAM3B/B,GAAGsS,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIXnS,OAAQ,WACJ,GAAI0H,GAAOG,SAEX9H,MAAKsS,YAAY3S,GAAGgI,EAAK,IAAI1H,OAAO+P,MAAMhQ,KAAM4H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,MAI1FwK,YAAa,SAASC,GAClBL,EAAUrP,KAAK0P,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAO7S,MAGY,mBAAX+S,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAUhT,GAGjBD,OAAOC,GAAKA,MCRnB,WACG,YAEAA,IAAGwB,MAAQ,SAAS4E,GAChB/F,KAAK+F,QAAU,kBAAoBpG,GAAGiT,QAAU,KAAO7M,GAG3DpG,GAAGwB,MAAMkF,UAAY,GAAIlF,UCV7BxB,GAAGiT,QAAU,SCAbjT,GAAGkT,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAYvJ,SAASC,cAAc,SACnCsJ,EAAU7S,KAAO,OACjBP,GAAGoT,GAAWlT,OAEVkT,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQxT,GAAGmO,UAAYnO,GAAGoO,UAC+CjK,SAArEuJ,UAAUC,UAAU8F,MAAM,uCAIlC,QAASC,KACL,OAAQ1T,GAAGmO,UAAYnO,GAAGoO,UAC+CjK,SAArEuJ,UAAUC,UAAU8F,MAAM,uCAIlC,QAASE,KACL,GAAIzO,OAAOiF,eAAgB,CACvB,GAAIyJ,GAAM5T,GAAGiK,mBAGb,OAA+B9F,UAAxByP,EAAIC,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiC3P,UAA1Be,OAAO6O,eAKlB,QAASC,KACL,QAAIL,KAIGG,IAGX,QAASG,KAEL,MAA2D9P,UAApD0F,SAASC,cAAc,SAASoK,gBAG3C,QAASC,KACL,IACI,QAASjP,OAAOkP,cAEZpU,GAAG6G,WAAW3B,OAAOkP,aAAaC,SAE1C,MAAOhK,GAEH,OAAO,GAIf,QAASiK,KACL,GAAIC,GAAO1K,SAASC,cAAc,OAElC,QAAQ,aAAeyK,IAAS,eAAiBA,IAAQ,UAAYA,MAChEvU,GAAGwO,YAAcxO,GAAG0O,MAhG7B,GAAI8F,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAnCAd,GAAoBrB,IAEpBwB,EAA4BH,GAAqBxU,GAAG2J,uBAEpD8K,EAAyBE,IAA8B3U,GAAG2K,eAE1D+J,EAAmBC,GAA6BL,IAEhDM,EAAqBF,GAAoBlB,IAEzCqB,EAAmBF,GAA6B3U,GAAG0K,0BAEnDoK,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BjB,IAEtDsB,EAAqBR,IAA6CrQ,SAAvBe,OAAOqQ,aAA6BZ,GAE/EO,EAA4BvB,IAE5BsB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmDxQ,SAAtBe,OAAO2G,WAE5DyJ,EAA0B,WACtB,QAAIX,KACQ3U,GAAG2K,iBAAmB3K,GAAG8O,iBAMrC0G,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiB7Q,OAAO8Q,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAc3W,GAAGiO,SACjB2I,0BAA2B5W,GAAG0O,MAC9BmI,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxB/U,GAAGkX,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQpX,GAAG6G,WAAWsQ,EAAaC,QAG9EpX,GAAG+L,QAAU,WACT,YAEA,IAAIsL,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZ1X,IAAG6B,OAAOxB,MACN+W,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiBrU,KAAKyU,GAEtBC,GACAJ,EAAiBtU,KAAK0U,IAGrBF,KAAU,EACfE,GAAaA,EAAUvH,MAAM,KAAMiH,GAE9BK,GACLA,EAAUtH,MAAM,KAAMgH,GAGnBhX,MAGXwX,KAAM,SAASpI,GAQX,MAPc,KAAViI,EACAD,EAAcvU,KAAKuM,GAGnBA,EAASY,MAAM,KAAsBlM,SAAhBmT,EAA4BD,EAAcC,GAG5DjX,MAGX4L,QAAS,WAgBL,MAfAyL,GAAQ,EACRL,EAAclP,UAEVoP,EAAiBxR,QACjB/F,GAAG+C,KAAKwU,EAAkB,SAASvU,EAAKyM,GACpCA,EAASY,MAAM,KAAMgH,KAIzBI,EAAc1R,QACd/F,GAAG+C,KAAK0U,EAAe,SAASzU,EAAKyM,GACjCA,EAASY,MAAM,KAAMgH,KAItBhX,MAGX8L,QAAS,WAgBL,MAfAuL,IAAQ,EACRJ,EAAcnP,UAEVqP,EAAiBzR,QACjB/F,GAAG+C,KAAKyU,EAAkB,SAASxU,EAAKyM,GACpCA,EAASY,MAAM,KAAMiH,KAIzBG,EAAc1R,QACd/F,GAAG+C,KAAK0U,EAAe,SAASzU,EAAKyM,GACjCA,EAASY,MAAM,KAAMiH,KAItBjX,SC3EnBL,GAAG8X,UAAY,SAASC,EAAeC,GACnC,YAEAhY,IAAG6B,OAAOxB,MACN0X,cAAeA,EAEfE,OAAQ,WACJ,MAAOD,GAASD,OCF5B/X,GAAGkY,aAAe,SAASC,GACvB,YA0CA,SAASC,KACL,GAAIxO,GAAQC,SAASC,cAAc,QAmEnC,OAjEAF,GAAM2H,aAAavR,GAAGkY,aAAaG,oBAAqBC,GACxD1O,EAAM2H,aAAa,QAASgH,EAAQC,OAEpCC,EAAKC,YAAYH,EAAQxO,SAAUH,GAE/B2O,EAAQI,SAAW3Y,GAAGkT,kBAAkBiD,iBAExCvM,EAAM2H,aAAa,kBAAmB,IAGtCgH,EAAQK,aACRhP,EAAM2H,aAAa,SAAUgH,EAAQK,aAGzChP,EAAM2H,aAAa,OAAQ,QAC3B3H,EAAM2H,aAAa,OAAQgH,EAAQxW,MAEnC/B,GAAG4J,GAAOtI,KACNuX,SAAU,WAIVC,MAAO,EACPC,IAAK,EACLC,WAAY,QASZC,SAAUjZ,GAAGyN,OAASzN,GAAG6N,MAAQ,SAAW,QAC5CqL,OAAQ,EACRC,QAAS,EACTC,OAAQ,UACR3X,QAAS,KAKZzB,GAAG4N,OAAS5N,GAAG4J,GAAOtI,KAAK+X,OAAQ,SAEpCd,EAAQtY,QAAQuR,YAAY5H,GAE5B0P,EAAehZ,OAAOsJ,EAAO,SAAU,WACnC2O,EAAQgB,SAAS3P,KAIrB0P,EAAehZ,OAAOsJ,EAAO,YAAa,WACtC5J,GAAGuY,EAAQtY,SAASoC,SAASkW,EAAQiB,cAEzCF,EAAehZ,OAAOsJ,EAAO,WAAY,WACrC5J,GAAGuY,EAAQtY,SAASqC,YAAYiW,EAAQiB,cAG5CF,EAAehZ,OAAOsJ,EAAO,QAAS,WAClC5J,GAAGuY,EAAQtY,SAASoC,SAASkW,EAAQkB,cAEzCH,EAAehZ,OAAOsJ,EAAO,OAAQ,WACjC5J,GAAGuY,EAAQtY,SAASqC,YAAYiW,EAAQkB,cAGrC7P,EA5GX,GAgCIA,GAAO0O,EAhCPG,EAAOpY,KAEPiZ,EAAiB,GAAItZ,IAAGsS,eAExBiG,GAEIK,YAAa,KAGb3Y,QAAS,KAETwZ,WAAY,yBAGZd,SAAS,EAGTa,WAAY,yBAEZE,4BAA4B,EAG5B3P,UAAU,EAGVhI,KAAM,SAGNwX,SAAU,SAAS3P,KAEnB4O,MAAO,KAKfxY,IAAG6B,OAAO0W,EAASJ,GAEnBG,EAAWtY,GAAGoN,cA2EdpN,GAAGuY,EAAQtY,SAASqB,KAChBuX,SAAU,WACVc,SAAU,SAEVC,UAAW,QAIf5Z,GAAG6B,OAAOxB,MACNwZ,SAAU,WACN,MAAOjQ,IAGXkQ,YAAa,WACT,MAAOxB,IAGXI,YAAa,SAASqB,EAAYC,GAC9B,GAAIpQ,GAAQoQ,GAAY3Z,KAAKwZ,UAKzBtB,GAAQmB,4BAA8B1Z,GAAG4O,SAAW5O,GAAG8O,aAAe9O,GAAGgP,oBACzEpF,EAAM2H,aAAa,WAAY,IAI3BwI,EACAnQ,EAAM2H,aAAa,WAAY,IAG/B3H,EAAMqQ,gBAAgB,aAKlCC,eAAgB,SAAStB,GACjBA,IAAgBL,EAAQK,aACxBhP,EAAM2H,aAAa,SAAUqH,IAIrCuB,MAAO,WACCvQ,EAAMzI,YACNnB,GAAG4J,GAAOxI,SAGdpB,GAAGuY,EAAQtY,SAASqC,YAAYiW,EAAQkB,YACxC7P,EAAQ,KACRA,EAAQwO,OAIhBxO,EAAQwO,KAGZpY,GAAGkY,aAAaG,oBAAsB,eCxLtCrY,GAAGoa,WAAa,SAASC,GACrB,YAQA,SAASC,GAAaC,GAClB,GAAIva,GAAG8G,QAAQyT,GAAU,CACrB,GAAIC,KAMJ,OAJAxa,IAAG+C,KAAKwX,EAAS,SAASvX,EAAKyX,GAC3BD,EAAQtX,KAAK8B,EAAKyV,MAGfD,EAGX,MAAOxV,GAAKuV,GAGhB,QAASG,GAAeC,GACpB,GAAI3a,GAAG8G,QAAQ6T,GAAQ,CACnB,GAAIH,KAMJ,OAJAxa,IAAG+C,KAAK4X,EAAO,SAAS3X,EAAK4X,GACzBJ,EAAQtX,KAAK8B,EAAK6V,EAAOD,OAGtBJ,EAGX,MAAOxV,GAAK6V,EAAOF,IAGvB,QAASG,GAAgBC,GACrB,GAAIC,MACAC,KAAc7K,OAAO2K,EAYzB,OAVA/a,IAAG+C,KAAKkY,EAAU,SAASC,EAAOC,GAC9B,GAAIC,GAAsBC,EAASF,EAEPhX,UAAxBiX,GACApb,GAAG+C,KAAKqY,EAAqB,SAAStK,EAAGwK,GACrCN,EAAc9X,KAAK8B,EAAKsW,QAK7BN,EAhDX,GAAIhW,MACA6V,KACAQ,KACAE,KACAC,IA+CJxb,IAAG6B,OAAOxB,MAeNob,QAAS,SAASC,GACd,GAAIX,GAASW,EAAKX,QAAU/a,GAAG+a,OAAOY,WAClClB,EAAKzV,EAAK9B,MACNnB,KAAM2Z,EAAK3Z,KACX6Z,aAAcF,EAAK3Z,KACnB6Y,KAAMc,EAAKd,KACXiB,KAAmB,MAAbH,EAAKG,MAAe,EAAKH,EAAKG,KACpCd,OAAQA,IACP,CA8BT,OA5BIW,GAAKI,UACL9W,EAAKyV,GAAIqB,QAAUJ,EAAKI,QAEQ3X,SAA5BqX,EAAUE,EAAKI,WACfN,EAAUE,EAAKI,aAEnBN,EAAUE,EAAKI,SAAS5Y,KAAKuX,IAG7BiB,EAAKK,eACL/W,EAAKyV,GAAIsB,aAAeL,EAAKK,aAEa5X,SAAtCoX,EAAeG,EAAKK,gBACpBR,EAAeG,EAAKK,kBAExBR,EAAeG,EAAKK,cAAc7Y,KAAKuX,IAG3CzV,EAAKyV,GAAIA,GAAKA,EACdI,EAAOa,EAAKd,MAAQH,EAEKtW,SAArBkX,EAASN,KACTM,EAASN,OAEbM,EAASN,GAAQ7X,KAAKuX,GAEtBJ,EAAc2B,eAAevB,EAAI,KAAMM,GAEhCN,GAGXwB,SAAU,SAASC,GACf,MAAIlc,IAAGuG,SAAS2V,IAAmBlX,EAAKe,OACV5B,SAAtB+X,EAAezB,GACRH,EAAa4B,EAAezB,IAGNtW,SAAxB+X,EAAetB,KACbF,EAAewB,EAAetB,MAGhCsB,EAAenB,OACbD,EAAgBoB,EAAenB,QADrC,OAKE/a,GAAG6B,UAAWmD,GAAM,IAInCmV,MAAO,WACHnV,KACA6V,KACAQ,KACAG,MAGJW,UAAW,SAAS1B,EAAI2B,GACpB,GAAIC,GAAYrX,EAAKyV,GAAIM,OACrBuB,EAAyBtc,GAAG2F,QAAQ0V,EAASgB,GAAY5B,EAE7DY,GAASgB,GAAWE,OAAOD,EAAwB,GAEnDtX,EAAKyV,GAAIM,OAASqB,EAEUjY,SAAxBkX,EAASe,KACTf,EAASe,OAEbf,EAASe,GAAWlZ,KAAKuX,GAEzBJ,EAAc2B,eAAevB,EAAI4B,EAAWD,IAGhDI,YAAa,SAAS/B,EAAIgC,GACtB,GAAIC,GAAU1X,EAAKyV,GAAIG,IAEvB5V,GAAKyV,GAAIG,KAAO6B,EAChB5B,EAAO4B,GAAWhC,QACXI,GAAO6B,IAGlBC,WAAY,SAASlC,EAAImC,GACrB5X,EAAKyV,GAAI1Y,KAAO6a,GAGpBC,WAAY,SAASpC,EAAIqC,GACrB9X,EAAKyV,GAAIoB,KAAOiB,GAIpBC,YAAa,SAASC,EAAUC,GAC5BjY,EAAKgY,GAAUC,SAAWA,GAG9BC,mBAAoB,SAASzC,GACzB,GAAIsB,GAAe/W,EAAKyV,GAAIsB,YAE5B,OAAIA,GACOR,EAAeQ,OAK9BoB,cAAe,SAAS1C,GACpB,GAAIqB,GAAU9W,EAAKyV,GAAIqB,OAEvB,OAAON,GAAUM,OAK7B9b,GAAG+a,QACCY,WAAY,aACZyB,UAAW,YACXC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,UAAW,YACXC,gBAAiB,kBACjBC,kBAAmB,oBACnBC,cAAe,gBACfC,cAAe,gBACfC,SAAU,WACVC,QAAS,WCxMZ,WACG,YAEA/d,IAAGge,eAECC,SAAU,SAASC,EAAiBC,EAAQC,GACxC/d,KAAKge,SAASH,EAAiBC,EAAQC,IAG3CE,gBAAiB,SAASC,GACtB,GAAI9F,GAAOpY,IAEXL,IAAG+C,KAAKwb,EAAgB,SAASrD,EAAOsD,GACpC/F,EAAKgG,eAAeD,MAI5BH,SAAU,SAASrZ,EAAMmZ,EAAQC,GAC7B/d,KAAKqe,kCAEL,IAAI5C,GAAqC,IAA3Bzb,KAAKse,WAAW5Y,OAAe/F,GAAGoN,cAAgB/M,KAAKue,gBAEjEC,EAAc7e,GAAGgQ,KAAK,SAASvE,GAC3BpL,KAAKye,gBACDrT,KAAMA,EACN1J,KAAM1B,KAAK0e,SAASC,MAAMC,aAC3BnD,EAASoD,IACb7e,MAEH8e,EAAkBnf,GAAGgQ,KAAK,SAASoP,GAC/B/e,KAAKye,eAAeM,EAAUtD,EAASoD,IACxC7e,MAEHgf,EAAgBrf,GAAGgQ,KAAK,SAAS3L,GAC7B,GAAIoH,GAAOzL,GAAGoE,aAAaC,EAE3BhE,MAAKye,gBACDrT,KAAMA,EACN1J,KAAM1B,KAAK0e,SAASC,MAAMC,YAAc,QACzCnD,EAASoD,IACb7e,MAEHif,EAAoBtf,GAAGgQ,KAAK,SAASuP,GACjC,GAAIC,GAAoBD,EAAWhb,SAAWgb,EAAWhb,QAAU,IAC/DkH,EAAOzL,GAAGoE,aAAamb,EAAWlb,OAAQkb,EAAWhf,KAAMif,EAE/Dnf,MAAKye,gBACDrT,KAAMA,EACN1J,KAAMwd,EAAWxd,MAClB+Z,EAASoD,IACb7e,MAEHof,EAAqBzf,GAAGgQ,KAAK,SAAS0P,GAClC,GAAI1f,GAAGiJ,QAAQyW,IAAgB1f,GAAGkT,kBAAkBsC,cAAe,CAC/D,GAAImK,GAAQ1X,MAAMvB,UAAUwB,MAAMtB,KAAK8Y,EAAYC,OAC/ClH,EAAOpY,IAEXL,IAAG+C,KAAK4c,EAAO,SAAS3c,EAAK4c,GACzBnH,EAAKqG,eAAec,EAAM9D,EAASoD,SAIvC7e,MAAKye,eAAeY,EAAa5D,EAASoD,IAE/C7e,MAEHwf,EAAgB,WACR7f,GAAG4I,WAAW5D,KACdA,EAAOiD,MAAMvB,UAAUwB,MAAMtB,KAAK5B,IAEtCA,KAAUoL,OAAOpL,IAGrByT,EAAOpY,KACP6e,IAEJ7e,MAAKue,gBAAkB9C,EAEnB9W,IACA6a,IAEA7f,GAAG+C,KAAKiC,EAAM,SAAShC,EAAK8c,GACpB9f,GAAG+I,cAAc+W,GACjBL,EAAmBK,GAEd9f,GAAGyJ,OAAOqW,GACfjB,EAAYiB,GAEP9f,GAAGuG,SAASuZ,GACbA,EAAcrU,MAAQqU,EAAc/d,KACpCod,EAAgBW,GAEXA,EAAczb,QAAUyb,EAAc/d,MAC3Cud,EAAkBQ,GAGjBA,EAActW,SAAmD,WAAxCsW,EAActW,QAAQF,cACpD+V,EAAcS,GAGdrH,EAAKtS,IAAI2Z,EAAgB,6CAA8C,UAI/Ezf,KAAK8F,IAAI,YAAc+Y,EAAcnZ,OAAS,WAC9C1F,KAAK0f,uBAAuBb,EAAef,EAAQC,KAI3D4B,OAAQ,SAASvF,GACbpa,KAAK4f,SAASD,OAAOvF,IAGzByF,UAAW,WACP,GAAIC,MACA1H,EAAOpY,IAEXL,IAAG6B,OAAOse,EAAe9f,KAAKse,YAC9B3e,GAAG+C,KAAKod,EAAe,SAASnd,EAAKod,GACjC3H,EAAKuH,OAAOI,KAGhB/f,KAAK4f,SAASC,aAGlBG,iBAAkB,WACdhgB,KAAKse,eAGT2B,eAAgB,SAAS7F,GACrB,GAAI8F,GAAalgB,KAAKmgB,YAAYvE,UAAUxB,GAAIA,GAEhD,UAAKza,GAAGkT,kBAAkBqD,QAAUlW,KAAK0e,SAASpJ,SAAS8K,WAIvDF,EAAWxF,SAAW/a,GAAG+a,OAAOyC,QAChCnd,KAAK8F,IAAInG,GAAG8H,OAAO,yDAA0D2S,EAAIpa,KAAKqgB,QAAQjG,KAC9Fpa,KAAKsgB,YAAYlG,IACV,IAGPpa,KAAK8F,IAAInG,GAAG8H,OAAO,sDAAuD2S,EAAIpa,KAAKqgB,QAAQjG,IAAM,UAG9F,KAGXmG,WAAY,SAASnG,GACjB,MAAOpa,MAAKwgB,gBAAgBpG,IAIhCqG,UAAW,SAASC,GAChB,MAAO1gB,MAAK4f,SAASe,QAAQD,IAOjCE,cAAe,SAASC,EAAQC,EAAaC,EAASC,EAAYC,GAC9D,GACIC,GAAWhJ,EADXiJ,EAAkB,GAAIxhB,IAAG+L,OAqC7B,OAlCI1L,MAAKohB,iBACLF,EAAYlhB,KAAKqhB,eAAeR,GAChC3I,GACI+I,qBAAsBA,EACtBF,QAASA,EAAU,EAAIA,EAAU,KACjCO,MAAOP,EAAU,IAKhBC,GAAcrhB,GAAGkT,kBAAkBkD,gBACpCmL,EAAYlhB,KAAKuhB,QAAQV,IAIZ,MAAbK,EACAC,EAAgBrV,SAAS0V,UAAWV,EAAa9W,MAAO,2BAGxDhK,KAAKohB,gBAAgBK,SAASP,EAAWJ,EAAa5I,GAASnB,KAC3D,SAAiB2K,GACbP,EAAgBvV,QAAQ8V,IAG5B,SAAiBF,EAAWG,GACxBR,EAAgBrV,SAAS0V,UAAWA,EAAWxX,MAAO2X,GAAU,oCAM5ER,EAAgBrV,SAAS0V,UAAWV,EAAa9W,MAAO,mCAGrDmX,GAGXS,UAAW,SAASf,GAChB,MAAO7gB,MAAK6hB,WAAW7hB,KAAK8hB,qBAAqBjB,KAGrDkB,YAAa,SAASlB,GAClB,MAAO7gB,MAAKgiB,eAAeC,IAAIpB,IAGnCU,QAAS,SAASb,GACd,MAAO1gB,MAAK4f,SAAS2B,QAAQb,IAAiB,MAGlDwB,cAAe,WACX,MAAOliB,MAAKmgB,YAAYvE,UACpBlB,QACI/a,GAAG+a,OAAO0C,UACVzd,GAAG+a,OAAO2C,gBACV1d,GAAG+a,OAAOuC,UAEfvX,QAGP2a,QAAS,SAASjG,GACd,MAAOpa,MAAKmgB,YAAYvE,UAAUxB,GAAIA,IAAK1Y,MAI/CygB,YAAa,SAAS/H,GAClB,GAAIgI,GAAkBpiB,KAAKqiB,YAAYjI,GAAIA,IACvCwC,EAAW,IAQf,OANIwF,IACiCte,SAA7Bse,EAAgBxF,WAChBA,EAAWwF,EAAgBxF,UAI5BA,GAGX0F,sBAAuB,WACnB,MAAOtiB,MAAK4f,SAAS0C,yBAGzBC,QAAS,SAASnI,GACd,MAAOpa,MAAKmgB,YAAYvE,UAAUxB,GAAIA,IAAKoB,MAG/CgH,cAAe,WACX,MAAOxiB,MAAKyiB,cAGhBC,yBAA0B,WACtB,GAAIC,GAAe3iB,KAAK4iB,iBAExB,OAAID,GAAe,EACRA,EAAe3iB,KAAK6iB,qBAGxB,MAGXR,WAAY,SAASxG,GACjB,MAAO7b,MAAKmgB,YAAYvE,SAASC,IAGrCiH,QAAS,SAAS1I,GACd,MAAOpa,MAAKmgB,YAAYvE,UAAUxB,GAAIA,IAAKG,MAG/CzU,IAAK,SAAS4B,EAAK1B,IACXhG,KAAK0e,SAASqE,OAAW/c,GAAmB,SAAVA,EAG7BA,GAAmB,SAAVA,GACdrG,GAAGmG,IAAI,kBAAoBnG,GAAGiT,QAAU,KAAOlL,EAAK1B,GAHpDrG,GAAGmG,IAAI,kBAAoBnG,GAAGiT,QAAU,KAAOlL,IAQvDsb,YAAa,SAAS5I,GAClB,GAAI8F,GAAalgB,KAAKmgB,YAAYvE,UAAUxB,GAAIA,GAEhD,KAAKza,GAAGkT,kBAAkBqD,QAAUlW,KAAK0e,SAASpJ,SAAS8K,QACvD,OAAO,CAIX,IAAIzgB,GAAG2F,SAAS3F,GAAG+a,OAAO0C,UAAWzd,GAAG+a,OAAO2C,iBAAkB6C,EAAWxF,SAAW,EAAG,CACtF,GAAI1a,KAAK4f,SAAS1J,MAAMkE,GAEpB,MADApa,MAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAOyC,SAClC,CAGPnd,MAAK8F,IAAInG,GAAG8H,OAAO,mCAAoC2S,EAAIpa,KAAKqgB,QAAQjG,IAAM,aAIlFpa,MAAK8F,IAAInG,GAAG8H,OAAO,wDAAyD2S,EAAIpa,KAAKqgB,QAAQjG,IAAM,QAGvG,QAAO,GAGXN,MAAO,WACH9Z,KAAK8F,IAAI,yBAET9F,KAAK4f,SAAS9F,QACd9Z,KAAKse,cACLte,KAAKijB,gBACLjjB,KAAKkjB,kBACLljB,KAAKmjB,mBACLnjB,KAAKqhB,kBAEL1hB,GAAG+C,KAAK1C,KAAKojB,SAAU,SAASzgB,EAAK0gB,GACjCA,EAAOvJ,UAGX9Z,KAAKsjB,aAAaxJ,QAClB9Z,KAAKgiB,eAAelI,QACpB9Z,KAAK6iB,qBAAuB,EAC5B7iB,KAAKyiB,aAAe,EACpBziB,KAAKmgB,YAAYrG,QACjB9Z,KAAK8hB,wBAEL9hB,KAAKujB,eAAiBvjB,KAAKujB,cAAczJ,QACzC9Z,KAAK0e,SAAS8E,QAAQC,gBAAkBzjB,KAAK0jB,sBAE7C1jB,KAAK2jB,kCACL3jB,KAAK4jB,+BAEL5jB,KAAK6jB,gBAAkB7jB,KAAK6jB,eAAe/J,SAG/CgK,MAAO,SAAS1J,GACZ,MAAOpa,MAAK+jB,aAAa3J,IAG7B4J,WAAY,SAAS5J,EAAI6J,GACrB,GAAI7L,GAAOpY,IAEX,OAAOL,IAAGukB,OAAO7d,UAAU2d,WAAW5J,EAAI6J,GACtCne,IAAKnG,GAAGgQ,KAAKyI,EAAKtS,IAAKsS,GACvBmJ,QAAS5hB,GAAGgQ,KAAKyI,EAAKmJ,QAASnJ,GAC/B8H,WAAY9H,EAAK+H,eAIzBgE,iBAAkB,SAASC,EAAShK,GAChCpa,KAAKqkB,oBAAoBC,IAAIF,EAAShK,IAG1CmK,2BAA4B,SAASH,EAAShK,GAC1Cpa,KAAKwkB,8BAA8BF,IAAIF,EAAShK,IAGpDqK,sBAAuB,SAAS1G,EAAU3D,GACtCpa,KAAK0kB,yBAAyBJ,IAAIvG,EAAU3D,IAGhDuK,oBAAqB,SAAS7G,EAAQ1D,GAClCpa,KAAK4kB,uBAAuBN,IAAIxG,EAAQ1D,IAI5CyK,YAAa,SAAS9G,EAAU3D,GAC5Bpa,KAAKgiB,eAAesC,IAAIvG,EAAU3D,IAGtC0K,QAAS,SAASC,GACd/kB,KAAKglB,4BAA4BD,IAGrCE,aAAc,SAASC,GACnBllB,KAAK4iB,kBAAoBsC,GAG7BC,QAAS,SAAS/K,EAAImC,GAClBvc,KAAKmgB,YAAY7D,WAAWlC,EAAImC,IAGpC6I,UAAW,SAAStH,EAAQ1D,GACxBpa,KAAKsjB,aAAagB,IAAIxG,EAAQ1D,IAGlCiL,QAAS,SAASjL,EAAIgC,GAClB,MAAOpc,MAAKmgB,YAAYhE,YAAY/B,EAAIgC,IAG5CkJ,kBAAmB,WACgB,IAA3BtlB,KAAKse,WAAW5Y,OAChB1F,KAAKulB,WAAW,gBAGhBvlB,KAAKwlB,uBAQjB7lB,GAAG8lB,gBAECrH,eAAgB,SAASsH,GACrB,GAAItL,GAAKpa,KAAKmgB,YAAY/E,SACtBb,KAAMmL,EAAYnL,KAClB7Y,KAAMgkB,EAAYhkB,KAClB8Z,KAAMkK,EAAYlK,KAClBd,OAAQ/a,GAAG+a,OAAO4C,mBAatB,OAVAoI,GAAYC,oBAAsB3lB,KAAKykB,sBAAsBiB,EAAYC,mBAAoBvL,GAC7FsL,EAAYE,kBAAoB5lB,KAAK2kB,oBAAoBe,EAAYE,iBAAkBxL,GAEnFsL,EAAYG,eACZ7lB,KAAKqhB,eAAejH,GAAMsL,EAAYG,cAG1C7lB,KAAKyiB,eACLziB,KAAK6iB,uBAEEzI,GAGX0L,sBAAuB,SAASvG,EAAMwG,GAC9BpmB,GAAGyI,OAAOmX,KACVA,EAAKyG,WAAahmB,KAAKimB,aAAaF,KAI5CG,YAAa,SAASngB,GAClB/F,KAAK0e,SAASyH,UAAUC,QAAQ,KAAM,KAAMrgB,EAASjC,SAGzDuiB,qBAAsB,WAClB,GAAIjO,GAAOpY,IAEX,OAAO,IAAIL,IAAG2mB,yBACVC,OAAQvmB,KAAK0e,SAAS6B,WAAWgG,OAAOC,cACxCC,eAAgBzmB,KAAK0e,SAAS+H,eAC9BC,cAAe1mB,KAAK0e,SAASiI,QAAQC,SACrCC,cAAe7mB,KAAKwkB,8BACpBsC,YAAa9mB,KAAK4kB,uBAClBmC,cAAe/mB,KAAK0kB,yBACpBsC,KAAMhnB,KAAK0e,SAASsI,KACpBlhB,IAAKnG,GAAGgQ,KAAKyI,EAAKtS,IAAKsS,GACvB6O,SAAU,SAAS7M,GACfhC,EAAK8O,UAAU9M,GACfhC,EAAKsG,SAASyH,UAAUc,SAAS7M,IAErC+M,iBAAkB,SAAS/M,EAAIgN,EAAUC,GACrCjP,EAAKkP,kBAAkBlN,EAAIgN,EAAUC,GACrCjP,EAAKsG,SAASyH,UAAUgB,iBAAiB/M,EAAIgN,EAAUC,OAMnEE,oBAAqB,WACjB,GAAInP,GAAOpY,IAEX,OAAO,IAAIL,IAAG6nB,cACVC,cAAeznB,KAAK0e,SAASgJ,MAAMD,cACnCtB,WACIrgB,IAAKnG,GAAGgQ,KAAKyI,EAAKtS,IAAKsS,GACvBuP,cAAe,SAASvc,GACpBgN,EAAKwP,wBACDlmB,KAAM,kBACN0N,SAAUzP,GAAGgQ,KAAKyI,EAAKsG,SAASyH,UAAU0B,gBAAiBzP,EAAMhN,GACjEkM,UAAW3X,GAAGgQ,KAAKyI,EAAK0P,oBAAqB1P,EAAMhN,GACnD2c,WAAY,sBAOhCC,aAAc,SAASC,EAAcC,GACjC,GAAIC,MACAC,EAAWH,EACXI,KACAC,EAAiBJ,EACjBK,EAAO,SAASC,GACZ,MAAI7oB,IAAGuG,SAASsiB,GACL7oB,GAAG6B,UAAWgnB,GAElBA,GAEXC,EAAoB,WAChB,MAAI9oB,IAAG6G,WAAW8hB,GACPA,IAEJA,GAEXI,EAAwB,SAAStO,EAAIuO,GAC7BL,GAAkB3oB,GAAGuG,SAASyiB,IAC9BhpB,GAAG6B,OAAOmnB,EAAUF,KAGpBJ,EAAoBjO,IACpBza,GAAG6B,OAAOmnB,EAAUN,EAAoBjO,IAIpD,QACIkK,IAAK,SAAS1hB,EAAKwX,GAEL,MAANA,GACA+N,KACAC,EAAWG,EAAK3lB,IAGhBulB,EAAM/N,GAAMmO,EAAK3lB,IAIzBqf,IAAK,SAAS7H,GACV,GAAIwO,EAYJ,OARIA,GADM,MAANxO,GAAc+N,EAAM/N,GACX+N,EAAM/N,GAGNmO,EAAKH,GAGlBM,EAAsBtO,EAAIwO,GAEnBL,EAAKK,IAGhBC,YAAa,SAASzO,EAAIwO,GAElBjpB,GAAGuG,SAASiiB,KAED,OAAP/N,EACIza,GAAG6G,WAAWoiB,GACdN,EAAiBM,GAGjBN,EAAiBA,MACjB3oB,GAAG6B,OAAO8mB,EAAgBM,KAI9BP,EAAoBjO,GAAMiO,EAAoBjO,OAC9Cza,GAAG6B,OAAO6mB,EAAoBjO,GAAKwO,MAK/C7nB,OAAQ,SAAS8f,GACb,aAAcsH,GAAMtH,IAGxB/G,MAAO,WACHqO,KACAE,KACAD,EAAWH,KAKvBa,yBAA0B,WACtB,GAAI1Q,GAAOpY,IAEX,OAAO,IAAIL,IAAGoa,YACVsG,QAAS,SAASjG,GACd,MAAOhC,GAAKiI,QAAQjG,IAExB0I,QAAS,SAAS1I,GACd,MAAOhC,GAAK0K,QAAQ1I,IAExBmI,QAAS,SAASnI,GACd,MAAOhC,GAAKmK,QAAQnI,IAExBuB,eAAgB,SAASvB,EAAI4B,EAAWD,GACpC3D,EAAK2Q,sBAAsB3O,EAAI4B,EAAWD,GAC1C3D,EAAKsG,SAASyH,UAAUxK,eAAevB,EAAI4B,EAAWD,GACtD3D,EAAK4Q,kBAAkB5O,EAAI2B,GAEvB3D,EAAKyL,gBACLoF,WAAW,WACP7Q,EAAKyL,eAAelI,eAAevB,EAAI4B,EAAWD,IACnD,OAcnBmN,oBAAqB,SAAS7N,GAM1B,QAAS8N,KACL,QAAIxpB,GAAGkT,kBAAkBsC,kBAEjBiD,EAAKsG,SAAS0K,YAAYC,gBAC1B1pB,GAAG0O,QACF1O,GAAGyO,QACJgK,EAAKkR,oBAAoBC,EAAmB,WAK1BzlB,SAAlBuX,EAAK3R,SACE0O,EAAKsG,SAAShV,SAGlB2R,EAAK3R,WApBpB,GAGI2Z,GAHAjL,EAAOpY,KACPuY,EAAc8C,EAAKmO,QAAUxpB,KAAK0e,SAAS+K,WAAWlR,YACtDgR,EAAoBlO,EAAKkO,mBAAqBvpB,KAAK0e,SAAS+K,WAAWF,iBA6C3E,OArBAlG,GAAS,GAAI1jB,IAAGkY,cACZU,YAAaA,EACb3Y,QAASyb,EAAKzb,QACdwZ,WAAYpZ,KAAK0e,SAASgL,QAAQC,YAClCrR,QAAS+C,EAAK/C,QACda,WAAYnZ,KAAK0e,SAASgL,QAAQE,YAClCvQ,2BAA4BrZ,KAAK0e,SAAS0K,YAAYS,iBACtDngB,SAAUyf,IACVznB,KAAM1B,KAAK0e,SAASiI,QAAQmD,UAC5B5Q,SAAU,SAAS3P,GACf6O,EAAK2R,eAAexgB,IAExB4O,MAAqB,MAAdkD,EAAKlD,MAAgBnY,KAAK0e,SAASrb,KAAK2mB,eAAiB3O,EAAKlD,QAGzEnY,KAAKiqB,gBAAgB3X,YAAY,WAC7B+Q,EAAOlR,YAGXiG,EAAKgL,SAASvgB,KAAKwgB,GAEZA,GAGX6G,qBAAsB,SAASC,EAAmBC,GAC9C,GAAIhS,GAAOpY,KACPqqB,KACAnS,GACI6K,MAAO/iB,KAAK0e,SAASqE,MACrB0D,eAAgBzmB,KAAK0e,SAAS+H,eAC9BO,KAAMhnB,KAAK0e,SAASsI,KACpBF,YAAa9mB,KAAKsjB,aAClByD,cAAe/mB,KAAKgiB,eACpB1M,SAAUtV,KAAK0e,SAASpJ,SACxBc,OAAQpW,KAAK0e,SAAStI,OACtBuI,MAAO3e,KAAK0e,SAASC,MACrB7Y,IAAKnG,GAAGgQ,KAAKyI,EAAKtS,IAAKsS,GACvBkS,kBAAmBtqB,KAAK0e,SAASoF,MAAMyG,6BACvCC,WAAY,SAASpQ,EAAI1Y,EAAM+oB,EAAQC,GAC/BD,EAAS,GAAKC,EAAQ,IAItBL,EAAejQ,GACXiQ,EAAejQ,GAAIqQ,SAAWA,GAAUJ,EAAejQ,GAAIsQ,QAAUA,IACrEtS,EAAKuS,YAAYvQ,EAAI1Y,EAAM+oB,EAAQC,GACnCtS,EAAKsG,SAASyH,UAAUqE,WAAWpQ,EAAI1Y,EAAM+oB,EAAQC,KAIzDtS,EAAKuS,YAAYvQ,EAAI1Y,EAAM+oB,EAAQC,GACnCtS,EAAKsG,SAASyH,UAAUqE,WAAWpQ,EAAI1Y,EAAM+oB,EAAQC,IAGzDL,EAAejQ,IAAOqQ,OAAQA,EAAQC,MAAOA,KAGjDE,WAAY,SAASxQ,EAAI1Y,EAAMY,EAAQiR,SAC5B8W,GAAejQ,EAEtB,IACI9K,GADAoL,EAAStC,EAAKiK,YAAYjI,GAAIA,IAAKM,MAOnCA,KAAW/a,GAAG+a,OAAO4C,mBAAqB5C,IAAW/a,GAAG+a,OAAO6C,gBAInEjO,EAAS8I,EAAKyS,YAAYzQ,EAAI1Y,EAAMY,EAAQiR,GAIxCjE,YAAmB3P,IAAG+L,QACtB4D,EAAOkI,KAAK,WACRY,EAAKsG,SAASyH,UAAUyE,WAAWxQ,EAAI1Y,EAAMY,EAAQiR,KAIzD6E,EAAKsG,SAASyH,UAAUyE,WAAWxQ,EAAI1Y,EAAMY,EAAQiR,KAG7DuX,SAAU,SAAS1Q,EAAI1Y,EAAMqpB,GACzB,GAAItf,GAAU,GAAI9L,IAAG+L,OAgBrB,OAdA0M,GAAKwP,wBACDlmB,KAAM,WACN0N,SAAUzP,GAAGgQ,KAAKyI,EAAKsG,SAASyH,UAAU2E,SAAU1S,EAAMgC,EAAI1Y,GAC9D6V,UAAW9L,EAAQK,QACnBwL,UAAW,WACPyT,EAAyBhU,KAAK,WAC1BqB,EAAK4S,UAAU5Q,EAAI1Y,KAGvB+J,EAAQG,WAEZmc,WAAY3N,IAGT3O,GAEXwf,aAActrB,GAAGgQ,KAAK3P,KAAKkrB,cAAelrB,MAC1CmrB,SAAU,SAAS/Q,EAAI1Y,GACnB0W,EAAKgT,UAAUhR,EAAI1Y,GACnB0W,EAAKsG,SAASyH,UAAUgF,SAAS/Q,EAAI1Y,IAEzC2pB,cAAe,SAASjR,EAAI1Y,EAAM4pB,GAC9BlT,EAAKmT,eAAenR,EAAIkR,GACxBlT,EAAKsG,SAASyH,UAAUkF,cAAcjR,EAAI1Y,EAAM4pB,IAEpDE,qBAAsB,SAASpR,EAAIkR,EAAWhpB,EAAQiR,GAClD6E,EAAKsG,SAASyH,UAAUqF,qBAAqBxb,MAAMoI,EAAMtQ,YAE7D2jB,SAAU,SAASrR,EAAI1Y,EAAM4pB,GACzB,MAAOlT,GAAKsG,SAASyH,UAAUsF,SAASrR,EAAI1Y,EAAM4pB,IAEtDI,YAAa,SAAStR,EAAI1Y,EAAMiqB,EAAcpY,GAC1C,MAAO6E,GAAKwT,aAAa5b,MAAMoI,EAAMtQ,YAEzC+jB,cAAe,SAASzR,EAAIgC,GACxBhE,EAAKtS,IAAI,sCAAwCsS,EAAK0K,QAAQ1I,GAAM,SAAWgC,EAAU,KACzFhE,EAAKiN,QAAQjL,EAAIgC,IAErBiE,QAAS1gB,GAAGgQ,KAAKyI,EAAKiI,QAASjI,GAC/B0K,QAASnjB,GAAGgQ,KAAKyI,EAAK0K,QAAS1K,GAC/BmK,QAAS5iB,GAAGgQ,KAAKyI,EAAKmK,QAASnK,GAC/B0T,QAASnsB,GAAGgQ,KAAKyI,EAAK2T,SAAU3T,GAChC4T,cAAe,SAASzR,GACpB,MAAOnC,GAAKiK,YAAY9H,KAAMA,KAElC0R,SAAU,SAAS7R,GACf,GAAIM,GAAStC,EAAKiK,YAAYjI,GAAIA,IAAKM,MACvC,OAAOA,KAAW/a,GAAG+a,OAAOuC,QACxBvC,IAAW/a,GAAG+a,OAAOqC,WACrBrC,IAAW/a,GAAG+a,OAAO2C,iBACrB3C,IAAW/a,GAAG+a,OAAOyC,QAE7BN,mBAAoBzE,EAAK+H,YAAYtD,mBACrCC,cAAe1E,EAAK+H,YAAYrD,cAexC,OAZAnd,IAAG+C,KAAK1C,KAAK0e,SAASiI,QAAS,SAASza,EAAMtJ,GAC1CsV,EAAQhM,GAAQtJ,IAGpBsV,EAAQ2O,cAAgB7mB,KAAKqkB,oBAEzB8F,GACAxqB,GAAG+C,KAAKynB,EAAmB,SAAS3a,EAAK5M,GACrCsV,EAAQ1I,GAAO5M,IAIhB,GAAIjD,IAAGusB,wBAAwBhU,EAASkS,IAGnD+B,oBAAqB,SAAS/R,GAC1Bpa,KAAK6iB,uBACL7iB,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAOsC,WAG7CoP,YAAa,SAASphB,GAClB,GAAc,IAAVA,EACA,MAAOA,GAAQhL,KAAK0e,SAASrb,KAAKgpB,YAAY,EAElD,IAAI5b,IAAI,CACR,GACIzF,IAAgB,IAChByF,UACKzF,EAAQ,IAEjB,OAAO1J,MAAKgrB,IAAIthB,EAAO,IAAKuhB,QAAQ,GAAKvsB,KAAK0e,SAASrb,KAAKgpB,YAAY5b,IAK5E+b,0BAA2B,WACvB,GAAIpU,GAAOpY,IAEXA,MAAKysB,qBAEL9sB,GAAG+C,KAAK1C,KAAK0e,SAASgO,aAAc,SAAS/pB,EAAKgqB,GAC9C,GAAIjjB,GAAWijB,EAAuBjjB,SAClC+f,EAAa9pB,GAAG6B,UAAW4W,EAAKsG,SAAS+K,YAAY,GACrDmD,EAAkBjtB,GAAG6B,UAAWmrB,EAEnB7oB,UAAb4F,IACAA,EAAW0O,EAAKsG,SAAShV,UAGzBkjB,EAAgBnD,YAChB9pB,GAAG6B,OAAOioB,EAAYkD,EAAuBlD,YAAY,GAG7D9pB,GAAG6B,OAAOorB,GACNljB,SAAUA,EACV+f,WAAYA,IACb,GAEHrR,EAAKyU,iBAAiBD,MAI9B/K,WAAY,SAAS5J,GACjB,GAAI6U,GAAmB9sB,KAAKysB,kBAAkBxU,EAE9C,OAAI6U,GACOA,EAAiBltB,QAEnBqY,IAAajY,KAAK+sB,iBAChB/sB,KAAK0e,SAAS2E,OADpB,QAYT4C,aAAc,SAAS+G,GACnB,GAAIC,GAAQC,EACRC,EAAkBH,CAQtB,IALIG,YAA2BxtB,IAAG8X,YAC9B0V,EAAkBA,EAAgBzV,eAIlCyV,IAAoBxtB,GAAGyJ,OAAO+jB,GAAkB,CAChD,GAAIxtB,GAAGyI,OAAO+kB,GACV,MAAOA,GAAgBnH,UAEtB,IAA8C,UAA1CmH,EAAgBhkB,QAAQF,eACU,SAAvCkkB,EAAgBjtB,KAAK+I,cAErB,MAAOkkB,GAAgBtpB,aAAalE,GAAGkY,aAAaG,oBAYxD,IATAiV,EAASE,EAAgB1qB,qBAAqB,SAE9C9C,GAAG+C,KAAKuqB,EAAQ,SAAStqB,EAAK4G,GAC1B,GAAmC,SAA/BA,EAAM1F,aAAa,QAEnB,MADAqpB,GAAY3jB,GACL,IAIX2jB,EACA,MAAOA,GAAUrpB,aAAalE,GAAGkY,aAAaG,uBAK1DoV,gBAAiB,WACb,MAAOptB,MAAKmgB,YAAYvE,UACpBlB,QACI/a,GAAG+a,OAAO0C,UACVzd,GAAG+a,OAAO2C,gBACV1d,GAAG+a,OAAOuC,OACVtd,GAAG+a,OAAOY,WACV3b,GAAG+a,OAAOqC,UACVpd,GAAG+a,OAAOyC,UAEfzX,QAKP2nB,mBAAoB,SAASpV,GACzB,GAAI2U,GAAkB5sB,KAAKysB,kBAAkBxU,EAE7C,OAAO2U,GAAkBA,EAAgBnD,WAAazpB,KAAK0e,SAAS+K,YAGxE6D,yBAA0B,SAASC,GAC/B,MAAIA,GAAYhO,eAAgB5f,IAAG8X,WAE3B/V,KAAM/B,GAAGmS,YAAYyb,EAAYhO,KAAK7H,eACtC8D,KAAM+R,EAAYhO,KAAK7H,cAAc8D,OAKzC9Z,KAAM1B,KAAKqiB,YAAYjI,GAAImT,EAAYnT,KAAK1Y,KAC5C8Z,KAAMxb,KAAKqiB,YAAYjI,GAAImT,EAAYnT,KAAKoB,OAIpDgS,0BAA2B,SAASC,GAChC,GAAIrV,GAAOpY,KACP0tB,IAMJ,OAJA/tB,IAAG+C,KAAK+qB,EAAc,SAAS9qB,EAAK4qB,GAChCG,EAAgB7qB,KAAKuV,EAAKkV,yBAAyBC,MAGhDG,GAIXC,oBAAqB,WACjB,GAAI3tB,KAAK0e,SAASkP,OAAOvf,KAAO1O,GAAG0O,MAAO,CACtC,GAAIwf,GAAkB,yBAClBxK,EAASrjB,KAAK0e,SAASkP,OAAOvK,OAC9BpL,EAAWoL,EAASrjB,KAAKimB,aAAa5C,GAAUrjB,KAAK+sB,iBACrDe,EAAa9tB,KAAK0e,QAGlBzG,IAAYA,IAAajY,KAAK+sB,mBAC9Be,EAAa9tB,KAAKysB,kBAAkBxU,IAIxC6V,EAAWpkB,UAAW,EAGoB,OAAtCokB,EAAWrE,WAAWlR,YACtBuV,EAAWrE,WAAWlR,YAAcsV,EAGpCC,EAAWrE,WAAWlR,aAAe,IAAMsV,EAI/CluB,GAAG+C,KAAK1C,KAAKojB,SAAU,SAASzgB,EAAK0gB,GACjC,GAAIA,EAAO5J,gBAAkBxB,EAIzB,MAHAoL,GAAOhL,YAAYyV,EAAWpkB,UAC9B2Z,EAAOxJ,eAAeiU,EAAWvV,cAE1B,MAMvBqP,uBAAwB,SAASmG,GAC7B,GAAI3V,GAAOpY,KACPguB,EAAiBD,EAAQ3e,UAE7B,OAAIzP,IAAGkX,iBAAiBmX,IACpBhuB,KAAK8F,IAAIioB,EAAQrsB,KAAO,kBAAoBqsB,EAAQrsB,KAAO,gCAAkCqsB,EAAQhG,YAC9FiG,EAAejX,KAClB,SAASkX,GACL7V,EAAKtS,IAAIioB,EAAQrsB,KAAO,wBAA0BqsB,EAAQhG,YAC1DgG,EAAQzW,UAAU2W,IAEtB,WACQF,EAAQxW,WACRa,EAAKtS,IAAIioB,EAAQrsB,KAAO,wBAA0BqsB,EAAQhG,YAC1DgG,EAAQxW,aAGRa,EAAKtS,IAAIioB,EAAQrsB,KAAO,wBAA0BqsB,EAAQhG,gBAKtEiG,KAAmB,EACnBD,EAAQzW,UAAU0W,GAGdD,EAAQxW,WACRvX,KAAK8F,IAAIioB,EAAQrsB,KAAO,mCAAqCqsB,EAAQhG,WAAa,iCAClFgG,EAAQxW,aAGRvX,KAAK8F,IAAIioB,EAAQrsB,KAAO,mCAAqCqsB,EAAQhG,WAAa,wBAInFiG,IAIXvP,eAAgB,SAASc,EAAM9D,EAASyS,GACpC,GAAI9V,GAAOpY,KACPua,EAAO5a,GAAGoN,cACVyO,GAAO,EACP9Z,EAAO/B,GAAGmS,YAAYyN,GACtB4O,EAAa5O,EAAKnU,MAAQmU,EAC1B6O,EAAUpuB,KAAKquB,sBACXruB,KAAKquB,sBACL1uB,GAAGgQ,KAAKyI,EAAKkW,sBAAuBlW,IAEvCzY,GAAGiJ,QAAQulB,IAAeA,EAAW3S,MAAQ,IAC9CA,EAAO2S,EAAW3S,MAGtB4S,EAAQD,EAAYzsB,EAAM6Y,EAAMiB,EAAM0S,EAAoBzS,EAASzb,KAAK0e,SAASiI,QAAQC,UACrF1G,WAAY9H,EAAK+H,YACjB2G,YAAa1O,EAAKkL,aAClBiL,iBAAkB,SAASnU,EAAImF,GAC3BnH,EAAKwH,SAASrP,IAAI6J,EAAImF,GACtBnH,EAAKyK,uBACLzK,EAAKoW,aAAapU;KAK9BkU,sBAAuB,SAAS/O,EAAM7d,EAAM6Y,EAAMiB,EAAMiT,EAAUhT,GAC9D,GAAIrB,GAAKpa,KAAKmgB,YAAY/E,SAASb,KAAMA,EAAM7Y,KAAMA,EAAM8Z,KAAMA,EAAMC,QAASA,GAEhFzb,MAAK4f,SAASrP,IAAI6J,EAAImF,GACtBvf,KAAKwuB,aAAapU,GAElBpa,KAAK6iB,uBAEL4L,EAAS5rB,MAAMuX,GAAIA,EAAImF,KAAMA,KAGjCuI,oBAAqB,SAAS1c,EAAMsjB,GAChC,GAAIC,GAAYvjB,EAAKlL,KAAKmF,MAAM,KAAK,GACjC3D,EAAOgtB,CAGC,OAARhtB,IACAA,EAAO1B,KAAK0e,SAASgJ,MAAM9I,aAG/Bld,GAAQ,IAAMitB,EAEd3uB,KAAKge,UACDtc,KAAMA,EACN0J,KAAMA,KAKdyhB,iBAAkB,SAASxR,GACvB,GAAIgI,GAASrjB,KAAKkpB,qBACdM,OAAQnO,EAAKoO,WAAWlR,YACxBgR,kBAAmBlO,EAAKoO,WAAWF,kBACnC3pB,QAASyb,EAAKzb,QACd0Y,QAAS+C,EAAK/C,QACd5O,SAAU2R,EAAK3R,SACfyO,MAAOkD,EAAK2O,gBAGhBhqB,MAAKysB,kBAAkBpJ,EAAO5J,eAAiB4B,GAGnDuT,0BAA2B,WACvB5uB,KAAK6uB,aAAelvB,GAAGmvB,aAAe,GAAInvB,IAAGmvB,YACzC9uB,KAAK0e,SAASzN,KAAMtR,GAAGgQ,KAAK3P,KAAKslB,kBAAmBtlB,MAAOL,GAAGgQ,KAAK3P,KAAK8F,IAAK9F,OAG7EA,KAAK6uB,cAAgB7uB,KAAK6uB,aAAaE,gBACvC/uB,KAAKsjB,aAAetjB,KAAKgoB,aACrBhoB,KAAK0e,SAASiI,QAAQ7I,OAAS9d,KAAK6uB,aAAaG,uBAGrDhvB,KAAK0e,SAASuQ,WAAajvB,KAAK6uB,aAAaK,cACzClvB,KAAK6uB,aAAaM,cAClBnvB,KAAK0e,SAASiI,QAAQ5I,SAAW/d,KAAK6uB,aAAaM,cAIvDnvB,KAAKsjB,aAAetjB,KAAKgoB,aAAahoB,KAAK0e,SAASiI,QAAQ7I,SAIpEsR,kBAAmB,WACf,SAAKzvB,GAAG2mB,0BAA4BtmB,KAAK0e,SAAS6B,WAAWH,YAIzDpgB,KAAK0e,SAASsI,KAAKqI,aACf1vB,GAAGkT,kBAAkB4C,sBAIrB9V,GAAGkT,kBAAkB2C,oBAAqBxV,KAAK0e,SAASsI,KAAKsI,aAUzEhG,oBAAqB,SAASiG,EAASvd,GACnC,GAAIwd,IAAQ,CAEZ,QAAKD,EAAQ7pB,SAIb/F,GAAG+C,KAAK6sB,EAAS,SAAS5sB,EAAK8sB,GAK3B,GAAI9vB,GAAGwH,SAASsoB,GAAa,CAEzB,GAAIC,GAAW,GAAI7tB,QAAO,MAAQ4tB,EAAa,IAAK,IAEpD,IAAgC,MAA5Bzd,EAASoB,MAAMsc,GAEf,MADAF,IAAQ,GACD,KAKZA,IAWXjK,WAAY,SAASoK,EAAMC,EAAkB3oB,GASzC,QAASgG,GAAEvL,EAAMmuB,GAAe9pB,EAAUA,EAAQ7D,QAAQR,EAAMmuB,GARhE,GAMIC,GAAsBC,EANtBhqB,EAAU/F,KAAK0e,SAASsR,SAASL,GACjCpG,KACA0G,KAAWlgB,OAAO6f,GAClBluB,EAAOuuB,EAAM,GACbhY,EAAWjY,KAAKimB,aAAahf,GAC7BipB,EAAiBlwB,KAAKqtB,mBAAmBpV,EA+B7C,OA1BAtY,IAAG+C,KAAKwtB,EAAe3G,kBAAmB,SAAS5mB,EAAKwtB,GAKhDxwB,GAAGwH,SAASgpB,IACZ5G,EAAkB1mB,KAAKstB,KAI/BL,EAAuBvG,EAAkB3Y,KAAK,MAAM3H,cAEpDgE,EAAE,SAAUjN,KAAK0e,SAAS0R,eAAe1uB,IACzCuL,EAAE,eAAgB6iB,GAClB7iB,EAAE,cAAejN,KAAKosB,YAAY8D,EAAeG,YACjDpjB,EAAE,iBAAkBjN,KAAKosB,YAAY8D,EAAeI,eAEpDP,EAAmBhqB,EAAQqN,MAAM,cACR,OAArB2c,GACApwB,GAAG+C,KAAKqtB,EAAkB,SAASptB,EAAK4tB,GACpCtjB,EAAEsjB,EAAaN,EAAMttB,MAI7B3C,KAAK0e,SAASyH,UAAUC,QAAQ,KAAM1kB,EAAMqE,EAASjC,QAE9CiC,GAYXge,aAAc,SAAS3J,EAAIhL,GACvB,GAAIpP,KAAKwwB,qBAAqBpW,GAW1B,MAVApa,MAAK6iB,uBACL7iB,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAO2C,iBAErCjO,EACAA,EAASgL,GAGTpa,KAAK4f,SAASkE,MAAM1J,IAGjB,GAIf4O,kBAAmB,SAAS5O,EAAIM,GAC5B,GAAItC,GAAOpY,KACPywB,EAAczwB,KAAKotB,iBAEnB1S,KAAW/a,GAAG+a,OAAO4C,kBACrBtd,KAAK2jB,+BAA+B9gB,KAAKuX,GAEpCM,IAAW/a,GAAG+a,OAAO6C,eAC1Bvd,KAAK4jB,4BAA4B/gB,KAAKuX,GAGtB,IAAhBqW,IACCzwB,KAAK2jB,+BAA+Bje,QAAU1F,KAAK4jB,4BAA4Ble,SAEhFujB,WAAW,WACP7Q,EAAKsY,eAAetY,EAAKuL,+BAAgCvL,EAAKwL,8BAC/D,IAIXvF,iCAAkC,WAC9B,GAAIjG,GAAOpY,IAEX,IAAIA,KAAK0e,SAAS0K,YAAYuH,mBAAqBhxB,GAAG6O,UAAY7O,GAAG+O,YAIjE,KAHAua,YAAW,WACPpkB,OAAO+rB,MAAMxY,EAAKsG,SAASsR,SAASa,+BACrC,GACG,GAAIlxB,IAAGwB,MAAMnB,KAAK0e,SAASsR,SAASa,+BAIlDC,8BAA+B,SAAS1W,EAAI1Y,EAAMqvB,EAAUxd,GAGxD,IAAKwd,EAASnlB,QACV,GAAI2H,GAAsB,MAAfA,EAAImH,SAAmBqW,EAAS/mB,MACvChK,KAAK0e,SAASyH,UAAUC,QAAQhM,EAAI1Y,EAAM,8BAAgC6R,EAAImH,OAAQnH,OAErF,CACD,GAAIyd,GAAcD,EAAS/mB,MAAQ+mB,EAAS/mB,MAAQhK,KAAK0e,SAASrb,KAAK4tB,oBACvEjxB,MAAK0e,SAASyH,UAAUC,QAAQhM,EAAI1Y,EAAMsvB,EAAazd,KAKnE2d,6CAA8C,SAASC,EAAWhnB,EAAO0Q,EAAOiD,EAAQC,GACpF,GAAI3F,GAAOpY,IAEX,IAAImK,EAAMzE,OAASmV,EACf,GAAIsW,IAAcnxB,KAAK0e,SAAS+K,WAAW2H,uBAEvCnI,WAAW,WACP,GAAIoI,GAAuBjZ,EAAKkV,yBAAyBnjB,EAAM0Q,IAC3D5C,EAAWG,EAAK6N,aAAa9b,EAAM0Q,GAAO0E,MAC1C8D,EAASjL,EAAKyJ,WAAW5J,EAE7BG,GAAKwP,wBACDlmB,KAAM,aACN0N,SAAUzP,GAAGgQ,KAAKyI,EAAKsG,SAASyH,UAAUmL,WAAYlZ,EAAMiZ,EAAsBhO,GAClF/L,UAAW3X,GAAGgQ,KAAKyI,EAAKmZ,2BAA4BnZ,EAAMjO,EAAO0Q,EAAOiD,EAAQC,GAChFxG,UAAW5X,GAAGgQ,KAAKyI,EAAKoZ,2BAA4BpZ,EAAMjO,EAAO0Q,EAAOiD,EAAQC,GAChFgK,WAAY,SAAWsJ,EAAqB3vB,KAAO,YAAc2vB,EAAqB7V,QAE3F,OAEF,KAAK2V,EACN,KAAOtW,EAAQ1Q,EAAMzE,OAAQmV,IACzBzC,EAAK+T,oBAAoBhiB,EAAM0Q,GAAOT,KAMtDsW,eAAgB,SAASe,EAAYC,GACjC1xB,KAAK6jB,gBAAkB7jB,KAAK6jB,eAAe8N,cAAcF,EAAYC,EAAQ1xB,KAAKmjB,iBAElFnjB,KAAK0e,SAASyH,UAAUwL,cAAchyB,GAAG6B,UAAWiwB,GAAa9xB,GAAG6B,UAAWkwB,IAE/E1xB,KAAK2jB,kCACL3jB,KAAK4jB,gCAeTgI,aAAc,SAASxR,EAAI1Y,EAAMiqB,EAAcpY,EAAKnE,GAChD,GAAIgJ,GAAOpY,IAIX,IAFAoY,EAAK+K,gBAAgB/I,GAAMuR,EAAavT,EAAKsG,SAASoF,MAAMyG,8BAExDnS,EAAKwZ,iBAAiBxX,EAAI1Y,EAAMiqB,GAAe,CAC/C,GAAIkG,GAAyD,IAAvCzZ,EAAKsG,SAASoF,MAAMgO,gBAkB1C,OAhBA1Z,GAAK0Y,8BAA8B9gB,MAAMoI,EAAMtQ,WAC/CsQ,EAAKsG,SAASyH,UAAUuF,YAAYtR,EAAI1Y,EAAM0W,EAAK6K,aAAa7I,IAChEhC,EAAK2Z,mBAAmB3X,EAAI1Y,GAE5B0W,EAAK+H,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAO2C,iBACzCjF,EAAK8K,eAAe9I,GAAM6O,WAAW,WACjC7Q,EAAKtS,IAAI,sBAAwBpE,EAAO,OAEpC0N,EACAA,EAASgL,GAGThC,EAAKwH,SAASkE,MAAM1J,IAEzByX,IAEI,IAIfE,mBAAoB,SAAS3X,EAAI1Y,GAC7B1B,KAAK8F,IAAI,WAAa9F,KAAK0e,SAASoF,MAAMgO,iBAAmB,4BAA8BpwB,EAAO,QAItG8uB,qBAAsB,SAASpW,GAC3B,GACIpI,GADAggB,EAAYhyB,KAAK4iB,iBAGrB,OAAI5iB,MAAKmjB,gBAAgB/I,IACrBpa,KAAK8F,IAAI,gCAAkCsU,EAAI,SACxC,GAEFpa,KAAK4f,SAASe,QAAQvG,IAC3BpI,EAAWhS,KAAKqgB,QAAQjG,GAEpBpa,KAAK0e,SAASyH,UAAU8L,cAAc7X,EAAIpI,MAAc,IAIxDggB,EAAY,GAAKhyB,KAAK6iB,qBAAuB,EAAImP,GACjDhyB,KAAKulB,WAAW,0BACT,IAGXvlB,KAAK8F,IAAI,wBAA0BkM,EAAW,UAAYoI,EAAK,SACxD,MAGPpa,KAAK8F,IAAI,IAAMsU,EAAK,2BAA4B,UACzC,IAIf4Q,UAAW,SAAS5Q,EAAI1Y,GACpB1B,KAAK6iB,uBAELqP,aAAalyB,KAAKkjB,eAAe9I,GAEjC,IAAI+X,GAAkBxyB,GAAG2F,QAAQtF,KAAKse,WAAYlE,IAC7Cpa,KAAK0e,SAASuQ,YAAckD,GAAmB,GAChDnyB,KAAKse,WAAWpC,OAAOiW,EAAiB,GAG5CnyB,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAOwC,WAG7C2N,YAAa,SAASzQ,EAAI1Y,EAAMY,EAAQiR,GAoBpC,MAnBKjR,GAAOsJ,SASJtJ,EAAOujB,eACP7lB,KAAKqhB,eAAejH,GAAM9X,EAAOujB,cAGrC7lB,KAAKyiB,eACLziB,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAO4C,qBAbzCtd,KAAK6iB,uBACL7iB,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAO6C,eAErCjb,EAAOtC,KAAK0e,SAASoF,MAAMyG,iCAAkC,IAC7DvqB,KAAKmjB,gBAAgB/I,IAAM,IAYnCpa,KAAK8wB,8BAA8B1W,EAAI1Y,EAAMY,EAAQiR,KAE9CjR,EAAOsJ,SAGlBsb,UAAW,SAAS9M,GAChBpa,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAO+C,WAG7C6J,kBAAmB,SAASlN,EAAIgN,EAAUC,GACtC,GAAI3lB,GAAO1B,KAAKqgB,QAAQjG,EAEpBiN,IACArnB,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAO8C,eACzCxd,KAAK8F,IAAI,uBAAyBpE,EAAO,gBAAiB,SAIzBoC,SAA7BsjB,EAAS5T,gBACTxT,KAAK0e,SAASyH,UAAUC,QAAQhM,EAAI1Y,EAAM,wBAAyB0lB,GAGnEpnB,KAAK0e,SAASyH,UAAUC,QAAQhM,EAAI1Y,EAAM,4CAA8C0lB,EAAS1M,OAAQ0M,KAI7GpnB,KAAK6iB,uBACL7iB,KAAKyiB,eACLziB,KAAK4f,SAASwS,QAAQhY,GACtBpa,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAOgD,SACzC1d,KAAK8F,IAAI,uBAAyBpE,EAAO,sBAIjDqoB,eAAgB,SAASxgB,GACrB,GAAI8oB,EAEJ,IAAI1yB,GAAGkT,kBAAkBsC,cAAe,CACpC,IAAKkd,EAAY,EAAGA,EAAY9oB,EAAM+V,MAAM5Z,OAAQ2sB,IAChDryB,KAAK8lB,sBAAsBvc,EAAM+V,MAAM+S,GAAY9oB,EAGvDvJ,MAAKge,SAASzU,EAAM+V,WAGf/V,GAAM7C,MAAMhB,OAAS,GAC1B1F,KAAKge,SAASzU,EAGlB5J,IAAG+C,KAAK1C,KAAKojB,SAAU,SAASzgB,EAAK0gB,GACjCA,EAAOvJ,WAIf6Q,YAAa,SAASvQ,EAAI1Y,EAAM+oB,EAAQC,GACpC1qB,KAAK6jB,gBAAkB7jB,KAAK6jB,eAAeyO,qBAAqBlY,EAAIqQ,EAAQC,IAGhF6H,UAAW,SAASnY,EAAI1Y,KAIxB8wB,yBAA0B,SAASpY,EAAI1Y,GACnC1B,KAAKuyB,UAAUviB,MAAMhQ,KAAM8H,WAC3B9H,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAOqC,WACzC/c,KAAKyyB,aAAaziB,MAAMhQ,KAAM8H,WAE1B9H,KAAK0e,SAASuQ,YACdjvB,KAAK0e,SAASyH,UAAUuM,YAAY1iB,MAAMhQ,KAAM8H,WAChD9H,KAAKsgB,YAAYlG,KAGjBpa,KAAK2yB,eAAevY,GACpBpa,KAAK0e,SAASyH,UAAUuM,YAAY1iB,MAAMhQ,KAAM8H,aAIxD0Y,gBAAiB,SAASpG,EAAIwY,EAAmBC,GAC7C,GACIC,GADAvY,EAAOva,KAAK8iB,QAAQ1I,EAOxB,OAJIwY,KACAE,EAA4BnzB,GAAGgQ,KAAKijB,EAAmB5yB,KAAMoa,EAAIG,EAAMsY,IAGvE7yB,KAAKovB,qBACLpvB,KAAK4nB,wBACDlmB,KAAM,iBACN0N,SAAUzP,GAAGgQ,KAAK3P,KAAK0e,SAASyH,UAAU4M,eAAgB/yB,KAAMoa,GAChE9C,UAAWwb,GACPnzB,GAAGgQ,KAAK3P,KAAKgzB,eAAeC,WAAYjzB,KAAMoa,EAAIG,EAAMsY,GAC5D9K,WAAY3N,KAET,IAGPpa,KAAK8F,IAAI,iCAAmCsU,EAAK,wHACuB,SACjE,IAIfqY,aAAc,SAASrY,KAIvB8Y,iBAAkB,SAASzI,EAAQC,GAC/B1qB,KAAK0e,SAASyH,UAAUgN,gBAAgB1I,EAAQC,IAGpDQ,cAAe,SAAS9Q,KAIxBgR,UAAW,SAAShR,EAAI1Y,GACpB1B,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAO0C,YAG7CmO,eAAgB,SAASnR,EAAIkR,KAI7BvC,sBAAuB,SAAS3O,EAAI4B,EAAWD,GAEvCA,IAAcpc,GAAG+a,OAAOyC,QACxB+U,aAAalyB,KAAKkjB,eAAe9I,KAIzCgZ,gCAAiC,SAAS3F,GACtC,GAAIrV,GAAOpY,IAEXL,IAAG+C,KAAK+qB,EAAc,SAAS9qB,EAAK4qB,GAChCnV,EAAK+T,oBAAoBoB,EAAYnT,OAI7CiZ,gCAAiC,SAASC,EAAuBnpB,EAAO2T,EAAQC,EAAUsF,GACtF,GAAIkQ,GACAvB,EAAYhyB,KAAK4iB,kBACjB4Q,EAAmCxzB,KAAK6iB,oBAE1B,KAAdmP,GAAmBwB,GAAoCxB,EACnD7nB,EAAMzE,OAAS,EACf1F,KAAK4nB,wBACDlmB,KAAM,aACN0N,SAAUzP,GAAGgQ,KAAK3P,KAAK0e,SAASyH,UAAUmL,WAAYtxB,KAAMszB,EAAsB,GAAIjQ,GACtF/L,UAAW3X,GAAGgQ,KAAK3P,KAAKuxB,2BAA4BvxB,KAAMmK,EAAO,EAAG2T,EAAQC,GAC5ExG,UAAW5X,GAAGgQ,KAAK3P,KAAKwxB,2BAA4BxxB,KAAMmK,EAAO,EAAG2T,EAAQC,GAC5EgK,WAAY,SAAW5d,EAAM,GAAGoV,KAAK7d,KAAO,YAAcyI,EAAM,GAAGoV,KAAK/D,OAI5Exb,KAAKulB,WAAW,iBAIpBvlB,KAAKozB,gCAAgCjpB,GACrCopB,EAAevzB,KAAK0e,SAASsR,SAASyD,kBACjCvxB,QAAQ,gBAAiBsxB,GACzBtxB,QAAQ,iBAAkB8vB,GAC/BhyB,KAAKkmB,YAAYqN,KAIzB/B,2BAA4B,SAASrnB,EAAO0Q,EAAOiD,EAAQC,GACvD,GAAI2V,GAAY7Y,EAAQ,CAExB7a,MAAKmsB,oBAAoBhiB,EAAM0Q,GAAOT,GAAIjQ,EAAM0Q,GAAO0E,KAAK7d,MAE5D1B,KAAKkxB,8CAA6C,EAAO/mB,EAAOupB,EAAW5V,EAAQC,IAGvFwT,2BAA4B,SAASpnB,EAAO0Q,EAAOiD,EAAQC,GACvD,GAAI3F,GAAOpY,KACP0zB,EAAY7Y,EAAQ,EACpBwW,EAAuBrxB,KAAKstB,yBAAyBnjB,EAAM0Q,GAE/D7a,MAAK2zB,wBAAwBxpB,EAAM0Q,GAAQwW,GACtCta,KACD,WACIqB,EAAKwb,QAAQzpB,EAAM0Q,GAAOT,GAAI0D,EAAQC,GACtC3F,EAAK8Y,8CAA6C,EAAM/mB,EAAOupB,EAAW5V,EAAQC,IAEtF,WACI3F,EAAK8Y,8CAA6C,EAAO/mB,EAAOupB,EAAW5V,EAAQC,MAK/F2B,uBAAwB,SAASvV,EAAO2T,EAAQC,GAC5C,GAAqB,IAAjB5T,EAAMzE,OAEN,WADA1F,MAAKulB,WAAW,eAIpB,IAAI+N,GAAwBtzB,KAAKwtB,0BAA0BrjB,GACvD8N,EAAWjY,KAAKimB,aAAa9b,EAAM,GAAGoV,MACtC8D,EAASrjB,KAAK6hB,WAAW5J,EAE7BjY,MAAK4nB,wBACDlmB,KAAM,kBACN0N,SAAUzP,GAAGgQ,KAAK3P,KAAK0e,SAASyH,UAAU0N,gBAAiB7zB,KAAMszB,EAAuBjQ,GACxF/L,UAAW3X,GAAGgQ,KAAK3P,KAAKqzB,gCAAiCrzB,KAAMszB,EAAuBnpB,EAAO2T,EAAQC,EAAUsF,GAC/G9L,UAAW5X,GAAGgQ,KAAK3P,KAAKozB,gCAAiCpzB,KAAMmK,GAC/D4d,WAAY,sBAIpB+L,wBAAyB,WACrB,GAAI1b,GAAOpY,IAEXA,MAAKiqB,gBAAgBhqB,OAAO4E,OAAQ,eAAgB,SAASgK,GACzD,GAAIuJ,EAAK8J,gBAKL,MAJArT,GAAIA,GAAKhK,OAAOkvB,MAEhBllB,EAAEC,YAAcsJ,EAAKsG,SAASsR,SAASgE,QAEhC5b,EAAKsG,SAASsR,SAASgE,WAQ1CtQ,oBAAqB,WACjB,GAAItL,GAAOpY,KACPkY,EAAUlY,KAAK0e,SAAS8E,OAGxB7jB,IAAGs0B,SAA6C,MAAlCj0B,KAAK0e,SAAS8E,QAAQzF,WAC/B/d,KAAKk0B,WACNv0B,GAAG6B,OAAO0W,GAAU8O,KAAMhnB,KAAK0e,SAASsI,OAExC9O,EAAQpS,IAAMnG,GAAGgQ,KAAK3P,KAAK8F,IAAK9F,MAChCkY,EAAQic,cAAgBx0B,GAAGgQ,KAAK3P,KAAKoe,eAAgBpe,MAErDA,KAAKk0B,SAAW,GAAIv0B,IAAGs0B,QAAQ/b,IAGnC+Q,WAAW,WACP7Q,EAAK8b,SAASE,UAAUrd,KAAK,SAASga,EAAU3J,GAC5ChP,EAAKic,0BACLjc,EAAKsG,SAASyH,UAAUmO,yBAAyBvD,GAAU,EAAM3J,IAElE,SAAS2J,EAAU3J,GAElBhP,EAAKsG,SAASyH,UAAUmO,yBAAyBvD,GAAU,EAAO3J,MAEvE,KAIXiN,wBAAyB,aAEzBtI,SAAU,SAAS3R,EAAIqC,GACnBzc,KAAKmgB,YAAY3D,WAAWpC,EAAIqC,GAChCzc,KAAK6jB,gBAAkB7jB,KAAK6jB,eAAe0Q,UAAUna,IAGzDwX,iBAAkB,SAASxX,EAAI1Y,EAAMiqB,GACjC,GAAIzL,GAAalgB,KAAKmgB,YAAYvE,UAAUxB,GAAIA,GAGhD,WAAKpa,KAAKmjB,gBAAgB/I,IACnBpa,KAAK0e,SAASoF,MAAM0Q,YACpBtU,EAAWxF,SAAW/a,GAAG+a,OAAOyC,SAELrZ,SAA1B9D,KAAKijB,aAAa7I,KAClBpa,KAAKijB,aAAa7I,GAAM,GAGxBpa,KAAKijB,aAAa7I,GAAMpa,KAAK0e,SAASoF,MAAM2Q,oBAC5Cz0B,KAAKijB,aAAa7I,IAAO,GAClB,IAOnBuY,eAAgB,SAASvY,GACrBpa,KAAKse,WAAWzb,KAAKuX,IAIzBoU,aAAc,SAASpU,GACnB,GAAInC,EAGAA,GADAtY,GAAGkT,kBAAkBsC,cACVnV,KAAK4f,SAAS2B,QAAQnH,GAAI4L,WAG1BhmB,KAAKimB,aAAajmB,KAAK4f,SAASpG,SAASY,IAGpDnC,IACAjY,KAAK8hB,qBAAqB1H,GAAMnC,IAIxC+M,4BAA6B,SAAS0P,GAClC10B,KAAK0e,SAASzN,KAAKrR,QAAU80B,EAE7B10B,KAAK6uB,aAAelvB,GAAGmvB,aAAe,GAAInvB,IAAGmvB,YACrC9uB,KAAK0e,SAASzN,KAAMtR,GAAGgQ,KAAK3P,KAAKslB,kBAAmBtlB,MAAOL,GAAGgQ,KAAK3P,KAAK8F,IAAK9F,OAGjFA,KAAK6uB,cAAgB7uB,KAAK6uB,aAAaE,iBACvC/uB,KAAKsjB,aAAauF,YAAY,KAAM7oB,KAAK6uB,aAAaG,uBAEtDhvB,KAAK0e,SAASuQ,WAAajvB,KAAK6uB,aAAaK,cACzClvB,KAAK6uB,aAAaM,aAClBnvB,KAAK6kB,YAAY7kB,KAAK6uB,aAAaM,eAK/CyE,QAAS,SAASxZ,EAAI0D,EAAQC,GAC1B,GAAIrc,GAAO1B,KAAKqgB,QAAQjG,EAEpB0D,IACA9d,KAAKolB,UAAUtH,EAAQ1D,GAGvB2D,GACA/d,KAAK6kB,YAAY9G,EAAU3D,GAG/Bpa,KAAK4nB,wBACDlmB,KAAM,WACN0N,SAAUzP,GAAGgQ,KAAK3P,KAAK0e,SAASyH,UAAUwO,SAAU30B,KAAMoa,EAAI1Y,GAC9D4V,UAAW3X,GAAGgQ,KAAK3P,KAAKwyB,yBAA0BxyB,KAAMoa,EAAI1Y,GAC5D6V,UAAW5X,GAAGgQ,KAAK3P,KAAKmsB,oBAAqBnsB,KAAMoa,EAAI1Y,GACvDqmB,WAAY3N,KAIpBkG,YAAa,SAASlG,GACbpa,KAAK4f,SAAS/V,OAAOuQ,IACtBpa,KAAKmgB,YAAYrE,UAAU1B,EAAIza,GAAG+a,OAAOuC,SAIjDuI,mBAAoB,WAIhB,IAHA,GAAIoP,GAAYC,EACZzc,EAAOpY,KAEJA,KAAKse,WAAW5Y,QACnBkvB,EAAa50B,KAAKse,WAAWjM,QAC7BrS,KAAKsgB,YAAYsU,EAIrBC,GAAkB70B,KAAKqiB,YAAY3H,OAAQ/a,GAAG+a,OAAOY,aAAa5V,OAC9DmvB,IACAl1B,GAAGmG,IAAI,qBAAuB+uB,EAAkB,yEAChD5L,WAAW,WACP7Q,EAAKoN,sBACN,OAYXmO,wBAAyB,SAASpG,EAAa8D,GAC3C,GAAIjZ,GAAOpY,KACPuf,EAAQ,WACJ,MAAIgO,GAAYhO,eAAgB5f,IAAG8X,UACxB8V,EAAYhO,KAAK7H,cAErB6V,EAAYhO,QAEvB7d,EAAO2vB,EAAqB3vB,KAC5B8Z,EAAO6V,EAAqB7V,KAC5BvD,EAAWjY,KAAKimB,aAAasH,EAAYhO,MACzC2Q,EAAiBlwB,KAAKqtB,mBAAmBpV,GACzC6c,EAAkB,GAAIn1B,IAAG+L,OAQ7B,OANAopB,GAAgB/d,KACZ,aACA,WACIqB,EAAK+T,oBAAoBoB,EAAYnT,GAAI1Y,KAG7C/B,GAAG+I,cAAc6W,KAAUvf,KAAKspB,oBAAoB4G,EAAe3G,kBAAmB7nB,IACtF1B,KAAKulB,WAAW,YAAa7jB,EAAM6d,GAC5BuV,EAAgBhpB,WAGtB9L,KAAK0e,SAAS+K,WAAWsL,YAAuB,IAATvZ,EAKxCA,EAAO,GAAK0U,EAAeG,WAAa7U,EAAO0U,EAAeG,WAC9DrwB,KAAKulB,WAAW,YAAa7jB,EAAM6d,GAC5BuV,EAAgBhpB,WAGvB0P,EAAO,GAAKA,EAAO0U,EAAeI,cAClCtwB,KAAKulB,WAAW,eAAgB7jB,EAAM6d,GAC/BuV,EAAgBhpB,YAGvBnM,GAAGq1B,iBAAmBr1B,GAAGkT,kBAAkBkD,eAAiBpW,GAAGyI,OAAOmX,GACtE,GAAI5f,IAAGq1B,gBAAgBzV,EAAM5f,GAAGgQ,KAAKyI,EAAKtS,IAAKsS,IAAO6c,SAAS/E,EAAegF,OAAOne,KACjF+d,EAAgBlpB,QAChB,SAASupB,GACL/c,EAAKmN,WAAW4P,EAAY,aAAczzB,EAAM6d,GAChDuV,EAAgBhpB,YAKxBgpB,EAAgBlpB,UAGbkpB,IA3BH90B,KAAKulB,WAAW,aAAc7jB,EAAM6d,GAC7BuV,EAAgBhpB,YA6B/BspB,eAAgB,WACZ,GAAIhd,GAAMid,EAAcnpB,CAExBkM,GAAOpY,KAEPq1B,EAAe,SAAS3zB,EAAM0N,EAAUzH,GACpC,GAAI2tB,EAEJ,KACI,MAAOlmB,GAASY,MAAMoI,EAAMzQ,GAEhC,MAAO4tB,GACHD,EAAWC,EAAUxvB,SAAWwvB,EAAUjvB,WAC1C8R,EAAKtS,IAAI,wBAA0BpE,EAAO,gBAAkB4zB,EAAU,UAK9E,KAAKppB,IAAQlM,MAAK0e,SAASyH,WACtB,WACG,GAAIqP,GAAcC,CAClBD,GAAetpB,EACfupB,EAAerd,EAAKsG,SAASyH,UAAUqP,GACvCpd,EAAKsG,SAASyH,UAAUqP,GAAgB,WACpC,MAAOH,GAAaG,EAAcC,EAAc3tB,oBCh0DvE,WACG,YAEAnI,IAAG+1B,kBAAoB,SAAS5d,GAC5B,GAAIM,GAAOpY,IAGXA,MAAK0e,UACDqE,OAAO,EACPM,OAAQ,KACR3Z,UAAU,EACV+c,eAAgB,EAChBkP,6BAA6B,EAC7B1G,YAAY,EAEZtI,SACIE,iBACA9I,SAAU,iBACV6X,cAAe,aACfC,gBAAgB,EAChB/L,UAAW,SACXvD,OAAQ,OACRzI,UACAgY,cAAc,EACdC,kBAAmB,kBACnBnP,SAAU,UAGd6C,YACIF,qBACA8G,UAAW,EACXC,aAAc,EACd0B,UAAW,EACXZ,wBAAwB,EACxB7Y,YAAa,KACb2c,OACIc,UAAW,EACXC,SAAU,EACVC,UAAW,EACXC,SAAU,GAEdpB,YAAY,GAGhB5O,WACIwO,SAAU,SAASva,EAAI1Y,KACvBgxB,YAAa,SAAStY,EAAI1Y,KAC1BkpB,WAAY,SAASxQ,EAAI1Y,EAAMiqB,EAAcyK,KAC7CzE,cAAe,SAASF,EAAYC,KACpC5G,SAAU,SAAS1Q,EAAI1Y,KACvBypB,SAAU,SAAS/Q,EAAI1Y,KACvB2pB,cAAe,SAASjR,EAAI1Y,EAAM4pB,KAClCE,qBAAsB,SAASpR,EAAIkR,EAAWK,EAAcpY,KAC5DkY,SAAU,SAASrR,EAAIpI,EAAUsZ,KACjCd,WAAY,SAASpQ,EAAI1Y,EAAM+oB,EAAQC,KACvCyI,gBAAiB,SAAS1I,EAAQC,KAClCtE,QAAS,SAAShM,EAAI1Y,EAAMigB,EAAQ0U,KACpC3K,YAAa,SAAStR,EAAI1Y,EAAM40B,KAChCrE,cAAe,SAAS7X,EAAI1Y,KAC5BmyB,gBAAiB,SAAS0C,KAC1BjF,WAAY,SAASiF,KACrBxD,eAAgB,SAAS3Y,KACzB6M,SAAU,SAAS7M,KACnB+M,iBAAkB,SAAS/M,EAAIgN,EAAUC,KACzCQ,gBAAiB,SAASzc,KAC1BuQ,eAAgB,SAASvB,EAAI4B,EAAWD,KACxCuY,yBAA0B,SAASvD,EAAUnlB,EAASwb,MAG1D4I,UACIwG,UAAW,qEACXC,UAAW,yDACXC,aAAc,4DACdC,WAAY,yDACZC,aAAc,sBACdnD,kBAAmB,6EACnBoD,oBAAqB,qBACrBC,mBAAoB,qBACpBC,oBAAqB,4BACrBC,mBAAoB,4BACpBC,sBAAuB,mDACvBjD,QAAS,8EACTnD,6BAA8B,6KAGlC/M,OACI0Q,YAAY,EACZC,gBAAiB,EACjB3C,iBAAkB,EAClBvH,6BAA8B,gBAGlCb,SACIE,YAAa,yBACbD,YAAa,0BAGjBrU,UACI8K,SAAS,EACT8W,YACI9W,SAAS,GAEb+W,WAAW,EACXC,YACIC,UAAW,cACXC,eAAgB,mBAChBC,UAAW,cACXC,cAAe,kBACfC,WAAY,gBAEhBC,SAAU,IAEV9rB,SACImS,SAAU,OAIlB3H,QACIgK,SAAS,EACTuX,gBAAiB,EACjBP,YACIQ,SAAU,aAIlBxH,eAAgB,SAASyH,GACrB,MAAOA,IAGXx0B,MACI4tB,qBAAsB,gCACtBjH,eAAgB,aAChBqC,aAAc,KAAM,KAAM,KAAM,KAAM,KAAM,OAGhD9L,YACIH,SAAS,EACTmG,OAAQ,SACRxI,SAAU,iBACV8I,iBACA/I,WAGJkJ,MACIqI,UAAU,EACVyI,iBAAiB,EACjBxI,UAAU,GAGd3Q,OACIC,YAAa,aAGjB8I,OACID,cAAe,KACf7I,YAAa,gBAGjBgP,QACIvf,KAAK,EAGLgV,OAAQ,MASZqJ,gBAIAlJ,SACIzF,SAAU,KACVD,UACA+I,iBACApD,gBAAgB,GAIpBxS,MAEIrR,QAAS,UAGTqvB,YAAY,EAGZ8I,iBAAiB,GAIrB1hB,SACI2hB,cAAe,KAGfC,cAAc,EAGdC,QAAQ,EAIRC,YAAa,KAEbC,eAAgB,GAEhBC,YAAa,kBAEbC,aAAa,EAGbC,UAGJnP,aACIC,gBAAgB,EAChBsH,mBAAmB,EACnB9G,kBAAkB,IAK1BlqB,GAAG6B,OAAOxB,KAAK0e,SAAU5G,GAAG,GAE5B9X,KAAKojB,YACLpjB,KAAKysB,qBACLzsB,KAAK8hB,wBAEL9hB,KAAKo1B,iBACLp1B,KAAKiqB,gBAAmB,GAAItqB,IAAGsS,eAE/BjS,KAAKse,cACLte,KAAKijB,gBACLjjB,KAAKkjB,kBACLljB,KAAKmjB,mBACLnjB,KAAKqhB,kBAELrhB,KAAK6iB,qBAAuB,EAC5B7iB,KAAKyiB,aAAe,EACpBziB,KAAKmgB,YAAcngB,KAAK8oB,2BAExB9oB,KAAK4uB,4BAEL5uB,KAAKqkB,oBAAsBrkB,KAAKgoB,aAAahoB,KAAK0e,SAASiI,QAAQE,eACnE7mB,KAAKwkB,8BAAgCxkB,KAAKgoB,aAAahoB,KAAK0e,SAAS6B,WAAWsG,eAEhF7mB,KAAK4kB,uBAAyB5kB,KAAKgoB,aAAahoB,KAAK0e,SAAS6B,WAAWzC,QAEzE9d,KAAKgiB,eAAiBhiB,KAAKgoB,aAAahoB,KAAK0e,SAASiI,QAAQ5I,UAC9D/d,KAAK0kB,yBAA2B1kB,KAAKgoB,aAAahoB,KAAK0e,SAAS6B,WAAWxC,UAE3E/d,KAAK4f,SAAW5f,KAAKkqB,uBAErBlqB,KAAKgzB,eAAiBrzB,GAAG2mB,yBAA2BtmB,KAAKqmB,uBAErDrmB,KAAK0e,SAAS2E,SACdrjB,KAAK+sB,iBAAmB/sB,KAAKkpB,qBACzBtpB,QAASI,KAAK0e,SAAS2E,OACvBlL,MAAOnY,KAAK0e,SAASrb,KAAK2mB,iBAC3BvQ,eAGPzZ,KAAKwsB,4BAELxsB,KAAK2tB,sBAED3tB,KAAK0e,SAASgJ,MAAMD,gBAChB9nB,GAAG6nB,aACHxnB,KAAKujB,cAAgBvjB,KAAKunB,sBAG1BvnB,KAAK8F,IAAI,iCAAkC,UAInD9F,KAAK8zB,0BAEL9zB,KAAKohB,gBAAkBzhB,GAAG64B,gBAAkB,GAAI74B,IAAG64B,eAAe74B,GAAGgQ,KAAK3P,KAAK8F,IAAK9F,OACpFA,KAAK0jB,sBAEL1jB,KAAK2jB,kCACL3jB,KAAK4jB,+BAEL5jB,KAAKy4B,QAAW94B,GAAGukB,QAAU,GAAIvkB,IAAGukB,OAAOlkB,KAAK0e,SAASrI,QAAS1W,GAAGgQ,KAAK3P,KAAK8F,IAAK9F,WAChFA,KAAKy4B,QAAQrY,UACbpgB,KAAKquB,sBAAwB1uB,GAAGgQ,KAAK3P,KAAKy4B,QAAQC,cAAe14B,KAAKy4B,UAGtE94B,GAAGg5B,eAAiBh5B,GAAGkT,kBAAkBsD,cACzCnW,KAAK6jB,eAAiB,GAAIlkB,IAAGg5B,cACzBh5B,GAAGgQ,KAAK3P,KAAKkzB,iBAAkBlzB,MAE/B,SAASoa,GACL,GAAIwe,GAAQxgB,EAAK+H,YAAYvE,UAAUxB,GAAIA,GAC3C,OAAQwe,IAASA,EAAMpd,MAAS,KAK5Cxb,KAAK4iB,kBAAoB5iB,KAAK0e,SAAS+K,WAAWuI,WAItDryB,GAAG+1B,kBAAkBrvB,UAAY1G,GAAGge,cACpChe,GAAG6B,OAAO7B,GAAG+1B,kBAAkBrvB,UAAW1G,GAAG8lB,mBCnTjD9lB,GAAGk5B,cAAgB,SAAS/gB,GACxB,YA2CA,SAASghB,KACL,MAAOn5B,IAAG2F,SAAS,MAAO,OAAQ,QAAS4S,EAAQqO,SAAW,EAMlE,QAASwS,GAAyB3U,GAC9B,GAAI4U,IAAoB,CASxB,OAPAr5B,IAAG+C,KAAKs2B,EAAmB,SAASr2B,EAAKs2B,GACrC,GAAIt5B,GAAG2F,SAAS,SAAU,kBAAmB,mBAAoB,gBAAiB2zB,GAAU,EAExF,MADAD,IAAoB,GACb,IAIRA,EAGX,QAASE,GAAM3lB,GAEX,MAAO2E,GAAQ8O,KAAKqI,UAAoCvrB,SAAxByP,EAAIC,gBAIxC,QAAS2lB,KACL,GAAI/R,EAeJ,QAbIviB,OAAOiF,gBAAkBjF,OAAOkF,iBAChCqd,EAAWznB,GAAGiK,oBAEmB9F,SAA7BsjB,EAAS5T,kBACT4T,EAAW,GAAI1T,gBAEf0T,EAASzb,OAAS,aAClByb,EAASvb,QAAU,aACnBub,EAASgS,UAAY,aACrBhS,EAASiS,WAAa,eAIvBjS,EAIX,QAASkS,GAAYlf,EAAImf,GACrB,GAAInS,GAAWoS,EAAYpf,GAAI7G,GAkB/B,OAhBK6T,KAEGA,EADAmS,EACWA,EAGPrhB,EAAQ8O,KAAKqI,SACF8J,IAGAx5B,GAAGiK,oBAItB4vB,EAAYpf,GAAI7G,IAAM6T,GAGnBA,EAIX,QAASqS,GAAQrf,GACb,GAEIsf,GAFAjpB,EAAI9Q,GAAG2F,QAAQq0B,EAAOvf,GACtBkS,EAAMpU,EAAQuO,qBAGX+S,GAAYpf,GACnBuf,EAAMzd,OAAOzL,EAAG,GAEZkpB,EAAMj0B,QAAU4mB,GAAO7b,EAAI6b,IAC3BoN,EAASC,EAAMrN,EAAM,GACrBsN,EAAYF,IAIpB,QAAS9O,GAAWxQ,EAAIyf,GACpB,GAAItmB,GAAM+lB,EAAYlf,GAClBmM,EAASrO,EAAQqO,OACjBc,EAAUwS,KAAa,CAE3BJ,GAAQrf,GAEJiN,EACAvhB,EAAIygB,EAAS,gBAAkBnM,EAAK,cAAe,SAE7C8e,EAAM3lB,IAASumB,EAAqBvmB,EAAImH,UAC9C2M,GAAU,EACVvhB,EAAIygB,EAAS,gBAAkBnM,EAAK,+BAAiC7G,EAAImH,OAAQ,UAGrFxC,EAAQ0S,WAAWxQ,EAAI7G,EAAK8T,GAGhC,QAAS0S,GAAU3f,GACf,GAEI0D,GAFAkc,EAAiBR,EAAYpf,GAAI6f,iBACjCC,EAAiBhiB,EAAQgiB,cAqB7B,OAlBIhiB,GAAQ4O,YAAY7E,MACpBnE,EAAS5F,EAAQ4O,YAAY7E,IAAI7H,IAGjC4f,GACAr6B,GAAG+C,KAAKs3B,EAAgB,SAASt4B,EAAMkB,GACnCkb,EAASA,MACTA,EAAOpc,GAAQkB,IAInBs3B,GACAv6B,GAAG+C,KAAKw3B,EAAgB,SAASx4B,EAAMkB,GACnCkb,EAASA,MACTA,EAAOpc,GAAQkB,IAIhBkb,EAGX,QAAS8b,GAAYxf,EAAI+f,GACrB,GAIIC,GAJA7mB,EAAM+lB,EAAYlf,EAAI+f,GACtB5T,EAASrO,EAAQqO,OACjBzI,EAASic,EAAU3f,GACnBigB,EAAUb,EAAYpf,GAAIigB,OA+C9B,OA5CAniB,GAAQoiB,OAAOlgB,GAEfggB,EAAMG,EAAUngB,EAAI0D,EAAQ0b,EAAYpf,GAAIogB,uBAGxCtB,EAAM3lB,IACNA,EAAI5H,OAAS8uB,EAAkBrgB,GAC/B7G,EAAI1H,QAAU6uB,EAAmBtgB,IAGjC7G,EAAIonB,mBAAqBC,EAA8BxgB,GAG3DygB,EAA0BzgB,GAG1B7G,EAAIunB,KAAKvU,EAAQ6T,GAAK,GAIlBliB,EAAQ8O,KAAKqI,UAAYnX,EAAQ8O,KAAK8Q,kBAAoBoB,EAAM3lB,KAChEA,EAAIC,iBAAkB,GAG1BunB,EAAW3gB,GAEXtU,EAAI,WAAaygB,EAAS,gBAAkBnM,GAExCigB,EACA9mB,EAAIynB,KAAKX,GAEJY,IAAgCnd,EACrCvK,EAAIynB,OAECld,GAAU5F,EAAQgjB,aAAehjB,EAAQgjB,YAAYjyB,cAAc3D,QAAQ,sCAAwC,EACxHiO,EAAIynB,KAAKr7B,GAAGsQ,QAAQ6N,EAAQ,KAEvBA,GAAU5F,EAAQgjB,aAAehjB,EAAQgjB,YAAYjyB,cAAc3D,QAAQ,qBAAuB,EACvGiO,EAAIynB,KAAK1pB,KAAK6pB,UAAUrd,IAGxBvK,EAAIynB,KAAKld,GAGNvK,EAGX,QAASgnB,GAAUngB,EAAI0D,EAAQ0c,GAC3B,GAAIzc,GAAW7F,EAAQ6O,cAAc9E,IAAI7H,GACrCghB,EAAY5B,EAAYpf,GAAIghB,SAehC,OAZiBt3B,SAAbs3B,IACArd,GAAY,IAAMqd,GAGlBH,GAA+Bnd,IAC/BC,EAAWpe,GAAGsQ,QAAQ6N,EAAQC,IAG9Byc,IACAzc,EAAWpe,GAAGsQ,QAAQuqB,EAAuBzc,IAG1CA,EAKX,QAAS6c,GAA8BxgB,GACnC,MAAO,YACgC,IAA/Bkf,EAAYlf,GAAIihB,YAChBzQ,EAAWxQ,IAKvB,QAASygB,GAA0BzgB,GAC/B,GAAIoQ,GAAatS,EAAQsS,UAErBA,KACA8O,EAAYlf,GAAIvQ,OAAOwvB,WAAa,SAASxqB,GACrCA,EAAEysB,kBACF9Q,EAAWpQ,EAAIvL,EAAE4b,OAAQ5b,EAAE6b,SAQ3C,QAAS+P,GAAkBrgB,GACvB,MAAO,YACHwQ,EAAWxQ,IAMnB,QAASsgB,GAAmBtgB,GACxB,MAAO,YACHwQ,EAAWxQ,GAAI,IAIvB,QAAS2gB,GAAW3gB,GAChB,GAAI7G,GAAM+lB,EAAYlf,GAClByM,EAAgB3O,EAAQ2O,cACxB0U,EAAkB/B,EAAYpf,GAAIohB,sBAClCjV,EAASrO,EAAQqO,OACjBkV,IAGCvC,GAAM3lB,KACP2E,EAAQwjB,cAAgBnoB,EAAIooB,iBAAiB,SAAUzjB,EAAQwjB,cAG3DxjB,EAAQ0jB,qCAKH1jB,EAAQ8O,KAAKqI,UAAcyJ,MAAoBC,EAAyBlS,KACzEtT,EAAIooB,iBAAiB,mBAAoB,kBACzCpoB,EAAIooB,iBAAiB,gBAAiB,eAI1CzjB,EAAQgjB,aAA2B,SAAX3U,GAAgC,QAAXA,GAC7ChT,EAAIooB,iBAAiB,eAAgBzjB,EAAQgjB,aAGjDv7B,GAAG6B,OAAOi6B,EAAY97B,GAAG6G,WAAWqgB,GAAiBA,EAAczM,GAAMyM,GACzElnB,GAAG6B,OAAOi6B,EAAYF,GAEtB57B,GAAG+C,KAAK+4B,EAAY,SAAS/5B,EAAMkB,GAC/B2Q,EAAIooB,iBAAiBj6B,EAAMkB,MAKvC,QAASk3B,GAAqB+B,GAC1B,MAAOl8B,IAAG2F,QAAQ4S,EAAQ4jB,wBAAwB5jB,EAAQqO,QAASsV,IAAiB,EAGxF,QAASE,GAAc3hB,EAAI+f,EAAQiB,EAAWnB,EAAkBO,EAAuBgB,EAAmBnB,GACtGb,EAAYpf,IACRghB,UAAWA,EACXnB,iBAAkBA,EAClBO,sBAAuBA,EACvBgB,kBAAmBA,EACnBnB,QAASA,EAGb,IAAIxtB,GAAM8sB,EAAM92B,KAAKuX,EAGrB,IAAIvN,GAAOqL,EAAQuO,eACf,MAAOmT,GAAYxf,EAAI+f,GA7U/B,GAAIr0B,GAAKm1B,EACLtB,KACAH,KACAthB,GACIwjB,aAAc,KACdM,cAAe,QAAS,OAAQ,OAChCzV,OAAQ,OACR2U,YAAa,oCACbzU,eAAgB,EAChBI,iBACAE,iBACAD,eACAoT,kBACA0B,oCAAoC,EACpCE,yBACIG,QAAS,IAAK,IAAK,KACnBC,OAAQ,IAAK,IAAK,IAAK,IAAK,KAC5BC,MAAO,IAAK,IAAK,IAAK,IAAK,KAC3BC,KAAM,IAAK,IAAK,IAAK,IAAK,KAC1BC,KAAM,MAEVrV,MACIqI,UAAU,EACVyI,iBAAiB,GAErBhyB,IAAK,SAAS4B,EAAK1B,KACnBs0B,OAAQ,SAASlgB,KACjBwQ,WAAY,SAASxQ,EAAIgN,EAAUC,KACnCmD,WAAY,KAMpB,IAHA7qB,GAAG6B,OAAO0W,EAASJ,GACnBhS,EAAMoS,EAAQpS,IAEVnG,GAAG2F,QAAQ4S,EAAQ8jB,aAAc9jB,EAAQqO,QAAU,EACnD,KAAM,IAAIplB,OAAM,IAAM+W,EAAQqO,OAAS,wDA8S3C0U,GAAiD,QAAnB/iB,EAAQqO,QAAuC,WAAnBrO,EAAQqO,OAElE5mB,GAAG6B,OAAOxB,MAENs8B,cAAe,SAASliB,GACpB,GAAImiB,GAAMze,EAAQsG,EAASiW,EAASmC,EAAahC,CAEjD,QAEIiC,SAAU,SAASC,GAEf,MADAH,GAAOG,EACA18B,MAOX28B,WAAY,SAAS1C,GAEjB,MADAnc,GAASmc,EACFj6B,MAGX48B,gBAAiB,SAASC,GAEtB,MADArC,GAAwBqC,EACjB78B,MAIX88B,YAAa,SAAStB,GAElB,MADApX,GAAUoX,EACHx7B,MAIX+8B,YAAa,SAASC,GAElB,MADA3C,GAAU2C,EACHh9B,MAIXi9B,gBAAiB,WAEb,MADAT,IAAc,EACPx8B,MAIXg7B,KAAM,SAASb,GAKX,MAJIqC,IAAe78B,GAAG2F,SAAS,MAAO,UAAW4S,EAAQqO,SAAW,IAChEzI,EAAOof,aAAc,GAAIC,OAAOC,WAG7BrB,EAAc3hB,EAAI+f,EAAQoC,EAAMze,EAAQ0c,EAAuBpW,EAASiW,MAK3FgD,SAAU,SAASjjB,GACfqf,EAAQrf,OC1YpBza,GAAG29B,cAAgB,SAASjiB,GACxB,YAEA,IAAIkiB,GAAQliB,EAAKkiB,MACbC,KACA1S,EAAWyS,EAAMzS,SACjBzK,EAAUkd,EAAMld,OAEpB1gB,IAAG6B,OAAOxB,MACNuQ,IAAK,SAAS6J,EAAIqjB,GACdD,EAAUpjB,GAAMqjB,EAChBD,EAAUpjB,GAAIjK,SAGlBwP,OAAQ,SAASvF,GACb,GAAIhC,GAAOpY,KACP+qB,EAA2B,GAAIprB,IAAG+L,QAClCgyB,EAAiB5S,EAAS1Q,EAAIiG,EAAQjG,GAAK2Q,EAE/C2S,GAAe3mB,KAAK,WACZqB,EAAKuI,QAAQvG,KACbojB,EAAUpjB,GAAIijB,UAAW,EACzBjlB,EAAKga,QAAQhY,IAEjB2Q,EAAyBnf,aAIjCwmB,QAAS,SAAShY,SACPojB,GAAUpjB,IAGrBujB,oBAAqB,SAASvjB,GAC1B,MAAOojB,GAAUpjB,GAAI5K,KAGzBmR,QAAS,SAASvG,GACd,MAAyBtW,UAAlB05B,EAAUpjB,IAGrBN,MAAO,WACH0jB,MAGJI,cAAe,SAASxjB,GACpB,MAAOojB,GAAUpjB,IAGrByjB,qBAAsB,SAASzjB,EAAI0jB,GAC/BN,EAAUpjB,GAAI5K,IAAMsuB,GAGxBC,aAAc,SAAS3jB,GACnB,QAASojB,EAAUpjB,GAAIijB,aCpDnC19B,GAAGusB,wBAA0B,SAASpU,EAAGsS,GACrC,YAEA,IAGc4T,GAAsBl4B,EAAKsoB,EAHrC6P,EAAaj+B,KACbk+B,GAAmB,EACnBC,GAA6B,EAGjCjmB,GACI4O,eACAL,eAAgB,EAChBnR,UACI8K,SAAS,EACT1W,UACI0W,SAAS,IAGjBta,IAAK,SAAS4B,EAAK1B,KACnBwkB,WAAY,SAASpQ,EAAIpI,EAAUyY,EAAQC,KAC3CE,WAAY,SAASxQ,EAAIpI,EAAU+e,EAAUxd,KAC7CuX,SAAU,SAAS1Q,EAAIpI,KACvBiZ,aAAc,SAAS7Q,KACvB+Q,SAAU,SAAS/Q,EAAIpI,KACvBqZ,cAAe,SAASjR,EAAIpI,EAAUsZ,KACtCE,qBAAsB,SAASpR,EAAIkR,EAAWyF,EAAUxd,KACxDmY,YAAa,SAAStR,EAAIpI,EAAU+e,EAAUxd,KAC9CkY,SAAU,SAASrR,EAAIpI,EAAUsZ,KACjCO,cAAe,SAASzR,EAAIgC,KAC5BiE,QAAS,SAASjG,KAClB0R,QAAS,SAAS1R,EAAIqC,KACtBwP,SAAU,SAAS7R,KACnByC,mBAAoB,SAASzC,KAC7B0C,cAAe,SAAS1C,MAG5BgkB,GAEI5mB,KAAM,SAAS4C,EAAIikB,EAAUtN,EAAUxd,GACnC,GAAI+X,GAAY8C,EAAQkQ,cAAclkB,EAAIikB,EAE1CjQ,GAAQwP,cAAcxjB,GAAImkB,kBAAmB,QAEtCnQ,GAAQwP,cAAcxjB,GAAIjK,KAAKquB,cAAcH,GACpDjQ,EAAQwP,cAAcxjB,GAAIqQ,QAAUa,EAAU9P,KAE9CtD,EAAQsT,qBAAqBpR,EAAIgU,EAAQqQ,yBAAyBnT,GAAYyF,EAAUxd,IAK5FmrB,SAAU,SAAStkB,GACf,GAAIoB,GAAOtD,EAAQqK,QAAQnI,GACvB1Y,EAAOwW,EAAQmI,QAAQjG,EAE3BtU,GAAI,qCAAuCsU,EAAK,qBAChDgU,EAAQuQ,eAAevkB,GAAIrD,KACvB,SAASga,EAAUxd,GACfzN,EAAI,2BAA6BsU,EAEjC,IAAIwkB,GAAoB/0B,EAAOg1B,kBAAkB9N,GAAU,EAE3D7Y,GAAQsS,WAAWpQ,EAAI1Y,EAAM8Z,EAAMA,GACnC4S,EAAQ0Q,+BAA+B1kB,GACvCvQ,EAAOk1B,QAAQ3kB,EAAIwkB,EAAmBrrB,IAE1C,SAASwd,EAAUxd,GACf,GAAIqrB,GAAoB/0B,EAAOg1B,kBAAkB9N,GAAU,EAE3DjrB,GAAI,yCAA2CsU,EAAK,MAAQwkB,EAAkB50B,MAAO,SAEjF40B,EAAkB9kB,OAClBskB,EAAQtkB,MAAMM,GAGblC,EAAQwT,YAAYtR,EAAI1Y,EAAMk9B,EAAmBrrB,IAClD1J,EAAOk1B,QAAQ3kB,EAAIwkB,EAAmBrrB,MAMtDyrB,cAAe,SAASX,EAAUjkB,EAAI2W,EAAUxd,GAC5C,GAAI7R,GAAOwW,EAAQmI,QAAQjG,EAE3BtU,GAAI,qCAAuCsU,EAAK,WAAaikB,GAE7DjQ,EAAQ6Q,iBAAiB7kB,EAAIikB,EAE7B,IACIa,GADAC,EAAmBt1B,EAAOg1B,kBAAkB9N,GAAU,EAGtDoO,GAAiBrlB,MACjBskB,EAAQtkB,MAAMM,IAGd8kB,EAAgBv/B,GAAG2F,QAAQ8oB,EAAQwP,cAAcxjB,GAAI9E,SAAS8pB,WAAYf,GACtEa,GAAiB,IACjB9Q,EAAQwP,cAAcxjB,GAAI9E,SAAS8pB,WAAWljB,OAAOgjB,EAAe,GACpE9Q,EAAQwP,cAAcxjB,GAAI9E,SAAS+pB,UAAUC,QAAQjB,KAMxDjQ,EAAQwP,cAAcxjB,GAAIjK,KAAKovB,gBAG5BpB,IACA/P,EAAQwP,cAAcxjB,GAAIjK,KAAKovB,eAAgB,EAE/Cz5B,EAAInG,GAAG8H,OAAO,mFAAoF6J,KAAK6pB,UAAU/0B,OAAOo5B,KAAKpR,EAAQqR,SAASrlB,KAAO9I,KAAK6pB,UAAU/M,EAAQwP,cAAcxjB,GAAI9E,SAAS8pB,cACvMz/B,GAAG+C,KAAK0rB,EAAQqR,SAASrlB,GAAK,SAASslB,EAAMC,GACzC75B,EAAInG,GAAG8H,OAAO,sDAAuD2S,EAAIslB,EAAMC,EAAMtE,aACrFsE,EAAMC,QAGND,EAAME,YAAa,IAIvBzR,EAAQ0R,0BAA0B1lB,GAIlC2lB,EAAkBC,KAAK5lB,GAAI,IAG1BlC,EAAQwT,YAAYtR,EAAI1Y,EAAMy9B,EAAkB5rB,IAIjD1J,EAAOk1B,QAAQ3kB,EAAI+kB,EAAkB5rB,KAKjD0sB,aAAc,SAAS7lB,GACnB,QAASgU,EAAQwP,cAAcxjB,GAAI9E,SAAS+pB,UAAU35B,QAG1Dw6B,SAAU,SAAS9lB,GACf,GAAI+lB,GAAU/R,EAAQwP,cAAcxjB,GAAI9E,SAAS+pB,UAAUhtB,OAM3D,OAJI8tB,IAAW/R,EAAQgS,gBAAgBhmB,KACnC+lB,EAAU,MAGPA,GAGXrmB,MAAO,SAASM,GACZtU,EAAI,8FAAgGsU,EAAI,SAExGgU,EAAQ0Q,+BAA+B1kB,GACvCgU,EAAQiS,mBAAmBjmB,GAC3BgU,EAAQwP,cAAcxjB,GAAIqQ,OAAS,GAGvC6V,SAAU,SAASlmB,GACf,GAAIoB,GAAOtD,EAAQqK,QAAQnI,GACvB1Y,EAAOwW,EAAQmI,QAAQjG,GACvBikB,EAAWD,EAAQ8B,SAAS9lB,GAC5BkR,EAAY8C,EAAQkQ,cAAclkB,EAAIikB,GACtCzG,EAAWxJ,EAAQwP,cAAcxjB,GAAImkB,iBACrCgC,EAAmBnS,EAAQwP,cAAcxjB,GAAI9E,SAAS8pB,cAElB,OAApChR,EAAQwP,cAAcxjB,GAAIqQ,SAC1B2D,EAAQwP,cAAcxjB,GAAIqQ,OAAS,GAInCmN,GAAY1f,EAAQuT,SAASrR,EAAI1Y,EAAM4pB,MAAe,IACtD8S,EAAQtkB,MAAMM,GACdikB,EAAWD,EAAQ8B,SAAS9lB,GAC5BkR,EAAY8C,EAAQkQ,cAAclkB,EAAIikB,GACtCzG,GAAW,GAIC,MAAZyG,GAAgD,IAA5BkC,EAAiB76B,OACrC04B,EAAQM,SAAStkB,IAKjBtU,EAAInG,GAAG8H,OAAO,oEAAqE2S,EAAIikB,EAAU/S,EAAU3gB,MAAQ,EAAG2gB,EAAU1gB,IAAK4Q,IACrItD,EAAQmT,cAAcjR,EAAI1Y,EAAM0sB,EAAQqQ,yBAAyBnT,IACjEiV,EAAiB19B,KAAKw7B,GACtBjQ,EAAQwP,cAAcxjB,GAAI9E,SAAS8pB,WAAamB,EAE5CpC,GACA4B,EAAkBjF,KAAK1gB,EAAIikB,GAG3BF,GAA8B4B,EAAkBS,aAAepS,EAAQwP,cAAcxjB,GAAI9E,SAAS+pB,UAAU35B,QAC5G04B,EAAQkC,SAASlmB,GAGO,IAAxBkR,EAAUlgB,KAAKoQ,MACf1V,EAAInG,GAAG8H,OAAO,+DAAgE42B,EAAUjkB,GAAK,SAC7FgkB,EAAQY,cAAcX,EAAUjkB,EAAI,8BAA+B,OAGnEgU,EAAQqS,YAAYrmB,EAAIikB,EAAUzG,GAAU7gB,KAExC,SAAiBga,EAAUxd,GACvBzN,EAAI,wCAA0CsU,EAAK,WAAaikB,GAEhEjQ,EAAQ6Q,iBAAiB7kB,EAAIikB,EAE7B,IAAIkC,GAAmBnS,EAAQwP,cAAcxjB,GAAI9E,SAAS8pB,eACtDD,EAAmBt1B,EAAOg1B,kBAAkB9N,GAAU,GACtD2P,EAAqB/gC,GAAG2F,QAAQi7B,EAAkBlC,EAEtDv4B,GAAInG,GAAG8H,OAAO,8CAA+C42B,EAAUjkB,IAEvEgkB,EAAQ5mB,KAAK4C,EAAIikB,EAAUc,EAAkB5rB,GAEzCmtB,GAAsB,GACtBH,EAAiBrkB,OAAOwkB,EAAoB,GAGhDtS,EAAQuS,0BAA0BvmB,GAE7BgkB,EAAQ6B,aAAa7lB,IAAmC,IAA5BmmB,EAAiB76B,OAGzC04B,EAAQ6B,aAAa7lB,GAC1BgkB,EAAQkC,SAASlmB,GAGjBtU,EAAInG,GAAG8H,OAAO,oGAAqG2S,EAAI9I,KAAK6pB,UAAUoF,KANtInC,EAAQM,SAAStkB,IAWzB,SAAiB2W,EAAUxd,GACvB6qB,EAAQY,cAAcX,EAAUjkB,EAAI2W,EAAUxd,KAGjDiE,KAAK,WACF4W,EAAQwS,SAASxmB,EAAIikB,QAO7C0B,GACIc,SACAC,eACAC,YAEAP,UAAW,WACP,GAAIlU,GAAMpU,EAAQuO,eACdua,EAAwB,EACxBC,EAAkB,CAOtB,OALAthC,IAAG+C,KAAKq9B,EAAkBe,YAAa,SAASjgB,EAAQqgB,GACpDF,IACAC,GAAmBC,EAAiBx7B,SAGjC4mB,GAAOyT,EAAkBc,MAAMn7B,OAASs7B,EAAwBC,IAM3EjB,KAAM,SAAS5lB,EAAI+mB,GACf,GAGIzH,GAHA0H,GAAaD,EACbE,EAAe1hC,GAAG2F,QAAQy6B,EAAkBgB,SAAU3mB,GACtDknB,EAAmB3hC,GAAG2F,QAAQy6B,EAAkBc,MAAOzmB,SAGpD2lB,GAAkBe,YAAY1mB,GAEjCvQ,EAAO03B,eAAennB,YAAeza,IAAG8X,YACxC3R,EAAI,uCAAyCsU,EAAK,qCAC3CgU,GAAQwP,cAAcxjB,GAAImF,MAIjC8hB,GAAgB,EAChBtB,EAAkBgB,SAAS7kB,OAAOmlB,EAAc,GAG3CD,GAAaE,GAAoB,IACtCvB,EAAkBc,MAAM3kB,OAAOolB,EAAkB,GAEjD5H,EAASqG,EAAkBgB,SAAS1uB,QAChCqnB,GAAU,IACVqG,EAAkBc,MAAMh+B,KAAK62B,GAC7B7vB,EAAOc,MAAM+uB,MAKzB8H,sBAAuB,WACnB,GAAIC,KAqBJ,OAjBA9hC,IAAG+C,KAAKq9B,EAAkBe,YAAa,SAASjgB,EAAQ6gB,GAChDA,GAAUA,EAAOh8B,QACjB+7B,EAAmB5+B,KAAK8+B,SAAS9gB,MAMzClhB,GAAG+C,KAAKq9B,EAAkBc,MAAO,SAASl+B,EAAKke,GACtCkf,EAAkBe,YAAYjgB,IAC/B4gB,EAAmB5+B,KAAK8+B,SAAS9gB,MAKzC4gB,EAAqBA,EAAmB1xB,OAAOgwB,EAAkBgB,WAKrEa,kBAAmB,SAASxnB,GACxB,MAAOza,IAAG2F,QAAQy6B,EAAkBc,MAAOzmB,IAAO,GAGtD0gB,KAAM,SAAS1gB,EAAIikB,GAKf,MAJgB,OAAZA,GACA0B,EAAkBgB,SAASl+B,KAAKuX,KAGhC2lB,EAAkBS,cACF,MAAZnC,GACA0B,EAAkBgB,SAASc,MAC3B9B,EAAkBc,MAAMh+B,KAAKuX,KAG5B,WACG,GAAI0nB,GAAkB/B,EAAkBe,YAAY1mB,MACpD0nB,GAAgBj/B,KAAKw7B,GACrB0B,EAAkBe,YAAY1mB,GAAM0nB,MAIrC,IAMfhoB,MAAO,WACHimB,EAAkBgB,YAClBhB,EAAkBc,WAI1BkB,GACI/G,KAAM,SAAS5gB,EAAI1Y,GACf0sB,EAAQwP,cAAcxjB,GAAIqQ,OAAS,EAEnC3kB,EAAI,qCAAuCsU,GAC3CgU,EAAQ4T,WAAW5nB,GAAIrD,KACnB,SAASga,EAAUoJ,GACfr0B,EAAI,uCAAyCsU,EAE7C,IAAI+kB,GAAmBt1B,EAAOg1B,kBAAkB9N,GAAU,GACtDvV,EAAOtD,EAAQqK,QAAQnI,EAE3BlC,GAAQsS,WAAWpQ,EAAI1Y,EAAM8Z,EAAMA,GACnC3R,EAAOo4B,aAAa7nB,EAAI+kB,GACxBt1B,EAAOk1B,QAAQ3kB,EAAI+kB,EAAkBhF,IAGzC,SAASpJ,EAAUoJ,GACfr0B,EAAI,oCAAsCsU,EAE1C,IAAI+kB,GAAmBt1B,EAAOg1B,kBAAkB9N,GAAU,EAErD7Y,GAAQwT,YAAYtR,EAAI1Y,EAAMy9B,EAAkBhF,IACjDtwB,EAAOk1B,QAAQ3kB,EAAI+kB,EAAkBhF,OAOzDtwB,GACI8V,OAAQ,SAASvF,GACbtU,EAAI,cAAgBsU,GACpBlC,EAAQ4O,YAAY/lB,OAAOqZ,GAC3B2lB,EAAkBC,KAAK5lB,IAG3B2kB,QAAS,SAAS3kB,EAAI2W,EAAUoJ,GAC5B,GAAIz4B,GAAOwW,EAAQmI,QAAQjG,EAE3BlC,GAAQ0S,WAAWxQ,EAAI1Y,EAAMqvB,EAAUoJ,GAEnC/L,EAAQwP,cAAcxjB,IACtBgU,EAAQ8T,YAAc9T,EAAQ8T,WAAW9nB,GAG7C2lB,EAAkBC,KAAK5lB,IAK3BmnB,eAAgB,SAASnnB,GACrB,MAAQgU,GAAQ+T,UAAY/T,EAAQ+T,SAAS/nB,IACxCgU,EAAQ7M,SAAW6M,EAAQ7M,QAAQnH,IAG5CgoB,YAAa,WACT,GAAIC,GAAcjY,EAAYzqB,GAAGyqB,GAAazqB,GAAG2iC,YAC7CC,EAAuB5iC,GAAGkT,kBAAkBsC,cAAgB,MAAQ,MAExEiZ,GAAU,GAAIiU,GAAYE,EAAuB,iBAC7CrqB,GAEI8T,cAAe9T,EAAQ8T,cACvB3L,QAASnI,EAAQmI,QACjBkC,QAASrK,EAAQqK,QACjBO,QAAS5K,EAAQ4K,QACjBhd,IAAKA,EACLglB,SAAU5S,EAAQ4S,SAClBN,WAAYtS,EAAQsS,WACpBqB,cAAe3T,EAAQ2T,gBAI3BuC,EAAQoU,+BACRpU,EAAQoU,iCAIhBC,4BAA6B,SAASroB,GAClC,MAAOlC,GAAQ+T,SAAS7R,IAM5BsoB,WAAY,SAAStoB,EAAIhP,GAIrB,MAAIA,KAASgjB,EAAQ7M,QAAQnH,IAAOhP,YAAgBzL,IAAG8X,WAKnDS,EAAQ+S,aAAa7Q,GAErBtU,EAAI,+CAAiDsU,GACrDhP,EAAKwM,SAASb,KAAK,SAAS4rB,GACxB78B,EAAI,mCAAqCsU,GAGzCgU,EAAQwU,WAAWxoB,EAAIuoB,GAGvBzqB,EAAQ4T,QAAQ1R,EAAIuoB,EAAcnnB,MAGlC4S,EAAQiS,mBAAmBjmB,GAE3BvQ,EAAOg5B,uBAAuBzoB,IAIlC,SAASmZ,GACL,GAAIuP,KAEAvP,KACAuP,EAAc94B,MAAQupB,GAG1BztB,EAAInG,GAAG8H,OAAO,yDAA0D2S,EAAImZ,GAAe,SAE3Frb,EAAQ0S,WAAWxQ,EAAIlC,EAAQmI,QAAQjG,GAAKza,GAAG6B,OAAOshC,EAAe9E,GAAuB,MAC5Fn0B,EAAOg5B,uBAAuBzoB,GAC9B2lB,EAAkBC,KAAK5lB,MAOxB,GAHIvQ,EAAOg5B,uBAAuBzoB,IAO7CyoB,uBAAwB,SAASzoB,GAC7B,GAAI2oB,GAAa7qB,EAAQ2E,mBAAmBzC,GACxC4oB,GAAiB,CAoBrB,OAlBID,IAAcA,EAAWr9B,QACzBI,EAAI,0CAA4CsU,GAEhDza,GAAG+C,KAAKqgC,EAAY,SAASpgC,EAAKsgC,GAC9B,GAAIp5B,EAAO44B,4BAA4BQ,IAAgB7U,EAAQ7M,QAAQ0hB,GACnED,EAAiBC,IAAc7oB,EAC/BvQ,EAAOq5B,IAAID,OAEV,IAAIp5B,EAAO44B,4BAA4BQ,GACxC,OAAO,MAKfD,GAAiB,EACjBn5B,EAAOq5B,IAAI9oB,IAGR4oB,GAGXf,aAAc,SAAS7nB,EAAI2W,GACEjtB,SAArBitB,EAAS3U,SACTlE,EAAQ2T,cAAczR,EAAI2W,EAAS3U,UAO3CyiB,kBAAmB,SAASsE,EAAkB1R,GAC1C,GAAIV,GAAWoS,CAcf,OAVKxjC,IAAGuG,SAASi9B,KACbpS,KAEIpxB,GAAGwH,SAASg8B,KAAsB1R,IAClCV,EAAS/mB,MAAQm5B,IAIzBpS,EAASnlB,QAAU6lB,EAEZV,GAGXmS,IAAK,SAAS9oB,GACV,GAAI1Y,GAAOwW,EAAQmI,QAAQjG,EAE3B,KAAK6jB,EAAWtd,QAAQvG,GACpB,KAAM,IAAIza,IAAGwB,MAAMiZ,EAAK,qCAG5BlC,GAAQiT,SAAS/Q,EAAI1Y,GAEjBw8B,GAAoB9P,EAAQgV,qBAAqBhpB,GACjDgkB,EAAQkC,SAASlmB,GAGjB2nB,EAAO/G,KAAK5gB,EAAI1Y,IAIxBiJ,MAAO,SAASyP,GACZ,GAAIipB,GAAex5B,EAAO03B,eAAennB,EAEzC,OAAIipB,GACOx5B,EAAO64B,WAAWtoB,EAAIipB,IAG7Bx5B,EAAOq5B,IAAI9oB,IACJ,IAKnBza,IAAG6B,OAAOxB,MAINuQ,IAAK,SAAS6J,EAAImF,GACd6O,EAAQ7d,IAAIP,MAAMhQ,KAAM8H,YAM5B+B,OAAQ,SAASuQ,GACb,QAAI2lB,EAAkBjF,KAAK1gB,IAChBvQ,EAAOc,MAAMyP,IAK5B0J,MAAO,SAAS1J,GAWZ,MANI+jB,KACA/P,EAAQwP,cAAcxjB,GAAIjK,KAAKovB,eAAgB,GAK/CQ,EAAkB6B,kBAAkBxnB,GAC7BvQ,EAAOc,MAAMyP,GAOb6jB,EAAWp0B,OAAOuQ,IAOjCuF,OAAQ,SAASvF,GACb,GAAIkpB,GAAelV,EAAQzO,OAAOvF,EAE9Bza,IAAGkX,iBAAiBysB,GACpBA,EAAavsB,KAAK,WACdlN,EAAO8V,OAAOvF,KAGbkpB,KAAiB,GACtBz5B,EAAO8V,OAAOvF,IAOtByF,UAAW,WACP,GACIpP,GADAgxB,EAAqB1B,EAAkByB,uBAK3C,IAAIC,EAAmB/7B,OACnB,IAAK+K,EAAIgxB,EAAmB/7B,OAAS,EAAG+K,GAAK,EAAGA,IAC5CwtB,EAAWte,OAAO8hB,EAAmBhxB,GAI7CsvB,GAAkBjmB,SAKtByH,QAAS,SAASnH,GACd,MAAIgU,GAAQ+T,UAAY/T,EAAQ+T,SAAS/nB,GAC9BgU,EAAQ+T,SAAS/nB,GAAI1C,cAGzB0W,EAAQ7M,SAAW6M,EAAQ7M,QAAQnH;EAI9CmpB,UAAW,SAASnpB,GAChB,SAAUgU,EAAQ+T,WAAY/T,EAAQ+T,SAAS/nB,KAGnDZ,SAAU,SAASY,GACf,GAAIgU,EAAQ5U,SACR,MAAO4U,GAAQ5U,SAASY,IAIhCN,MAAO,WACHhU,EAAI,4BACJm4B,EAAWpe,YACXkgB,EAAkBjmB,QAClBsU,EAAQtU,SAGZsY,QAAS,SAAShY,GACd,GAAI6jB,EAAWtd,QAAQvG,GACnB,MAAOgU,GAAQgE,QAAQhY,IAO/BuG,QAAS,SAASvG,GACd,MAAOgU,GAAQzN,QAAQvG,IAG3BkI,sBAAuB,WACnB,MAAI8L,GAAQ9L,sBACD8L,EAAQ9L,4BAavBqb,oBAAqB,SAASvjB,GAC1B,GAAI6jB,EAAWtd,QAAQvG,GACnB,MAAOgU,GAAQuP,oBAAoBvjB,IAS3ClE,MAAO,SAASkE,GACZ,SAAI6jB,EAAWuF,YAAYppB,IAAOgU,EAAQlY,OAAS+nB,EAAWtd,QAAQvG,IAAOgU,EAAQlY,MAAMkE,MACvF2lB,EAAkBC,KAAK5lB,GACvBgU,EAAQ0R,0BAA0B1lB,IAC3B,IAMfopB,YAAa,SAASppB,GAClB,QAASgU,EAAQoV,aAAepV,EAAQoV,YAAYppB,MAI5Dza,GAAG6B,OAAO0W,EAASJ,GACnBhS,EAAMoS,EAAQpS,IACdo4B,EAAmBhmB,EAAQ5C,SAAS8K,SAAWzgB,GAAGkT,kBAAkByC,SACpE6oB,EAA6BD,GAAoBhmB,EAAQ5C,SAAS4hB,WAAW9W,QAE7E4d,EAAwB,WACpB,GAAIjN,KAIJ,OAFAA,GAAS7Y,EAAQoS,oBAAqB,EAE/ByG,KAGXlnB,EAAOu4B,eC9uBXziC,GAAG8jC,qBAAuB,SAAS3rB,GAC/B,YAEA,IAAII,IACIpS,IAAK,SAASC,EAASC,MAE3B09B,IAEJ/jC,IAAG6B,OAAO0W,EAASJ,GAEnBnY,GAAG6B,OAAOxB,MACN2jC,eAAgB,SAASvpB,EAAIhL,GACzB,GAAIw0B,GAA2B,SAAS7P,GAChC3kB,EAAS2kB,EAAMpvB,MAGnBE,QAAOqQ,YACPwuB,EAAyBtpB,GAAMza,GAAGkF,QAAQ5E,OAAO,UAAW2jC,GAG5D99B,IAAI,wDAAyD,UAIrE+9B,sBAAuB,SAASzpB,GAC5B,GAAIvV,OAAOqQ,YAAa,CACpB,GAAI4uB,GAAWJ,EAAyBtpB,EACpC0pB,IACAA,SCvBpBnkC,GAAGokC,kBAAoB,SAAS1oB,GAC5B,YAoBA,SAAS2oB,GAAY5pB,SACV6pB,GAAiB7pB,GAKpB8pB,IACAhS,aAAaiS,EAA0B/pB,UAChC+pB,GAA0B/pB,GACjCgqB,EAAoBP,sBAAsBzpB,GAG9C,IAAIiqB,GAAS76B,SAAS86B,eAAelW,EAAQmW,eAAenqB,GACxDiqB,KAIAA,EAAOnzB,aAAa,MAAO,qBAE3BvR,GAAG0kC,GAAQtjC,UAQnB,QAASyjC,GAAuBC,GAC5B,MAAOA,GAAWp/B,MAAM,KAAK,GAUjC,QAASq/B,GAAoBhjC,GACzB,GAAI2iC,GAAS1kC,GAAGoP,UAAU,yCAA2CrN,EAAO,OAO5E,OALA2iC,GAAOnzB,aAAa,KAAMxP,GAE1B2iC,EAAOvkC,MAAMC,QAAU,OACvByJ,SAASm7B,KAAKxzB,YAAYkzB,GAEnBA,EAUX,QAASO,GAA4BP,EAAQj1B,GACzC,GAAIq1B,GAAaJ,EAAOjqB,GACpByG,EAAS2jB,EAAuBC,GAChClqB,EAAOuI,EAAQjC,EAEnBgkB,GAAgBtqB,GAAQnL,EAIxB60B,EAAiBpjB,GAAUlhB,GAAG0kC,GAAQpkC,OAAO,OAAQ,WAC7CmuB,EAAQ5U,SAASqH,KACjB/a,EAAI,mEAAqE2+B,EAAa,KAEtFN,EAA0BM,GAAcxb,WAAW,WAC/C,GAAIsK,GAAe,gEAAkEkR,CACrF3+B,GAAIytB,EAAc,SAClBnkB,GACIpF,MAAOupB,KAEZ,QAMX6Q,EAAoBT,eAAec,EAAY,SAAS1+B,GACpDD,EAAI,2CAA6CC,EAAU,IAC3D,IAGI++B,GAFA/T,GADSyT,EAAuBC,GACrBrW,EAAQ2W,mBAAmBh/B,IACtCwU,EAAOwW,EAASxW,IAGhBA,IAAQsqB,EAAgBtqB,IACxBzU,EAAI,qCAAuC2+B,GAC3CvS,aAAaiS,EAA0BM,UAChCN,GAA0BM,GAEjCrW,EAAQ4W,iBAAiBP,GAEzBK,EAAiBD,EAAgBtqB,SAE1BsqB,GAAgBtqB,GACvB6pB,EAAoBP,sBAAsBY,GAC1CK,EAAe/T,IAETxW,GACNzU,EAAI,IAAMC,EAAU,2CAxHhC,GAAImS,GAAUmD,EAAKnD,QACfkW,EAAUpuB,KACVu9B,EAAQliB,EAAKkiB,MACb0H,EAAwBtlC,GAAGoN,cAC3B83B,KACAZ,KACAE,KACAD,EAAShsB,EAAQgsB,OACjBpa,EAAY5R,EAAQ4R,UACpBhH,EAAUya,EAAMza,QAChBhd,EAAMy3B,EAAMz3B,IACZs+B,EAAsB,GAAIzkC,IAAG8jC,sBAAsB39B,IAAKA,GAkH5DnG,IAAG6B,OAAOxB,KAAM,GAAIL,IAAG29B,cAAcjiB,IAErC1b,GAAGwM,SAASnM,KAAM,SAASsM,GACvB,OAIIiE,IAAK,SAAS6J,EAAI8S,GACd5gB,EAAOiE,IAAI6J,GAAK7Q,MAAO2jB,IAEvBA,EAAUhc,aAAa,OAAQ4Y,GAG3BoD,EAAUpsB,YACVnB,GAAGutB,GAAWnsB,UAItBqxB,QAAS,SAAShY,GACd4pB,EAAY5pB,GACZ9N,EAAO8lB,QAAQhY,IAGnBuG,QAAS,SAASvG,GACd,MAAO9N,GAAOqU,QAAQvG,IACkBtW,SAApCsqB,EAAQwP,cAAcxjB,GAAI7Q,UAK1C5J,GAAG6B,OAAOxB,MACNwZ,SAAU,SAASY,GACf,MAAOgU,GAAQwP,cAAcxjB,GAAI7Q,OAWrC27B,iBAAkB,SAASb,EAAQj1B,GAE/B,GAAI+1B,EAEAjB,GACAU,EAA4BP,EAAQj1B,GAGpC60B,EAAiBI,EAAOjqB,IAAMza,GAAG0kC,GAAQpkC,OAAO,OAAQ,WAMpD,GALA6F,EAAI,yBAA2Bu+B,EAAOjqB,IAKjCiqB,EAAOvjC,WAAZ,CAIA,IAEI,GAAIujC,EAAOe,iBACPf,EAAOe,gBAAgBT,MACkB,SAAzCN,EAAOe,gBAAgBT,KAAKz1B,UAK5B,OAGR,MAAOlF,GAEHlE,EAAI,8EAAgFkE,EAAMjE,QAAU,IAAK,SACzGo/B,GAAsBv5B,SAAS,GAGnCwD,EAAS+1B,OAWrBE,cAAe,SAASjrB,GACpB,GAAIqqB,GAAarW,EAAQmW,eAAenqB,EAExC,OAAOsqB,GAAoBD,IAQ/BO,iBAAkB,SAAS5qB,GACMtW,SAAzBmgC,EAAiB7pB,KACjB6pB,EAAiB7pB,WACV6pB,GAAiB7pB,KAQhCmqB,eAAgB,SAAS1jB,GACrB,MAAOA,GAAS,IAAMokB,GAY1BK,mBAAoB,SAASjqB,GACzB,GAAIkL,GAASlL,EAAKkL,OACdxI,EAAW1C,EAAK0C,SAChBD,EAASzC,EAAKyC,OACdgY,EAAeza,EAAKya,aACpByP,EAAalqB,EAAKkqB,WAClBt0B,EAAOtR,GAAGoP,UAAU,iBAAmBwX,EAAS,2CAChD6T,EAAMrc,CAcV,OAZI+X,GACAn2B,GAAGqR,WAAW8M,EAAQ7M,GAGtBmpB,EAAMz6B,GAAGsQ,QAAQ6N,EAAQC,GAG7B9M,EAAKC,aAAa,SAAUkpB,GAC5BnpB,EAAKC,aAAa,SAAUq0B,GAC5Bt0B,EAAKnR,MAAMC,QAAU,OACrByJ,SAASm7B,KAAKxzB,YAAYF,GAEnBA,GAOX8zB,mBAAoB,SAASS,GACzB,GAAIzU,KAEJ,KACIA,EAAWpxB,GAAGyR,UAAUo0B,GAE5B,MAAOx7B,GACHlE,EAAI,0DAA4DkE,EAAMjE,QAAU,IAAK,SAGzF,MAAOgrB,OCnSnBpxB,GAAG8lC,iBAAmB,SAASpqB,GAC3B,YAkBA,SAASukB,GAAMxlB,GACXza,GAAG+C,KAAK0rB,EAAQqR,SAASrlB,GAAK,SAASsrB,EAAOnyB,GAC1C,GAAIoyB,GAAgBvX,EAAQwX,kBAAkBxrB,EAAIsrB,EAElDnyB,GAAIonB,mBAAqB,KACzBpnB,EAAI1J,OAAOwvB,WAAa,KACxB9lB,EAAIqsB,QACJ+F,GAAiBA,EAActI,UAAYsI,EAActI,SAASjjB,KAvB1E,GAAIgU,GAAUpuB,KACVoqB,EAAY/O,EAAKnD,QAAQkS,UACzBmT,EAAQliB,EAAKkiB,MACbjoB,EAAW+F,EAAKnD,QAAQ5C,SACxBc,EAASiF,EAAKnD,QAAQ9B,OACtByvB,EAAavwB,GAAY+F,EAAKnD,QAAQ5C,SAAS8K,SAAWzgB,GAAGkT,kBAAkByC,SAC/EwwB,EAAgB1vB,GAAUiF,EAAKnD,QAAQ9B,OAAOgK,SAAWylB,GAAclmC,GAAGkT,kBAAkBuD,OAC5FiK,EAAUkd,EAAMld,QAChBkC,EAAUgb,EAAMhb,QAChBO,EAAUya,EAAMza,QAChBf,EAAcwb,EAAMxb,YACpBiK,EAAgBuR,EAAMvR,cACtBH,EAAgB0R,EAAM1R,cACtBrB,EAAa+S,EAAM/S,WACnB1kB,EAAMy3B,EAAMz3B,GAahBnG,IAAG6B,OAAOxB,KAAM,GAAIL,IAAG29B,cAAcjiB,IAErC1b,GAAGwM,SAASnM,KAAM,SAASsM,GACvB,OAIIiE,IAAK,SAAS6J,EAAI2rB,GACd,GAAIpmC,GAAGyI,OAAO29B,IAAgBpmC,GAAGyJ,OAAO28B,GACpCz5B,EAAOiE,IAAI6J,GAAKmF,KAAMwmB,QAErB,CAAA,KAAIA,YAAuBpmC,IAAG8X,WAI/B,KAAM,IAAItW,OAAM,2CAHhBmL,GAAOiE,IAAI6J,GAAKmjB,MAAOwI,IAM3B3X,EAAQ4X,eAAe5rB,GACvB0rB,GAAiB1X,EAAQ6X,uBAAuB7rB,IAGpDgY,QAAS,SAAShY,GACdwlB,EAAMxlB,GACNgU,EAAQ0Q,+BAA+B1kB,GACvCgU,EAAQ8T,WAAW9nB,GACnB9N,EAAO8lB,QAAQhY,OAK3Bza,GAAG6B,OAAOxB,MAENi/B,iBAAkB,SAAS7kB,EAAIikB,SACpBjQ,GAAQwP,cAAcxjB,GAAIjK,KAAK+1B,aAAa7H,IAGvDuC,SAAU,SAASxmB,EAAIikB,GACnB,GAAI8H,GAAY/X,EAAQwP,cAAcxjB,GAAIjK,IAEtCg2B,GAAUC,YACHD,GAAUC,KAAK/H,GAEtB8H,EAAUE,sBACHF,GAAUE,eAAehI,IAMxCM,eAAgB,SAASvkB,EAAIksB,GACzB,GAAIC,GAAenY,EAAQgS,gBAAgBhmB,GAAM,EAC7C7G,EAAM6a,EAAQoY,QAAQpsB,EAAImsB,EAE9B,OAAID,IACO,GAAI3mC,IAAG+L,SAAUE,QAAQ06B,EAAe/yB,GAAMA,IAGlD,GAAI5T,IAAG+L,SAAUE,WAAY2H,IAGxCgO,QAAS,SAASnH,GACd,MAAOgU,GAAQzN,QAAQvG,IAAOgU,EAAQwP,cAAcxjB,GAAImF,MAG5D4iB,SAAU,SAAS/nB,GACf,MAAOgU,GAAQzN,QAAQvG,IAAOgU,EAAQwP,cAAcxjB,GAAImjB,OAO5Djb,sBAAuB,WACnB,GAAImkB,KAmBJ,OAjBArY,GAAQsY,sBAAsB,SAASl3B,EAAK0Q,GACxCkO,EAAQ0R,0BAA0B,KAAM5f,EAAW5K,SAAS8pB,WAAalf,EAAW5K,SAAS+pB,UAE7F,IAAI16B,IACAjD,KAAMwe,EAAWxe,KACjB29B,UAAWnf,EAAW5K,SAAS+pB,UAC/B7jB,KAAM0E,EAAW1E,KACjBjB,KAAM2F,EAAW3F,KAGjB2F,GAAW1Q,MACX7K,EAAK6K,IAAM0Q,EAAW1Q,KAG1Bi3B,EAAmB5jC,KAAK8B,KAGrB8hC,GAGXjD,YAAa,SAASppB,GAClB,QAAS9E,GAAY8Y,EAAQzN,QAAQvG,KAAQgU,EAAQwP,cAAcxjB,GAAIusB,cAG3E7G,0BAA2B,SAAS1lB,EAAIwsB,EAAeC,GACnD,GAAIzH,GAAawH,GAAiBxY,EAAQwP,cAAcxjB,GAAI9E,SAAS8pB,WACjEC,EAAYwH,GAAgBzY,EAAQwP,cAAcxjB,GAAI9E,SAAS+pB,SAE/DD,KACAt5B,EAAInG,GAAG8H,OAAO,yDAA0D6J,KAAK6pB,UAAUiE,KACvFA,EAAW0H,UACXnnC,GAAG+C,KAAK08B,EAAY,SAASz8B,EAAK07B,GAC9BgB,EAAUC,QAAQjB,KAEtBe,EAAW15B,OAAS,IAI5BwQ,MAAO,SAASkE,GACZ,GAAIgU,EAAQzN,QAAQvG,GAIhB,MAHAtU,GAAInG,GAAG8H,OAAO,4DAA6D2S,EAAIiG,EAAQjG,KACvFgU,EAAQwP,cAAcxjB,GAAI2sB,QAAS,EACnCnH,EAAMxlB,IACC,GAIfimB,mBAAoB,SAASjmB,GACzB,GAAI9E,GAAY8Y,EAAQzN,QAAQvG,GAAK,CACjC,GACI4sB,GACAv2B,EAFA4G,EAAQ+W,EAAQwP,cAAcxjB,EAQlC,UAJO/C,GAAM/B,SAEb+B,EAAM/B,YACN0xB,EAAc5Y,EAAQgS,gBAAgBhmB,GAClC4sB,EAAc,GAAK1xB,EAAS6hB,UAAW,CAKvC,IAJA9f,EAAM/B,SAAS8K,SAAU,EACzB/I,EAAM/B,SAAS2xB,MAAQD,EACvB3vB,EAAM/B,SAAS+pB,aAEV5uB,EAAI,EAAGA,EAAIu2B,EAAav2B,IACzB4G,EAAM/B,SAAS+pB,UAAUx8B,KAAK4N,EAGlC2d,GAAQ4X,eAAe5rB,OAGvB/C,GAAM/B,SAAS8K,SAAU,IAKrCwiB,WAAY,SAASxoB,EAAI8sB,GACjB9Y,EAAQzN,QAAQvG,KAChBgU,EAAQwP,cAAcxjB,GAAImF,KAAO2nB,IAIzChF,WAAY,SAAS9nB,GACjB,GAAI+rB,GAAY/X,EAAQwP,cAAcxjB,GAAIjK,IAE1CxQ,IAAG+C,KAAKyjC,EAAUE,eAAgB,SAASc,SAChChB,GAAUE,eAAec,KAGpCxnC,GAAG+C,KAAKyjC,EAAUC,KAAM,SAASe,SACtBhB,GAAUC,KAAKe,MAW9BC,WAAY,SAAShtB,EAAIitB,GACrB,MAAOjZ,GAAQkZ,aAAaltB,EAAIitB,EAAa1nC,GAAGiK,sBAGpDg8B,kBAAmB,SAASxrB,EAAIitB,GAC5B,GAAIhJ,GAA0B,MAAfgJ,GAAsB,EAAKA,CAC1C,OAAOjZ,GAAQwP,cAAcxjB,GAAIjK,KAAKk2B,eAAehI,IAGzDC,cAAe,SAASlkB,EAAImtB,GACxB,GAAIhQ,GAAYjiB,EAASoiB,SACrB8P,EAAWjlB,EAAQnI,GACnB1P,EAAa0jB,EAAQ7M,QAAQnH,GAC7BqtB,EAAalQ,EAAYgQ,EACzBG,EAAWD,EAAalQ,GAAaiQ,EAAWA,EAAWC,EAAalQ,EACxEyP,EAAc5Y,EAAQgS,gBAAgBhmB,GACtC8rB,EAAelmC,KAAK49B,cAAcxjB,GAAIjK,KAAK+1B,aAI3C96B,EAAO86B,EAAaqB,IAAe5nC,GAAG8K,UAAUC,EAAY+8B,EAAYC,EAI5E,OAFAxB,GAAaqB,GAAcn8B,GAGvBu8B,KAAMJ,EACN58B,MAAO88B,EACP78B,IAAK88B,EACLE,MAAOZ,EACP57B,KAAMA,EACNoQ,KAAMksB,EAAWD,IAIzBhJ,yBAA0B,SAASnT,GAC/B,OACI+L,UAAW/L,EAAUqc,KACrBE,UAAWvc,EAAU3gB,MAAQ,EAC7Bm9B,QAASxc,EAAU1gB,IACnB6sB,WAAYnM,EAAUsc,QAQ9BG,mBAAoB,SAAS3tB,GACzB,GAAI4tB,GAAgB,MAChBtmC,EAAO2e,EAAQjG,GACfoB,EAAO+G,EAAQnI,GACfmd,EAAYjiB,EAASoiB,SACrB3Z,EAAWgE,EAAY3H,EAE3B,OAAOza,IAAG8H,OAAO,2BAA4B2iB,EAAW4d,EAAetmC,EAAM8Z,EAAM+b,EAAWxZ,IAGlGkqB,aAAc,SAAS7tB,GACnB,MAAOgU,GAAQ7M,QAAQnH,GAAIla,MAG/BgoC,oBAAqB,SAAS9tB,GAC1B,MAAOgU,GAAQwP,cAAcxjB,GAAI9E,UAOrC8qB,gBAAiB,SAAShmB,GACtB,GAAI9E,EAAU,CACV,GAAIkyB,GAAWjlB,EAAQnI,GACnBmd,EAAYjiB,EAASoiB,QAEzB,OAAOp2B,MAAK6mC,KAAKX,EAAWjQ,KAIpCiP,QAAS,SAASpsB,EAAIitB,GAClB,GAAIhJ,GAA0B,MAAfgJ,GAAsB,EAAKA,CAC1C,OAAOjZ,GAAQwP,cAAcxjB,GAAIjK,KAAKi2B,KAAK/H,IAG/CoB,SAAU,SAASrlB,GACf,MAAOgU,GAAQwP,cAAcxjB,GAAIjK,KAAKi2B,MAK1CM,sBAAuB,SAASt3B,GACxB02B,GACAnmC,GAAG+C,KAAKqR,aAAc,SAASvE,EAAKvI,GAChC,GAAwD,IAApDuI,EAAIlK,QAAQ3F,GAAG8H,OAAO,aAAc2iB,IAAmB,CACvD,GAAIlK,GAAa5O,KAAKC,MAAMtK,EAC5BmI,GAASI,EAAK0Q,OAM9B8lB,eAAgB,SAAS5rB,GACrBgU,EAAQwP,cAAcxjB,GAAIjK,MACtBk2B,kBACA7H,iBACA4H,QACAF,kBAIRkC,kBAAmB,SAAShuB,GACxBgU,EAAQwP,cAAcxjB,GAAIusB,cAAe,GAK7C7H,+BAAgC,SAAS1kB,GACrC,GAAIiuB,EAEJ,UAAIvC,GAAiB1X,EAAQoV,YAAYppB,KACrCiuB,EAAiBja,EAAQ2Z,mBAAmB3tB,GAExCiuB,GAAkBt0B,aAAatE,QAAQ44B,OACvCt0B,aAAau0B,WAAWD,IACjB,IASnBpC,uBAAwB,SAAS7rB,GAC7B,GACIiuB,GAAgBE,EADhBlxB,EAAQ+W,EAAQwP,cAAcxjB,EAK9B0rB,IAA+BhiC,SAAduT,EAAM7H,MACvB64B,EAAiBja,EAAQ2Z,mBAAmB3tB,GAC5CmuB,EAAgBx0B,aAAatE,QAAQ44B,GAGjCE,IACAA,EAAgBj3B,KAAKC,MAAMg3B,GAIvBvc,EAAcuc,EAAchuB,MAC5B6T,EAAQga,kBAAkBhuB,IAG1BtU,EAAInG,GAAG8H,OAAO,0DAA2D2S,EAAIiG,EAAQjG,KAErFyR,EAAczR,EAAImuB,EAAchuB,MAEhClD,EAAM7H,IAAM+4B,EAAc/4B,IAC1B6H,EAAM/B,SAAWizB,EAAcjzB,SAC/B+B,EAAMoT,OAAS8d,EAAc9d,OAC7BpT,EAAMknB,kBAAmB,EAEzBnQ,EAAQ0R,0BAA0B1lB,OAOlDumB,0BAA2B,SAASvmB,GAChC,GACIiuB,GAAgBE,EADhBlxB,EAAQ+W,EAAQwP,cAAcxjB,EAIlC,IAAI0rB,GAAiB1X,EAAQoV,YAAYppB,GAAK,CAC1CiuB,EAAiBja,EAAQ2Z,mBAAmB3tB,GAE5CmuB,GACI7mC,KAAM2e,EAAQjG,GACdoB,KAAM+G,EAAQnI,GACdG,KAAMuI,EAAQ1I,GACd5K,IAAK6H,EAAM7H,IACX8F,SAAU+B,EAAM/B,SAChBmV,OAAQpT,EAAMoT,OACd+d,YAAarL,KAAK+F,MAGtB,KACInvB,aAAaC,QAAQq0B,EAAgB/2B,KAAK6pB,UAAUoN,IAExD,MAAOv+B,GACHlE,EAAInG,GAAG8H,OAAO,0DAA2D2S,EAAIpQ,EAAM1D,YAAa,WAK5GmiC,yBAA0B,SAASruB,EAAIikB,EAAU9G,GAC7C,GAAIhkB,GAAM6a,EAAQoY,QAAQpsB,EAAIikB,GAC1B38B,EAAO2e,EAAQjG,GACfsuB,GACI3G,OAAQ,SAAStX,EAAQC,GACrB,GAAI8c,GAAWjlB,EAAQnI,EAEnBqQ,KAAWC,EACXF,EAAWpQ,EAAI1Y,EAAM8lC,EAAUA,GAG/Bhd,EAAWpQ,EAAI1Y,EAAO+oB,GAAU+c,EAAWA,EAAW,EAAI/c,EAAS+c,IAI3EpJ,QAAS,SAAS3T,EAAQC,GACtB,GAAI8T,GAAgBpQ,EAAQwP,cAAcxjB,GAAIjK,KAAKquB,cAC/CmK,EAAiCva,EAAQwP,cAAcxjB,GAAIqQ,OAC3Dme,EAAmBne,EACnBoe,EAAkBne,EAClB8M,EAAgBjV,EAAQnI,GACxB0uB,EAAuBF,GAAoBC,EAAkBtR,GAC7DwR,EAAqBJ,CAEzBnK,GAAcH,GAAYyK,EAE1BnpC,GAAG+C,KAAK87B,EAAe,SAASH,EAAU2K,GACtCD,GAAsBC,IAG1Bxe,EAAWpQ,EAAI1Y,EAAMqnC,EAAoBvR,IAIrDjkB,GAAI1J,OAAOwvB,WAAa,SAASxqB,GAC7B,GAAIA,EAAEysB,iBAAkB,CAEpB,GAAIp7B,GAAoB,MAAbq3B,EAAoB,SAAW,SAC1CmR,GAAmBxoC,GAAM2O,EAAE4b,OAAQ5b,EAAE6b,UAcjD4c,aAAc,SAASltB,EAAIitB,EAAa9zB,EAAK01B,GACzC,GAAIC,GAAwB,MAAf7B,GAAsB,EAAKA,EACpClB,EAAY/X,EAAQwP,cAAcxjB,GAAIjK,IAW1C,OATAg2B,GAAUC,KAAOD,EAAUC,SAC3BD,EAAUE,eAAiBF,EAAUE,mBAErCF,EAAUC,KAAK8C,GAAU31B,EAErB01B,IACA9C,EAAUE,eAAe6C,GAAUD,GAGhC11B,GAIXivB,8BAA+B,WAC3B,GAAI2G,GAAiB/yB,EAAOuhB,eAE5BvJ,GAAQsY,sBAAsB,SAASl3B,EAAK0Q,GACxC,GAAIkpB,GAAiB,GAAIjM,MAAKjd,EAAWsoB,YAGzCY,GAAeC,QAAQD,EAAeE,UAAYH,GAE9CC,EAAehM,WAAaD,KAAK+F,QACjCp9B,EAAI,2CAA6C0J,GACjDuE,aAAau0B,WAAW94B,OAWpC4zB,qBAAsB,SAAShpB,GAC3B,GAAI/C,GAAQ+W,EAAQwP,cAAcxjB,EAMlC,OAJK/C,GAAM/B,UACP8Y,EAAQiS,mBAAmBjmB,GAGxB/C,EAAM/B,SAAS8K,YCxflCzgB,GAAG2mB,wBAA0B,SAASxO,GAClC,YAqBA,SAASyxB,KACL,MAAqC,SAAjCrxB,EAAQqO,OAAOC,eAEXgjB,QAAS,aAtBrB,GAAIC,GACAvxB,GACIqO,OAAQ,SACRG,cAAe,SACfK,iBACAN,eAAgB,EAChBI,cAAe,SAASzM,GAAK,UAC7B0M,eACAE,MACIqI,UAAU,EACVyI,iBAAiB,GAErBhyB,IAAK,SAAS4B,EAAK1B,KACnBihB,SAAU,SAAS7M,KACnB+M,iBAAkB,SAAS/M,EAAIgN,EAAUC,KAGjD1nB,IAAG6B,OAAO0W,EAASJ,GAYnB2xB,EAAY9pC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGk5B,eAC/B6C,aAAc,mBACdM,cAAe,OAAQ,UACvBzV,OAAQrO,EAAQqO,OAChBQ,cAAe7O,EAAQ6O,cACvBD,YAAa5O,EAAQ4O,YACrBoT,eAAgBqP,IAChB9iB,eAAgBvO,EAAQuO,eACxBI,cAAe,SAASzM,GACpB,MAAOlC,GAAQ2O,cAAc5E,IAAI7H,IAErCtU,IAAKoS,EAAQpS,IACbw0B,OAAQpiB,EAAQ+O,SAChB2D,WAAY1S,EAAQiP,iBACpBH,KAAM9O,EAAQ8O,QAGlBrnB,GAAG6B,OAAOxB,MACNizB,WAAY,SAAS7Y,EAAIG,EAAMsY,GAC3B,GAAI1I,GAAoB0I,KAExB3a,GAAQpS,IAAI,sCAAwCsU,GAE7B,WAAnBlC,EAAQqO,OACRkjB,EAAUnN,cAAcliB,GACnBqiB,SAASliB,GACToiB,WAAWxS,GACX6Q,QAGL7Q,EAAkBjS,EAAQwO,eAAiBnM,EAC3CkvB,EAAUnN,cAAcliB,GACnBuiB,WAAWxS,GACX6Q,YCpDrB,WAMI,QAAS0O,GAAkBC,GACvB,GAGIC,GAHAC,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACThmC,EAASwF,SAASC,cAAc,SAGpC,OAAIogC,GAAKE,EAAK,UACV/lC,EAAOimC,MAAQjmC,EAAOgV,OAAS,EAC/B4wB,EAAM5lC,EAAOkmC,WAAW,MACxBN,EAAIO,UAAUR,GAAME,EAAK,EAAG,GAIoB,IAAzCD,EAAIQ,aAAa,EAAG,EAAG,EAAG,GAAGzlC,KAAK,IAUjD,QAAS0lC,GAAqBV,EAAKE,EAAIE,GACnC,GAIIH,GAAKjlC,EAAM2lC,EAAOC,EAJlBvmC,EAASwF,SAASC,cAAc,UAChC+gC,EAAK,EACLC,EAAKV,EACLW,EAAKX,CAUT,KAPA/lC,EAAOimC,MAAQ,EACfjmC,EAAOgV,OAAS+wB,EAChBH,EAAM5lC,EAAOkmC,WAAW,MACxBN,EAAIO,UAAUR,EAAK,EAAG,GACtBhlC,EAAOilC,EAAIQ,aAAa,EAAG,EAAG,EAAGL,GAAIplC,KAG9B+lC,EAAKF,GACRF,EAAQ3lC,EAAgB,GAAV+lC,EAAK,GAAS,GACd,IAAVJ,EACAG,EAAKC,EAELF,EAAKE,EAETA,EAAMD,EAAKD,GAAO,CAItB,OADAD,GAASG,EAAKX,EACI,IAAVQ,EAAe,EAAIA,EAM/B,QAASI,GAAqBhB,EAAKv+B,EAAM8M,EAAS0yB,GAC9C,GAAI5mC,GAASwF,SAASC,cAAc,UAChCxF,EAAOiU,EAAQjU,MAAQ,aACvBwH,EAAU,GAAI9L,IAAG+L,OASrB,OAPAm/B,GAAoBlB,EAAKv+B,EAAMpH,EAAQkU,EAAS0yB,GAC3C7zB,KAAK,WACFtL,EAAQG,QACJ5H,EAAOI,UAAUH,EAAMiU,EAAQhU,SAAW,OAI/CuH,EAGX,QAASq/B,GAAoCzvB,GACzC,GAAI0vB,GAAY,MAEhB,KAAKprC,GAAG0O,MACJ,KAAM,IAAI1O,IAAGwB,MAAM,kEAGvB,IAAIka,EAAK2vB,WAAa3vB,EAAK4vB,UAAYF,EACnC,OACIG,UAAW5pC,KAAKC,MAAMD,KAAK6pC,KAAKJ,GAAa1vB,EAAK2vB,WAAa3vB,EAAK4vB,aACpEG,SAAU9pC,KAAKC,MAAMD,KAAK6pC,KAAKJ,GAAa1vB,EAAK4vB,UAAY5vB,EAAK2vB,eAQ9E,QAASH,GAAoBlB,EAAKv+B,EAAMpH,EAAQkU,EAAS0yB,GACrD,GAMIS,GANAxB,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTC,EAAQ/xB,EAAQ+xB,MAChBjxB,EAASd,EAAQc,OACjB4wB,EAAM5lC,EAAOkmC,WAAW,MACxBz+B,EAAU,GAAI9L,IAAG+L,OAKrB,OAFAk+B,GAAI0B,OAEApzB,EAAQqzB,OACDC,GACHpgC,KAAMA,EACNpH,OAAQA,EACRkxB,MAAOyU,EACP8B,YAAa1B,EACb2B,WAAY7B,EACZ8B,YAAazzB,EAAQyzB,YACrBJ,OAAQrzB,EAAQqzB,OAChBK,aAAc5yB,EACd6yB,YAAa5B,KAIhBtqC,GAAGkT,kBAAkB0D,2BACtB80B,EAAqBP,GACjBG,UAAWhB,EACXe,WAAYhyB,IAGZqyB,IACA1rC,GAAGmG,IAAInG,GAAG8H,OAAO,iFACbwiC,EAAOjxB,EAAQqyB,EAAmBD,SAAUC,EAAmBH,WAC/D,QAEJjB,EAAQoB,EAAmBD,SAC3BpyB,EAASqyB,EAAmBH,YAIpCY,EAAoB9nC,EAAQimC,EAAOjxB,EAAQd,EAAQyzB,aAI/ChsC,GAAG0O,OACF,WACOq7B,EAAkBC,KAClBE,GAAM,EACNE,GAAM,EAGV,IAOIgC,GAAQC,EAAIC,EAPZC,EAAI,KACJC,EAAY3iC,SAASC,cAAc,UACnC2iC,EAAkBxB,EAAWP,EAAqBV,EAAKE,EAAIE,GAAM,EACjEsC,EAAK/qC,KAAK6mC,KAAK+D,EAAIjC,EAAQJ,GAC3ByC,EAAKhrC,KAAK6mC,KAAK+D,EAAIlzB,EAAS+wB,EAAKqC,GACjC5B,EAAK,EACL+B,EAAK,CAMT,KAHAJ,EAAUlC,MAAQkC,EAAUnzB,OAASkzB,EACrCH,EAASI,EAAUjC,WAAW,MAEvBM,EAAKT,GAAI,CAGZ,IAFAiC,EAAK,EACLC,EAAK,EACED,EAAKnC,GACRkC,EAAOS,UAAU,EAAG,EAAGN,EAAGA,GAC1BH,EAAO5B,UAAUR,GAAMqC,GAAKxB,GAC5BZ,EAAIO,UAAUgC,EAAW,EAAG,EAAGD,EAAGA,EAAGD,EAAIM,EAAIF,EAAIC,GACjDN,GAAME,EACND,GAAMI,CAEV7B,IAAM0B,EACNK,GAAMD,EAEV1C,EAAI6C,UACJN,EAAYJ,EAAS,QAIzBnC,EAAIO,UAAUR,EAAK,EAAG,EAAGM,EAAOjxB,GAGpChV,EAAO0oC,iBAAmB1oC,EAAO0oC,kBACjCjhC,EAAQG,UAEDH,GAGX,QAAS+/B,GAAqCmB,GAC1C,GAAIvhC,GAAOuhC,EAAWvhC,KAClB8pB,EAAQyX,EAAWzX,MACnBuW,EAAckB,EAAWlB,YACzBC,EAAaiB,EAAWjB,WACxBC,EAAcgB,EAAWhB,YACzBlgC,EAAU,GAAI9L,IAAG+L,QACjB6/B,EAASoB,EAAWpB,OACpBqB,EAAepjC,SAASC,cAAc,UACtCojC,EAAsBD,EAAa1C,WAAW,MAC9C4C,EAAeH,EAAW3oC,OAC1B4nC,EAAee,EAAWf,aAC1BC,EAAcc,EAAWd,WAyB7B,OAvBAC,GAAoBc,EAAclB,EAAYD,EAAaE,GAE3DmB,EAAa9zB,OAAS4yB,EACtBkB,EAAa7C,MAAQ4B,EAErBgB,EAAoB1C,UAAUjV,EAAO,EAAG,GAExCqW,GACIngC,KAAMA,EACN4N,OAAQ4yB,EACR1W,MAAOA,EACP0X,aAAcA,EACdE,aAAcA,EACd7C,MAAO4B,IAEN90B,KACG,WACI+1B,EAAaJ,iBAAmBI,EAAaJ,kBAC7CjhC,EAAQG,WAEZH,EAAQK,SAGTL,EAOX,QAASqgC,GAAoB9nC,EAAQimC,EAAOjxB,EAAQ2yB,GAChD,OAAQA,GACJ,IAAK,GACL,IAAK,GACL,IAAK,GACL,IAAK,GACD3nC,EAAOimC,MAAQjxB,EACfhV,EAAOgV,OAASixB,CAChB,MACJ,SACIjmC,EAAOimC,MAAQA,EACfjmC,EAAOgV,OAASA,EAExB,GAAI4wB,GAAM5lC,EAAOkmC,WAAW,KAC5B,QAAQyB,GACJ,IAAK,GAED/B,EAAImD,UAAU9C,EAAO,GACrBL,EAAItoB,OAAM,EAAI,EACd,MACJ,KAAK,GAEDsoB,EAAImD,UAAU9C,EAAOjxB,GACrB4wB,EAAIoD,OAAO1rC,KAAK2rC,GAChB,MACJ,KAAK,GAEDrD,EAAImD,UAAU,EAAG/zB,GACjB4wB,EAAItoB,MAAM,GAAG,EACb,MACJ,KAAK,GAEDsoB,EAAIoD,OAAO,GAAM1rC,KAAK2rC,IACtBrD,EAAItoB,MAAM,GAAG,EACb,MACJ,KAAK,GAEDsoB,EAAIoD,OAAO,GAAM1rC,KAAK2rC,IACtBrD,EAAImD,UAAU,GAAI/zB,EAClB,MACJ,KAAK,GAED4wB,EAAIoD,OAAO,GAAM1rC,KAAK2rC,IACtBrD,EAAImD,UAAU9C,GAAQjxB,GACtB4wB,EAAItoB,OAAM,EAAI,EACd,MACJ,KAAK,GAEDsoB,EAAIoD,QAAO,GAAO1rC,KAAK2rC,IACvBrD,EAAImD,WAAW9C,EAAO,IAUlC,QAASiD,GAAaC,EAAUC,GAC5B,GAAIh1B,GAAOpY,IAEP6E,QAAOO,MAAQ+nC,YAAoB/nC,QAClC,WACG,GAAIukC,GAAM,GAAI0D,OACVC,EAAMzoC,OAAOyoC,KAAOzoC,OAAOyoC,IAAIC,gBAAkB1oC,OAAOyoC,IACpDzoC,OAAO2oC,WAAa3oC,OAAO2oC,UAAUD,gBAAkB1oC,OAAO2oC,UAAY,IAClF,KAAKF,EAAO,KAAMnsC,OAAM,uDACxBwoC,GAAI8D,IAAMH,EAAIC,gBAAgBJ,GAC9B/0B,EAAKhN,KAAO+hC,EACZA,EAAWxD,KAGdwD,EAASrD,cAAiBqD,EAASnD,gBACpCmD,EAASxhC,OAAS,WACd,GAAI+hC,GAAYt1B,EAAKu1B,kBACjBD,KACAt1B,EAAKu1B,mBAAqB,KAG1B1kB,WAAW,WACP,IAAK,GAAIxY,GAAI,EAAG5D,EAAM6gC,EAAUhoC,OAAQ+K,EAAI5D,EAAK4D,IAC7Ci9B,EAAUj9B,MAEf,KAGX08B,EAASthC,QAAUuhC,EACnBptC,KAAK2tC,uBAET3tC,KAAKmtC,SAAWA,EAMpBD,EAAa7mC,UAAUunC,OAAS,SAASxhC,EAAQ8L,GAC7CA,EAAUA,KAEV,IASI21B,GATAz1B,EAAOpY,KACP8tC,EAAW9tC,KAAKmtC,SAASrD,aACzBiE,EAAY/tC,KAAKmtC,SAASnD,cAC1BC,EAAQ/xB,EAAQ+xB,MAChBjxB,EAASd,EAAQc,OACjBid,EAAW/d,EAAQ+d,SACnBD,EAAY9d,EAAQ8d,UACpB4U,GAAY5qC,KAAKoL,MAA2B,eAAnBpL,KAAKoL,KAAKlL,KACnCiJ,EAAUiD,EAAOjD,QAAQF,aAG7B,OAAIjJ,MAAK2tC,uBACL3tC,MAAK2tC,mBAAmB9qC,KAAK,WAAauV,EAAKw1B,OAAOxhC,EAAQ8L,MAI9D+xB,IAAUjxB,EACVA,EAAU+0B,EAAY9D,EAAQ6D,GAAa,EACpC90B,IAAWixB,EAClBA,EAAS6D,EAAW90B,EAAS+0B,GAAc,GAE3C9D,EAAQ6D,EACR90B,EAAS+0B,GAET9X,GAAYgU,EAAQhU,IACpBgU,EAAQhU,EACRjd,EAAU+0B,EAAY9D,EAAQ6D,GAAa,GAE3C9X,GAAahd,EAASgd,IACtBhd,EAASgd,EACTiU,EAAS6D,EAAW90B,EAAS+0B,GAAc,GAG/CF,GAAQ5D,MAAOA,EAAOjxB,OAAQA,GAC9BrZ,GAAG+C,KAAKwV,EAAS,SAAS81B,EAAYC,GAClCJ,EAAIG,GAAcC,IAGN,QAAZ9kC,GACC,WACG,GAAI+kC,GAAe9hC,EAAOqhC,GAC1B9C,GAAqBvyB,EAAK+0B,SAAU/0B,EAAKhN,KAAMyiC,EAAKjD,GAC/C7zB,KAAK,SAAS1S,GACX+H,EAAOqhC,IAAMppC,EACb6pC,IAAiB9hC,EAAOqhC,KAAOrhC,EAAOT,cAG/B,WAAZxC,GACP0hC,EAAoB7qC,KAAKmtC,SAAUntC,KAAKoL,KAAMgB,EAAQyhC,EAAKjD,QAElC,kBAAlB5qC,MAAKmuC,UACZnuC,KAAKmuC,SAAS/hC,MAItBzM,GAAGutC,aAAeA,KCtYtBvtC,GAAG64B,eAAiB,SAAS1yB,GACzB,YAEA,SAASsoC,GAAMC,GACX,MAAoC,QAA7BA,EAAGllC,QAAQF,cAGtB,QAASqlC,GAASD,GACd,MAAoC,WAA7BA,EAAGllC,QAAQF,cAGtB,QAASslC,KACL,MAAmCzqC,WAA5B,GAAIupC,QAAQmB,YAGvB,QAASC,KACL,GAAIzqC,GAASwF,SAASC,cAAc,SAEpC,OAAOzF,GAAOkmC,YAAclmC,EAAOkmC,WAAW,MAMlD,QAASwE,GAAwBC,GAE7B,GAAIC,GAAeD,EAAatpC,MAAM,KAClC3D,EAAOktC,EAAaA,EAAalpC,OAAS,GAAGL,MAAM,KAAK,GACxDspB,EAAYhvB,GAAG8R,aAAa/P,EAIhC,QAFAitB,EAAYA,GAAaA,EAAU1lB,eAG/B,IAAK,OACL,IAAK,MACD,MAAO,YACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,OACL,IAAK,MACD,MAAO,cASnB,QAAS4lC,GAAczU,GACnB,GACI0U,GAAgBC,EAAgBC,EADhCC,EAAezlC,SAASC,cAAc,IAS1C,OANAwlC,GAAaC,KAAO9U,EAEpB0U,EAAiBG,EAAaE,SAC9BH,EAAaC,EAAaG,KAC1BL,EAAiBE,EAAaI,SAE1BP,EAAe7lC,gBAAkBpE,OAAOyqC,SAASH,SAASlmC,gBAI1D8lC,EAAe9lC,gBAAkBpE,OAAOyqC,SAASD,SAASpmC,eAK1D+lC,IAAenqC,OAAOyqC,SAASF,OAASzvC,GAAGyN,MAOnD,QAASmiC,GAAyB5F,EAAKl+B,GACnCk+B,EAAIh+B,OAAS,WACTg+B,EAAIh+B,OAAS,KACbg+B,EAAI99B,QAAU,KACdJ,EAAQG,QAAQ+9B,IAGpBA,EAAI99B,QAAU,WACV89B,EAAIh+B,OAAS,KACbg+B,EAAI99B,QAAU,KACd/F,EAAI,6BAA8B,SAClC2F,EAAQK,QAAQ69B,EAAK,+BAI7B,QAAS6F,GAAgCxrC,EAAQyH,GAO7CzH,EAAO0oC,gBAAkB,WACrBjhC,EAAQG,QAAQ5H,IAQxB,QAASyrC,GAAkC3uB,EAAarV,GACpD,GAAIikC,GAAatB,EAAMttB,IAAgBwtB,EAASxtB,EAahD,OAXIstB,GAAMttB,GACNyuB,EAAyBzuB,EAAarV,GAEjC6iC,EAASxtB,GACd0uB,EAAgC1uB,EAAarV,IAG7CA,EAAQK,QAAQgV,GAChBhb,EAAInG,GAAG8H,OAAO,iDAAkDqZ,EAAY3X,SAAU,UAGnFumC,EAKX,QAASC,GAAKjlC,EAAY8W,EAAWtJ,GACjC,GAAI03B,GAAc,GAAIjwC,IAAG+L,QACrBqc,EAAa,GAAIpoB,IAAGkwC,SAASnlC,EAAY5E,GACzCib,EAAU7I,EAAQ6I,QAElBmX,EAA2B,MAAlBhgB,EAAQggB,QAAwBhgB,EAAQggB,OACjD4X,EAAsB,WAClBtuB,EAAU3V,QAAU,KACpB2V,EAAU7V,OAAS,KACnB7F,EAAI,mDAAoD,SACxD8pC,EAAY9jC,QAAQ0V,EAAW,gCAiDvC,OA9CAuG,GAAWgoB,gBAAgBh5B,KACvB,SAAS9S,GAGL,GAAI+rC,IACIz+B,MAAO,WACH,OAAO,GAAI5R,IAAG+L,SAAUE,YAGhCqkC,EAAO/X,EAAS,GAAIv4B,IAAGuwC,KAAKxlC,EAAY5E,GAAOkqC,EAC/CG,EAAQ,GAAIxwC,IAAGutC,aAAaxiC,EAAYolC,EAExCL,GAAkCjuB,EAAWouB,IAC7CK,EAAK1+B,QAAQwF,KACT,SAASk5B,GACL,GAAItE,GAAcsE,GAAQA,EAAKG,WAE/BD,GAAMvC,OAAOpsB,GACTyU,SAAUlV,EACViV,UAAWjV,EACX4qB,YAAaA,EACb1nC,KAAMA,EACNsnC,OAAQrzB,EAAQ+I,wBAIxB,SAASovB,GACLvqC,EAAInG,GAAG8H,OAAO,iEAAkE4oC,IAEhFF,EAAMvC,OAAOpsB,GACTyU,SAAUlV,EACViV,UAAWjV,EACX9c,KAAMA,EACNsnC,OAAQrzB,EAAQ+I,0BAOpC,WACInb,EAAI,mBACJ8pC,EAAY9jC,QAAQ0V,EAAW,qBAIhCouB,EAGX,QAASU,GAAyBlW,EAAKmW,EAAaZ,EAAM5uB,EAASE,GAC/D,GAAIuvB,GAAU,GAAInD,OACdoD,EAAgB,GAAI9wC,IAAG+L,OAE3B+jC,GAAkCe,EAASC,GAEvC5B,EAAczU,KACdoW,EAAQhC,YAAc,aAG1BgC,EAAQ/C,IAAMrT,EAEdqW,EAAc15B,KACV,WACI04B,EAAkCc,EAAaZ,EAE/C,IAAIQ,GAAQ,GAAIxwC,IAAGutC,aAAasD,EAChCL,GAAMvC,OAAO2C,GACTta,SAAUlV,EACViV,UAAWjV,EACX9c,KAAMyqC,EAAwBtU,GAC9BmR,OAAQtqB,KAIhB0uB,EAAK7jC,SAIb,QAAS4kC,GAA+BtW,EAAKuP,EAAKgG,EAAM5uB,GACpD0uB,EAAkC9F,EAAKgG,GAKvChwC,GAAGgqC,GAAK1oC,KACJg1B,SAAUlV,EAAU,KACpBiV,UAAWjV,EAAU,OAGzB4oB,EAAI8D,IAAMrT,EAWd,QAASuW,GAAYvW,EAAK5Y,EAAWtJ,GACjC,GAAIy3B,GAAO,GAAIhwC,IAAG+L,QACd4V,EAAQpJ,EAAQoJ,MAChBP,EAAUO,EAAQpJ,EAAQ6I,QAAU,IA8BxC,OA3BIO,IAAS8sB,EAAM5sB,GAGXitB,IAIII,EAAczU,KAASmU,IACvBmC,EAA+BtW,EAAK5Y,EAAWmuB,EAAM5uB,GAGrDuvB,EAAyBlW,EAAK5Y,EAAWmuB,EAAM5uB,GAInD2vB,EAA+BtW,EAAK5Y,EAAWmuB,EAAM5uB,GAIpDutB,EAAS9sB,GACd8uB,EAAyBlW,EAAK5Y,EAAWmuB,EAAM5uB,GAG1C0uB,EAAkCjuB,EAAWmuB,KAClDnuB,EAAUisB,IAAMrT,GAGbuV,EAGXhwC,GAAG6B,OAAOxB,MAWNyhB,SAAU,SAASmvB,EAAepvB,EAAWtJ,GACzC,MAAIvY,IAAGwH,SAASypC,IACZ9qC,EAAI,4DACG6qC,EAAYC,EAAepvB,EAAWtJ,SAG7CpS,EAAI,iDACG6pC,EAAKiB,EAAepvB,EAAWtJ,WAMlDlY,KAAK6wC,YACL7wC,KAAK6wC,SAASzC,MAAQA,EACtBpuC,KAAK6wC,SAASvC,SAAWA,EACzBtuC,KAAK6wC,SAAShC,cAAgBA,EAC9B7uC,KAAK6wC,SAASnC,wBAA0BA,GChT5C/uC,GAAGuwC,KAAO,SAASxlC,EAAY5E,GAC3B,YAYA,SAASgrC,GAAkBC,GAIvB,IAHA,GAAIzuC,GAAS,EACT0uC,EAAM,EAEHD,EAAIrrC,OAAS,GAChBpD,GAAUq/B,SAASoP,EAAI7oC,UAAU,EAAG,GAAI,IAAM5G,KAAK0vC,IAAI,EAAGA,GAC1DD,EAAMA,EAAI7oC,UAAU,EAAG6oC,EAAIrrC,QAC3BsrC,GAAO,CAGX,OAAO1uC,GAKX,QAAS2uC,GAAWC,EAAQzlC,GACxB,GAAI0lC,GAAYD,EACZE,EAAa3lC,CAwBjB,OAvBkB3H,UAAdqtC,IACAA,EAAY,EACZC,EAAa,GAAIzxC,IAAG+L,SAGxB/L,GAAGwL,cAAcT,EAAYymC,EAAW,GAAGp6B,KAAK,SAASg6B,GACrD,GACIM,GADAj+B,EAAQ,cAAcxP,KAAKmtC,EAG3B39B,GACiB,MAAbA,EAAM,IACNi+B,EAAgB1P,SAASoP,EAAIlpC,MAAM,EAAG,GAAI,IAC1CopC,EAAWE,EAAYE,EAAgB,EAAGD,IAG1CA,EAAWxlC,QAAQulC,GAIvBC,EAAWtlC,QAAQ,iCAIpBslC,EAIX,QAASE,KACL,GAAI7lC,GAAU,GAAI9L,IAAG+L,OAgBrB,OAdA/L,IAAGwL,cAAcT,EAAY,EAAG,GAAGqM,KAAK,SAASg6B,GACjB,IAAxBA,EAAIzrC,QAAQ,QACZmG,EAAQK,QAAQ,qBAGhBmlC,IAAal6B,KAAK,SAASm6B,GACvBzlC,EAAQG,QAAQslC,IAEpB,SAASlnC,GACLyB,EAAQK,QAAQ9B,OAKrByB,EAIX,QAAS8lC,GAAeC,GACpB,GAAI/lC,GAAU,GAAI9L,IAAG+L,OAMrB,OAJA/L,IAAGwL,cAAcT,EAAY8mC,EAAY,GAAI,GAAGz6B,KAAK,SAASg6B,GAC1DtlC,EAAQG,QAAgB,SAARmlC,KAGbtlC,EAIX,QAASgmC,GAAiBD,EAAWE,GACjC,GAAIjmC,GAAU,GAAI9L,IAAG+L,OAWrB,OATA/L,IAAGwL,cAAcT,EAAY8mC,EAAY,GAAI,GAAGz6B,KAAK,SAASg6B,GAC1D,MAAIW,GACOjmC,EAAQG,QAAQklC,EAAkBC,QAGzCtlC,GAAQG,QAAQ+1B,SAASoP,EAAK,OAI/BtlC,EAIX,QAASkmC,GAAOH,EAAWI,GACvB,GAAIV,GAASM,EAAY,GACrBxmC,EAAqB,GAAb4mC,CAEZ,OAAOjyC,IAAGwL,cAAcT,EAAYwmC,EAAQlmC,GAIhD,QAAS6mC,GAAcC,GAInB,IAHA,GAAI33B,MACA+2B,EAAS,EAENA,EAAS,IAAMY,EAAOpsC,QACzByU,EAAQtX,KAAKivC,EAAOjqC,MAAMqpC,EAAQA,EAAS,KAC3CA,GAAU,EAGd,OAAO/2B,GAIX,QAAS43B,GAAaL,EAAcE,GAChC,GAAII,GAAiB,GACjBC,EAAatyC,GAAG6B,UAAW0wC,GAC3BC,IAsBJ,OApBAxyC,IAAG+C,KAAKkvC,EAAY,SAASjvC,EAAKi2B,GAC9B,GAGIwZ,GAAWjpC,EAASkpC,EAHpBC,EAAQ1Z,EAAM/wB,MAAM,EAAG,GACvBuS,EAAKs3B,EAAeZ,EAAkBwB,GAAS3Q,SAAS2Q,EAAO,IAC/DC,EAAgBN,EAAW3sC,QAAQ8U,EAYvC,IATIm4B,GAAiB,IACjBppC,EAAUqpC,EAASp4B,GAAI1Y,KACvB2wC,EAAeG,EAASp4B,GAAIpP,MAC5BonC,EAAYxZ,EAAM/wB,MAAMmqC,EAAgBA,EAAiC,EAAfK,GAC1DF,EAAKhpC,GAAWuoC,EAAeZ,EAAkBsB,GAAazQ,SAASyQ,EAAW,IAElFH,EAAW/1B,OAAOq2B,EAAe,IAGX,IAAtBN,EAAWvsC,OACX,OAAO,IAIRysC,EApJX,GAAID,IAAW,KACXM,GACIC,KACI/wC,KAAM,cACNsJ,MAAO,GAmJnBrL,IAAG6B,OAAOxB,MAONuR,MAAO,WACH,GAAImhC,GAAS,GAAI/yC,IAAG+L,QAChBinC,EAAiB,SAAS5sC,GACtBD,EAAInG,GAAG8H,OAAO,kCAAmC1B,IACjD2sC,EAAO5mC,QAAQ/F,GA0BvB,OAvBAurC,KAAgBv6B,KAAK,SAAS67B,GAC1B9sC,EAAInG,GAAG8H,OAAO,mDAAwE3D,SAApB4G,EAAWhJ,KAAqB,OAASgJ,EAAWhJ,OAEtH6vC,EAAeqB,GAAY77B,KAAK,SAAS26B,GAErC5rC,EAAInG,GAAG8H,OAAO,+BAAgCiqC,EAAe,SAAW,QAExED,EAAiBmB,EAAYlB,GAAc36B,KAAK,SAAS87B,GAErD/sC,EAAInG,GAAG8H,OAAO,kCAAmCorC,IAEjDlB,EAAOiB,EAAYC,GAAe97B,KAAK,SAAS+6B,GAC5C,GAAIF,GAAaC,EAAcC,GAC3BgB,EAAYf,EAAaL,EAAcE,EAE3C9rC,GAAI,sCAEJ4sC,EAAO9mC,QAAQknC,IAChBH,IACJA,IACJA,IACJA,GAEID,KAKf1yC,KAAK6wC,YACL7wC,KAAK6wC,SAASC,kBAAoBA,GC7MtCnxC,GAAGkwC,SAAW,SAASnlC,EAAY5E,GAC/B,YAEA,SAASitC,GAAeC,EAAYC,GAChC,GAAIC,IAAe,EACfC,KAAuBpjC,OAAOijC,EASlC,OAPArzC,IAAG+C,KAAKywC,EAAmB,SAASxwC,EAAKywC,GACrC,GAAwD,IAApDH,EAAkB3tC,QAAQ8tC,GAE1B,MADAF,IAAe,GACR,IAIRA,EAGXvzC,GAAG6B,OAAOxB,MASN+vC,cAAe,WACX,GAAI33B,GAAOpY,KACP+nB,EAAa,GAAIpoB,IAAG+L,QACpB2nC,GAAc,EACd3xC,EAA2BoC,SAApB4G,EAAWhJ,KAAqB,OAASgJ,EAAWhJ,IAsC/D,OApCAoE,GAAInG,GAAG8H,OAAO,gEAAiE/F,IAE/EoE,EAAI,oDAEA9F,KAAKszC,qBACLxtC,EAAI,sDAEJnG,GAAGwL,cAAcT,EAAY,EAAG,GAAGqM,KAAK,SAASg6B,GAC7CpxC,GAAG+C,KAAK0V,EAAKm7B,uBAAwB,SAAStvC,EAAM+G,GAChD,GAAI+nC,EAAe/nC,EAAO+lC,GAQtB,OALa,eAAT9sC,GAAyBtE,GAAGkT,kBAAkByD,gBAC9C+8B,GAAc,EACdtrB,EAAWnc,QAAQ3H,KAGhB,IAIf6B,EAAInG,GAAG8H,OAAO,iDAAkD/F,EAAM2xC,EAAc,GAAK,QAEpFA,GACDtrB,EAAWjc,WAGnB,WACIhG,EAAI,+BAAiCpE,EAAO,gDAC5CqmB,EAAWjc,aAIfic,EAAWjc,UAGRic,GAWXurB,kBAAmB,WACf,GAAIE,GAAW9oC,EAAWxK,KAEtBuzC,EAAoB9zC,GAAG2F,QAAQc,OAAOo5B,KAAKx/B,KAAKuzC,wBAAyBC,IAAa,EACtFH,GAAc,EACd3xC,EAA2BoC,SAApB4G,EAAWhJ,KAAqB,OAASgJ,EAAWhJ,IAa/D,OAXI+xC,KAEIJ,EADa,eAAbG,GACc7zC,GAAGkT,kBAAkByD,eAO1C+8B,GAAevtC,EAAIpE,EAAO,gEAEpB2xC,MAKnB1zC,GAAGkwC,SAASxpC,UAAUktC,wBAClBG,aAAc,SACdC,YAAa,SACbC,YAAa,SACbC,YAAa,OACbC,cAAe,WAAY,aCpG/Bn0C,GAAGq1B,gBAAkB,SAAS5pB,EAAMtF,GAChC,YAMA,SAASiuC,GAAiBC,GACtB,GAAIC,IAAa,CASjB,OAPAt0C,IAAG+C,KAAKsxC,EAAQ,SAASE,EAAOxtC,GAC5B,GAAIA,EAAQ,EAER,MADAutC,IAAa,GACN,IAIRA,EAQX,QAASE,KACL,GAAIC,GAAoB,GAAIz0C,IAAG+L,OA6B/B,OA3BA,IAAI/L,IAAGkwC,SAASzkC,EAAMtF,GAAKiqC,gBAAgBh5B,KAAK,WAC5C,GAAIme,GAAQ,GAAImY,OACZjT,EAAMv1B,OAAOyoC,KAAOzoC,OAAOyoC,IAAIC,gBAAkB1oC,OAAOyoC,IAClDzoC,OAAO2oC,WAAa3oC,OAAO2oC,UAAUD,gBAAkB1oC,OAAO2oC,UAC9D,IAENpT,IACAlF,EAAMrpB,QAAU,WACZ/F,EAAI,4DAA6D,SACjEsuC,EAAkBtoC,WAGtBopB,EAAMvpB,OAAS,WACXyoC,EAAkBxoC,SACdq+B,MAAOjqC,KAAKiqC,MACZjxB,OAAQhZ,KAAKgZ,UAIrBkc,EAAMuY,IAAMrT,EAAImT,gBAAgBniC,KAGhCtF,EAAI,+DAAgE,SACpEsuC,EAAkBtoC,YAEvBsoC,EAAkBtoC,SAEdsoC,EASX,QAASC,GAAgBL,EAAQM,GAC7B,GAAIC,EA0BJ,OAxBA50C,IAAG+C,KAAKsxC,EAAQ,SAASQ,EAAWC,GAChC,GAAIA,EAAa,EAAG,CAChB,GAAIC,GAAe,0BAA0B9wC,KAAK4wC,GAC9CG,EAAoBD,EAAa,GAAGhlC,OAAO,GAAGzG,cAAgByrC,EAAa,GAAG7sC,MAAM,GACpF+sC,EAAcN,EAAWK,EAG7B,QAAQD,EAAa,IACjB,IAAK,MACD,GAAIE,EAAcH,EAEd,MADAF,GAAeC,GACR,CAEX,MACJ,KAAK,MACD,GAAII,EAAcH,EAEd,MADAF,GAAeC,GACR,MAOpBD,EAWXv0C,KAAKi1B,SAAW,SAAS+e,GACrB,GAAIa,GAAmB,GAAIl1C,IAAG+L,OAoB9B,OAlBA5F,GAAI,iCAEAiuC,EAAiBC,GACjBG,IAAiBp9B,KAAK,SAASu9B,GAC3B,GAAIC,GAAeF,EAAgBL,EAAQM,EAEvCC,GACAM,EAAiB/oC,QAAQyoC,GAGzBM,EAAiBjpC,WAEtBipC,EAAiBjpC,SAGpBipC,EAAiBjpC,UAGdipC,IC7Hfl1C,GAAGs0B,QAAU,SAAS5Y,GAClB,YAaA,SAASy5B,GAAoB/jB,GACzB,QAAIpxB,GAAG8G,QAAQsqB,QAIf7Y,GAAQpS,IAAI,oCAAqC,SAGrD,QAASivC,GAAgBC,EAAWppC,EAASwb,EAAU3b,GACnD,GAAIwpC,IAAmB,CAEvBrpC,GAAUA,GAAWkpC,EAAoBE,GAErCppC,GACAjM,GAAG+C,KAAKsyC,EAAW,SAASryC,EAAK86B,GAE7B,GAAqB,MAAjBA,EAASljB,KACT06B,GAAmB,EACnB/8B,EAAQpS,IAAInG,GAAG8H,OAAO,oEAAqE9E,GAAM,aAEhG,IAAqB,MAAjB86B,EAAS/7B,KACduzC,GAAmB,EACnB/8B,EAAQpS,IAAInG,GAAG8H,OAAO,oEAAqE9E,GAAM,aAGjG,KAEI,MADAuV,GAAQic,cAAcsJ,IACf,EAEX,MAAOyX,GACHD,GAAmB,EACnB/8B,EAAQpS,IAAIovC,EAAInvC,QAAS,SAIjC,OAAO,IAIf0F,EAAQG,IAAYqpC,EAAmB,UAAY,WAAWD,EAAW5tB,GAlD7E,GAAIlP,IACA6F,SAAU,KACVD,UACA+I,iBACAG,QACAmN,cAAe,SAASzO,KACxB5f,IAAK,SAASC,EAASC,KAG3BrG,IAAG6B,OAAO0W,EAASmD,GAAM,GA8CzBrb,KAAKo0B,QAAU,WAEX,GAAI+gB,GAAgB,GAAIx1C,IAAG+L,QACvB0pC,EAA0B,SAASrkB,EAAUnlB,EAASwb,GAClD2tB,EAAgBhkB,EAAUnlB,EAASwb,EAAU+tB,IAEjDE,EAAmB11C,GAAG6B,UAAW0W,GACjCuxB,EAAY,GAAI9pC,IAAG21C,qBACf31C,GAAG6B,OAAO6zC,GAAmBzqB,WAAYwqB,IAKjD,OAFA3L,GAAU8L,cAEHJ,ICrEfx1C,GAAG21C,qBAAuB,SAASj6B,GAC/B,YAiBA,SAASuP,GAAWxQ,EAAIgN,EAAUC,GAC9B,GAAI0J,GAAW,IAGf,IAA6B,MAAzB3J,EAASouB,aACT,IACIzkB,EAAWpxB,GAAGyR,UAAUgW,EAASouB,cAErC,MAAON,GACHh9B,EAAQpS,IAAI,qCAAuCovC,EAAInvC,QAAS,SAChEshB,GAAU,EAIlBnP,EAAQ0S,WAAWmG,GAAW1J,EAASD,GA7B3C,GAAIqiB,GACAvxB,GACI6F,SAAU,KACV8I,iBACA/I,UACAkJ,MACIqI,UAAU,EACVyI,iBAAiB,GAErBlN,WAAY,SAASmG,EAAUnlB,EAASwb,KACxCthB,IAAK,SAAS4B,EAAK1B,KAG3BrG,IAAG6B,OAAO0W,EAASmD,GAmBnBouB,EAAY9pC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGk5B,eAC/B6C,aAAc,mBACdM,cAAe,OACfzV,OAAQ,MACRQ,eACI9E,IAAK,WACD,MAAO/J,GAAQ6F,WAGvB8I,cAAe3O,EAAQ2O,cACvB/gB,IAAKoS,EAAQpS,IACb8kB,WAAYA,EACZ5D,KAAM9O,EAAQ8O,QAGlBrnB,GAAG6B,OAAOxB,MACNu1C,YAAa,WACT,GAAIz3B,GAASne,GAAG6B,UAAW0W,EAAQ4F,OAEnC5F,GAAQpS,IAAI,0BAEZ2jC,EAAUnN,cAAc,kBACnBK,WAAW7e,GACXmf,kBACAjC,WCzDjBr7B,GAAGukB,OAAS,SAAS7I,EAAMvV,GACvB,YAEA,IACImb,GAAuB5F,EAAK2c,cAC5Byd,EAAkBp6B,EAAK4c,aACvBC,EAAS7c,EAAK6c,OACdC,EAAc9c,EAAK8c,YACnBC,EAAiB/c,EAAK+c,eAAiB,IACvCsd,EAAoBr6B,EAAKgd,YACzBC,EAAcjd,EAAKid,YACnBC,EAAQv4B,KAAK21C,gBAAgBt6B,EAAKkd,MAGtC54B,IAAG6B,OAAOxB,MAGNogB,QAASzgB,GAAGkT,kBAAkBwD,SAAWkiB,EAAM7yB,OAAS,EAExDkwC,eAAgB,SAASC,EAAkBC,EAAkBC,GACzD,GAAI39B,GAAOpY,KACPg2C,KACAC,EAAeF,EAAuB3qC,KAAO2qC,EAAuB3qC,KAAO2qC,EAC3EhuB,EAAa,GAAIpoB,IAAGkwC,SAASoG,EAAcnwC,EAiD/C,OA9CIiiB,GAAWurB,qBAEX3zC,GAAG+C,KAAK61B,EAAO,SAAS51B,EAAKuzC,GACzB,GAAIC,GAAa/9B,EAAKg+B,sBAClBje,YAAaA,EACbke,cAAeH,EAAWh2C,KAC1Bo2C,QAASL,EAAa/1C,MAG1B81C,GAAQnzC,MACJ0X,KAAM5a,GAAGoN,cACTrL,KAAM0W,EAAKm+B,SAAST,GAChBp0C,KAAMw0C,EAAWx0C,KACjBxB,KAAMi2C,EACNG,QAASL,EAAa/1C,OAE1BkL,KAAM,GAAIzL,IAAG8X,UAAUw+B,EACvBt2C,GAAGgQ,KAAKyI,EAAKo+B,qBAAsBp+B,GAC/B6I,qBAAsBA,EACtBF,QAASm1B,EAAWn1B,QACpBmX,OAAQA,EACRh4B,KAAMi2C,EACNjyC,QAASk0B,EACTqe,WAAYf,EACZpd,YAAaA,EACbxyB,IAAKA,SAKjBkwC,EAAQnzC,MACJ0X,KAAMs7B,EACNn0C,KAAMo0C,EACNt6B,KAAMy6B,EAAaz6B,KACnBpQ,KAAMqqC,EAAkBQ,EAAe,QAI3CD,EAAQnzC,MACJ0X,KAAMs7B,EACNn0C,KAAMo0C,EACNt6B,KAAMy6B,EAAaz6B,KACnBpQ,KAAM6qC,IAIPD,GAGXtd,cAAe,SAASnZ,EAAM7d,EAAM6Y,EAAMiB,EAAMiT,EAAUhT,EAASiL,EAAegwB,GAC9E,GAAIt+B,GAAOpY,KAEP22C,GADWp3B,EAAKyG,YAAezG,EAAKnU,MAAQmU,EAAKnU,KAAK4a,eAEtD4wB,EAAa,KACbroB,EAAmBmoB,EAAInoB,iBACvBrO,EAAaw2B,EAAIx2B,WACjB4G,EAAc4vB,EAAI5vB,YAClBpL,EAAe/b,GAAGoN,aAEtBpN,IAAG+C,KAAK0V,EAAKw9B,eAAer7B,EAAM7Y,EAAM6d,GAAO,SAAS5c,EAAKk0C,GACzD,GACIz8B,GADA08B,EAAWD,EAAOr7B,IAGlBq7B,GAAOzrC,eAAgBzL,IAAG8X,YAC1Bq/B,GAAW,GAGf18B,EAAK8F,EAAW9E,SACZb,KAAMs8B,EAAOt8B,KACb7Y,KAAMm1C,EAAOn1C,KACb8Z,KAAMs7B,EACNr7B,QAASA,EACTC,aAAcA,IAGdm7B,EAAOzrC,eAAgBzL,IAAG8X,UAC1Bk/B,EAAU9zC,KAAKuX,GAGfw8B,EAAax8B,EAGby8B,EAAOzrC,MACPmjB,EAAiBnU,EAAIy8B,EAAOzrC,MAC5BqjB,EAAS5rB,MAAMuX,GAAIA,EAAImF,KAAMs3B,EAAOzrC,QAGpC8U,EAAWpE,UAAU1B,EAAIza,GAAG+a,OAAOsC,YAOxB,OAAf45B,IACAj3C,GAAG+C,KAAKi0C,EAAW,SAASh0C,EAAKo0C,GAC7B,GAAIj5B,IACAk5B,aAAc92B,EAAWtE,UAAUxB,GAAIw8B,IAAar8B,KACpD08B,aAAc/2B,EAAWtE,UAAUxB,GAAIw8B,IAAap7B,KAKxDsC,GAAO4I,GAAiBxG,EAAWtE,UAAUxB,GAAI28B,IAAWx8B,KAE5D2F,EAAWxD,YAAYq6B,EAAUH,GACjC9vB,EAAY+B,YAAYkuB,EAAUj5B,KAKlC64B,EAAUjxC,SACT,WACG,GAAIwxC,KACJA,GAAMxwB,GAAiBxG,EAAWtE,UAAUxB,GAAIw8B,IAAar8B,KAC7DuM,EAAY+B,YAAY+tB,EAAYM,WAQ5Dv3C,GAAG6B,OAAO7B,GAAGukB,OAAO7d,WAChB2d,WAAY,SAAS5J,EAAI6J,EAAOyyB,GAC5B,YAEA,KAAK/2C,GAAGkT,kBAAkBwD,QACtB,KAAM,IAAI1W,IAAGwB,MAAM,4CAGvB,IAAIg2C,GAAgB,GAAIx3C,IAAG+L,QACvB5F,EAAM4wC,EAAI5wC,IACVyZ,EAAOm3B,EAAIn1B,QAAQnH,GACnB8F,EAAaw2B,EAAIx2B,WAAWtE,UAAUxB,GAAIA,IAC1C1Y,EAAOwe,GAAcA,EAAWxe,KAChC6Y,EAAO2F,GAAcA,EAAW3F,KAChC68B,GACIpf,cAAe/T,EAAM+T,cACrBC,cAAc,EACdC,OAAQjU,EAAMiU,OACdC,YAAalU,EAAM/jB,MAAQ,KAC3Bk4B,eAAgBnU,EAAM/f,QACtBwxC,kBAAmB,kBACnBnd,QAAS72B,KAAM,GAAIqf,QAASkD,EAAMlD,WAEtCs2B,EAAS,GAAI13C,IAAGukB,OAAOkzB,EAAgBtxC,EAuB3C,OArBKnG,IAAGukB,QAAWvkB,GAAGkT,kBAAkBkD,eAAkBwJ,EAOrD5f,GAAGgQ,KAAK,WAEL,GAAIknC,GAASQ,EAAOzB,eAAer7B,EAAM7Y,EAAM6d,GAAM,EAEjDs3B,IAAUA,EAAOzrC,eAAgBzL,IAAG8X,UACpCo/B,EAAOzrC,KAAKwM,SAASb,KAAKogC,EAAcvrC,QAASurC,EAAcrrC,UAG/DhG,EAAIsU,EAAK,4BAA6B,SACtC+8B,EAAcrrC,YAEnB9L,SAjBHm3C,EAAcrrC,UAEdhG,EAAI,iDAAmDsU,EAAK,uFAC6B,UAiBtF+8B,GAKXf,qBAAsB,SAAS/6B,GAC3B,YAEA,IAAIg7B,GAAgBh7B,EAAKg7B,cACrBle,EAAc9c,EAAK8c,YACnBmf,EAAgBj8B,EAAKi7B,OAIzB,OAAKne,IAAgBke,EAQhBA,GAKD12C,GAAG2F,QAAQc,OAAOo5B,KAAK7/B,GAAGkwC,SAASxpC,UAAUktC,wBAAyB8C,IAAkB,EAClE,eAAlBA,EACO12C,GAAGkT,kBAAkByD,aAAe+/B,EAAgBle,EAGxDke,EATAle,EARe,eAAlBmf,EACO,YAEJA,GAqBff,SAAU,SAASh7B,EAAcg8B,GAC7B,YAEA,IAAIC,GAAaj8B,EAAa3J,YAAY,KACtC6lC,EAAcF,EAAwBr3C,MAAQ,YAC9Co3C,EAAgBC,EAAwBjB,QACxCoB,EAAa,GACbC,EAAYh4C,GAAG8R,aAAa8J,GAC5Bq8B,EAAgB,EAmBpB,OAjBIL,GAAwB71C,MAAQ61C,EAAwB71C,KAAK8F,OAAO9B,SACpEkyC,EAAgB,KAAOL,EAAwB71C,KAAO,KAGtD81C,GAAc,GACdE,EAAan8B,EAAa1J,OAAO,EAAG2lC,GAEhCF,IAAkBG,IAClBE,EAAYF,EAAYpyC,MAAM,KAAK,IAGvCqyC,GAAcE,EAAgB,IAAMD,GAGpCD,EAAan8B,EAAeq8B,EAGzBF,GAIX/B,gBAAiB,SAASpd,GACtB,YAIA,OAFAA,GAAQ54B,GAAG6B,UAAW+2B,GAEfA,EAAMsf,KAAK,SAASC,EAAGC,GAC1B,MAAID,GAAE/2B,QAAUg3B,EAAEh3B,QACP,EAEP+2B,EAAE/2B,QAAUg3B,EAAEh3B,SACP,EAEJ,KAIfy1B,qBAAsB,SAASn7B,EAAM28B,GACjC,YAEA,IAAI5/B,GAAOpY,KACPihB,EAAuB5F,EAAK4F,qBAC5Bnb,EAAMuV,EAAKvV,IACXib,EAAU1F,EAAK0F,QACfmX,EAAS7c,EAAK6c,OACdh4B,EAAOmb,EAAKnb,KACZgE,EAAUmX,EAAKnX,QACfuyC,EAAap7B,EAAKo7B,WAClBne,EAAcjd,EAAKid,aAAmC,eAApB0f,EAAW93C,MAAkC,eAATA,EACtEi3C,EAAgB,GAAIx3C,IAAG+L,QACvBusC,EAAiB,GAAIt4C,IAAG64B,eAAe1yB,GACvC9B,EAASwF,SAASC,cAAc,SA8BpC,OA5BA3D,GAAI,6CAA+CkyC,EAAWt2C,MAE9Du2C,EAAex2B,SAASu2B,EAAYh0C,GAAS+c,QAASA,EAASmX,OAAQA,EAAQjX,qBAAsBA,IAAuBlK,KAAK,WAC7H,GAAImhC,GAAqBl0C,EAAOI,UAAUlE,EAAMgE,GAC5Ci0C,EAAgB,WACZryC,EAAI,yCAA2CkyC,EAAWt2C,KAC1D,IAAI0J,GAAOzL,GAAGwE,cAAc+zC,EAC5Bf,GAAcvrC,QAAQR,GAG1BktB,GACAlgB,EAAKggC,kBAAkBJ,EAAYE,EAAoBpyC,GAAKiR,KAAK,SAASshC,GACtEH,EAAqBG,EACrBF,KAEJ,WACIryC,EAAI,wFAAyF,SAC7FqyC,MAIJA,KAEL,WACCryC,EAAI,iDAAmDkyC,EAAWt2C,KAAM,SACxEy1C,EAAcrrC,QAAQ2qC,KAGnBU,GAIXiB,kBAAmB,SAASE,EAAeJ,EAAoBpyC,GAC3D,YAEA,IAAIyyC,GAAS,GAAI/sC,YACbgtC,EAAkB,GAAI74C,IAAG+L,QACzB+sC,EAAuB,EAc3B,OAZAF,GAAO5sC,OAAS,WACZ8sC,EAAuBF,EAAOj2C,OAC9Bk2C,EAAgB5sC,QAAQjM,GAAG+4C,aAAajM,QAAQgM,EAAsBP,KAG1EK,EAAO1sC,QAAU,WACb/F,EAAI,mBAAqBwyC,EAAc52C,KAAO,2DAA4D,SAC1G82C,EAAgB1sC,WAGpBysC,EAAOI,cAAcL,GAEdE,GAGXI,eAAgB,SAASv0C,GACrB,YAEA,IAAIE,GAAYE,EAAYH,EAAaE,CAsBzC,OAlBID,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlC7F,KAAK64C,YAAYv0C,EAAaG,IAGzCo0C,YAAa,SAASl0C,EAAMV,GACxB,YAEA,IAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,OChZ3CtE,GAAG+4C,aAAe,WAGjB,GAAIA,KA+KD,OA7KAA,GAAaI,QAAU,oEAMvBJ,EAAaK,SAAW,SAASxvC,GAE7B,GACIyvC,GAAMC,EACNC,EAAMC,EAAMC,EAFZC,EAAS,GACGC,EAAO,GACDC,EAAO,GACzB9oC,EAAI,CAER,GACIuoC,GAAOzvC,EAAMkH,KACbwoC,EAAO1vC,EAAMkH,KACb6oC,EAAO/vC,EAAMkH,KAEbyoC,EAAOF,GAAQ,EACfG,GAAgB,EAAPH,IAAa,EAAMC,GAAQ,EACpCG,GAAgB,GAAPH,IAAc,EAAMK,GAAQ,EACrCC,EAAc,GAAPD,EAEHE,MAAMP,GACPG,EAAOG,EAAO,GACNC,MAAMF,KACdC,EAAO,IAGVF,EAASA,EACNr5C,KAAK84C,QAAQppC,OAAOwpC,GACpBl5C,KAAK84C,QAAQppC,OAAOypC,GACpBn5C,KAAK84C,QAAQppC,OAAO0pC,GACpBp5C,KAAK84C,QAAQppC,OAAO6pC,GACvBP,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SACvB9oC,EAAIlH,EAAM7D,OAEnB,OAAO2zC,IAGXX,EAAajM,QAAU,SAASgN,EAAgBC,GAE5C,GAAIC,GAAuB,yBAE3B,KAAKF,EAAermC,MAAMumC,GAEzB,MAAOD,EAGR,IAAIE,GAAW55C,KAAK65C,SAASJ,EAAev3C,QAAQy3C,EAAsB,KACtEG,EAAW95C,KAAK+5C,eAAeH,GAE/B1kB,EAAQl1B,KAAKg6C,iBAAiBN,EAAmBI,EAErD,OAAOH,GAAuB35C,KAAK+4C,SAAS7jB,IAKhDwjB,EAAasB,iBAAmB,SAASN,EAAmBI,GAEpD,GAAIG,GAAYj6C,KAAKk6C,aAAaJ,GAC9BK,EAAgBn6C,KAAKo6C,WAAWV,EAAmBO,GACnDI,EAAU,GAAI10C,YAAWw0C,EAE7B,OAAOE,IAIf3B,EAAawB,aAAe,SAASJ,GAG7B,IAAK,GADDQ,GACKC,EAAI,EAAGA,EAAIT,EAASp0C,OAAQ60C,IAGjC,GADAD,EAAMR,EAASS,GACD,KAAVD,EAAI,GAAsB,KAAVA,EAAI,GAEpB,MAAOA,EAGf,WAIR5B,EAAa0B,WAAa,SAASV,EAAmBO,GAE9C,GAAIO,GAAYd,EAAkBx3C,QAAQ,0BAA2B,IACjEu4C,EAAMz6C,KAAK65C,SAASW,GACpBE,EAAgBD,EAAIn1C,QAAQ,IAAI,GAChCq1C,EAAMF,EAAI5yC,MAAM,EAAG6yC,GACnBE,EAAMH,EAAI5yC,MAAM6yC,GAChBG,EAAQF,CAIb,OAFCE,GAAQA,EAAM9qC,OAAOkqC,GACrBY,EAAQA,EAAM9qC,OAAO6qC,IAM7BlC,EAAaqB,eAAiB,SAASe,GAKnC,IAHA,GAAIC,GAAO,EACPjB,OAGJ,CACI,GAA2B,KAAvBgB,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAAW,KACjE,IAA2B,KAAvBD,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAElDA,GAAQ,MAGZ,CACI,GAAIr1C,GAAmC,IAA1Bo1C,EAAcC,EAAO,GAAWD,EAAcC,EAAO,GAC9DC,EAAWD,EAAOr1C,EAAS,EAC3B40C,EAAMQ,EAAcjzC,MAAMkzC,EAAMC,EACpClB,GAASj3C,KAAKy3C,GACdS,EAAOC,EAEX,GAAID,EAAOD,EAAcp1C,OAAQ,MAGrC,MAAOo0C,IAKXpB,EAAamB,SAAW,SAAStwC,GAE7B,GACIyvC,GAAMC,EACNC,EAAMC,EAAMC,EADAE,EAAO,GACDC,EAAO,GACzB9oC,EAAI,EACJgqC,KAGAQ,EAAa,qBACjB,IAAIA,EAAWr3C,KAAK2F,GAChB,KAAM,IAAIpI,OAAM,uHAGpBoI,GAAQA,EAAMrH,QAAQ,sBAAuB,GAE7C,GACIg3C,GAAOl5C,KAAK84C,QAAQxzC,QAAQiE,EAAMmG,OAAOe,MACzC0oC,EAAOn5C,KAAK84C,QAAQxzC,QAAQiE,EAAMmG,OAAOe,MACzC2oC,EAAOp5C,KAAK84C,QAAQxzC,QAAQiE,EAAMmG,OAAOe,MACzC8oC,EAAOv5C,KAAK84C,QAAQxzC,QAAQiE,EAAMmG,OAAOe,MAEzCuoC,EAAQE,GAAQ,EAAMC,GAAQ,EAC9BF,GAAgB,GAAPE,IAAc,EAAMC,GAAQ,EACrCE,GAAgB,EAAPF,IAAa,EAAKG,EAE3BkB,EAAI53C,KAAKm2C,GAEG,IAARI,GACDqB,EAAI53C,KAAKo2C,GAEA,IAARM,GACDkB,EAAI53C,KAAKy2C,GAGZN,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SAEvB9oC,EAAIlH,EAAM7D,OAEnB,OAAO+0C,IAIJ/B,KC7KX/4C,GAAGg5B,cAAgB,SAASvpB,EAAUmT,GAClC,YAEA,IAAI24B,MACAC,EAAc,EACdC,EAAY,EAEZC,GAAiB,EACjBC,GAAgB,EAChBC,EAAgB,SAAS9wB,EAAQC,GACzBD,IAAW4wB,GAAkB3wB,IAAU4wB,GACvClsC,EAASqb,EAAQC,GAGrB2wB,EAAiB5wB,EACjB6wB,EAAgB5wB,GAQpB8wB,EAAmB,SAAS9pB,EAAQ+pB,GAChC,GAAIC,IAAO,CASX,OAPA/7C,IAAG+C,KAAKgvB,EAAQ,SAAS/uB,EAAKg5C,GAC1B,GAAIh8C,GAAG2F,QAAQm2C,EAAWE,IAAa,EAEnC,MADAD,IAAO,GACA,IAIRA,GAGX5wB,EAAW,SAAS1Q,GAChBwhC,EAAoBxhC,GAAI,GAAI,SACrB8gC,GAAgB9gC,IAG3BuX,EAAgB,SAASF,EAAYC,EAAQ+pB,IACnB,IAAlB/pB,EAAOhsB,QAAgB81C,EAAiB9pB,EAAQ+pB,MAChDF,EAAcH,EAAWA,GACzBp7C,KAAK8Z,UAIb+hC,EAAQ,SAASzhC,GACb,GAAIoB,GAAO+G,EAAQnI,EAGfoB,GAAO,IACPogC,EAAoBxhC,EAAI,EAAGoB,GAC3B0/B,EAAgB9gC,IAAOqQ,OAAQ,EAAGC,MAAOlP,KAYjDogC,EAAsB,SAASxhC,EAAI0hC,EAAWC,GAC1C,GAAIC,GAAYd,EAAgB9gC,GAAM8gC,EAAgB9gC,GAAIqQ,OAAS,EAC/DwxB,EAAWf,EAAgB9gC,GAAM8gC,EAAgB9gC,GAAIsQ,MAAQ,CAE7DoxB,MAAc,GAAMC,KAAa,GACjCZ,GAAea,EACfZ,GAAaa,IAGTH,IACAX,GAAeW,EAAYE,GAE3BD,IACAX,GAAaW,EAAWE,IAIhCV,EAAcJ,EAAaC,GAGnCz7C,IAAG6B,OAAOxB,MAEN2xB,cAAeA,EAGfhW,eAAgB,SAASvB,EAAI4B,EAAWD,GAChCA,IAAcpc,GAAG+a,OAAOwC,UAAYnB,IAAcpc,GAAG+a,OAAOsC,SAC5D8N,EAAS1Q,GAEJ2B,IAAcpc,GAAG+a,OAAOY,YAC7BugC,EAAMzhC,IAKdkY,qBAAsB,SAASlY,EAAIqQ,EAAQC,GACvCkxB,EAAoBxhC,EAAIqQ,EAAQC,GAChCwwB,EAAgB9gC,IAAOqQ,OAAQA,EAAQC,MAAOA,IAIlD6J,UAAW,SAASna,GAChByhC,EAAMzhC,IAGVN,MAAO,WACHohC,KACAC,EAAc,EACdC,EAAY,MCzHxBz7C,GAAG6nB,aAAe,SAAS1P,GACvB,YAYA,SAASokC,GAAQj1C,GACb,MAAOA,GAAK/G,MACwB,IAAhC+G,EAAK/G,KAAKoF,QAAQ,UAG1B,QAAS62C,KACLC,EAAqBz8C,GAAGuY,EAAQuP,eAAexnB,OAAO,QAAS,SAAS8zB,GACpE,GAAIsoB,GAAgBtoB,EAAMsoB,aAEtBA,IACA18C,GAAG+C,KAAK25C,EAAclyC,MAAO,SAASxH,EAAKsE,GACvC,GAAIi1C,EAAQj1C,GAAO,CACf,GAAImE,GAAOnE,EAAKq1C,WAChBpkC,GAAQiO,UAAUwB,cAAcvc,QAOpD,QAASmxC,KACDH,GACAA,IAhCR,GAAIlkC,GAASkkC,CAEblkC,IACIuP,cAAe,KACftB,WACIrgB,IAAK,SAASC,EAASC,KACvB2hB,cAAe,SAASvc,OA8BhCzL,GAAG6B,OAAO0W,EAASJ,GACnBqkC,IAEAx8C,GAAG6B,OAAOxB,MACN8Z,MAAO,WACHyiC,QCpCZ58C,GAAGmvB,YAAc,SAAS5W,EAASskC,EAAa12C,GAC5C,YAgCA,SAAS22C,GAAqBC,GACtBA,EAAO74C,aAAa,YACpBuU,EAAK+W,YAAcutB,EAAO74C,aAAa,WAM/C,QAAS84C,GAAaD,EAAQE,GAC1B,QAAIF,EAAOG,gBAAkBH,EAAOG,mBAChC/2C,EAAI,yDAA0D,aAC9D82C,MAQR,QAASE,GAAoBJ,GACzB,GAAIE,GAAeF,EAAOK;AAG1Bp9C,GAAG+8C,GAAQz8C,OAAO,SAAU,SAAS8zB,GACjCA,EAAQA,GAASlvB,OAAOkvB,MAEpBA,EAAMnlB,eACNmlB,EAAMnlB,iBAGNmlB,EAAMjlB,aAAc,EAGxB6tC,EAAaD,EAAQE,IAAiBJ,MAK1CE,EAAOK,OAAS,WACZJ,EAAaD,EAAQE,IAAiBJ,KAM9C,QAASQ,GAAgBN,GAarB,MAZIA,KACI/8C,GAAGwH,SAASu1C,KACZA,EAASlzC,SAAS86B,eAAeoY,IAGjCA,IACA52C,EAAI,8BACJ22C,EAAqBC,GACrB3kB,GAAmB+kB,EAAoBJ,KAIxCA,EAzFX,GAAItkC,GAAQpY,KACR+3B,EAAkB7f,EAAQ6f,gBAC1B2kB,EAASxkC,EAAQtY,QACjBqvB,EAAa/W,EAAQ+W,UAGzBtvB,IAAG6B,OAAOxB,MAINmvB,YAAa,KAIbD,cAAeD,EAGfF,gBAAgB,EAGhBC,sBAAuB,WAEnB,MAAc,OAAV0tB,EACO,KAGJtkC,EAAK6kC,UAAUP,MAkE9BA,EAASM,EAAgBN,GACzB18C,KAAK+uB,iBAAmB2tB,GAG5B/8C,GAAG6B,OAAO7B,GAAGmvB,YAAYzoB,WAGrB42C,UAAW,SAAShsC,GAChB,YACA,IAAIf,MACAgtC,EAAoB,SAASh9C,GACzB,GAAIi9C,IACA,SACA,QACA,QACA,SAGJ,OAAOx9C,IAAG2F,QAAQ63C,EAAiBj9C,EAAK+I,eAAiB,GAE7Dm0C,EAAkB,SAASl9C,GACvB,MAAOP,IAAG2F,SAAS,WAAY,SAAUpF,EAAK+I,gBAAkB,GAEpEo0C,EAAc,SAAShP,GACnB,SAAI+O,EAAgB/O,EAAGnuC,OAAUmuC,EAAGiP,UAI7BjP,EAAGp7B,UAAsC,WAA1Bo7B,EAAGnuC,KAAK+I,eAElCs0C,EAAc,SAASC,GACnB,GAAI92C,GAAQ,IASZ,OAPA/G,IAAG+C,KAAK/C,GAAG69C,GAAQz6C,WAAY,SAASJ,EAAKK,GACzC,GAAoC,WAAhCA,EAAMmG,QAAQF,eAA8BjG,EAAMy6C,SAElD,MADA/2C,GAAQ1D,EAAM0D,OACP,IAIRA,EAmBf,OAhBA/G,IAAG+C,KAAKuO,EAAKysC,SAAU,SAAS/6C,EAAK0rC,GACjC,IAAK1uC,GAAGiJ,QAAQylC,GAAI,IAAsC,aAA7BA,EAAGllC,QAAQF,gBACpCi0C,EAAkB7O,EAAGnuC,OACpBm9C,EAAYhP,IAIZ,GAAiC,WAA7BA,EAAGllC,QAAQF,gBAA+Bo0C,EAAYhP,GAAK,CAChE,GAAI3nC,GAAQ62C,EAAYlP,EAEV,QAAV3nC,IACAwJ,EAAIm+B,EAAG3sC,MAAQgF,QANnBwJ,GAAIm+B,EAAG3sC,MAAQ2sC,EAAG3nC,QAWnBwJ,KCzJfvQ,GAAG2iC,YAAc3iC,GAAG2iC,gBACpB3iC,GAAG2iC,YAAYyB,kBAAoB,SAAS7rB,EAASqlB,GACjD,YAUA,SAASogB,GAAqBvjC,EAAIiqB,GAG9B,GAAItT,GAAU6sB,EAAKC,CAGnB,KAEID,EAAMvZ,EAAOe,iBAAmBf,EAAOyZ,cAAct0C,SACrDq0C,EAAYD,EAAIjZ,KAAKz1B,UAErBpJ,EAAI,yCACJA,EAAI,eAAiB+3C,GAEjBA,GAAaA,EAAUzqC,MAAM,YAC7ByqC,EAAYD,EAAIjZ,KAAK1hC,WAAWA,WAAW86C,WAG/ChtB,EAAW3C,EAAQ2W,mBAAmB8Y,GAE1C,MAAO7zC,GACHlE,EAAI,wDAA0DkE,EAAMjE,QAAU,IAAK,SACnFgrB,GAAYnlB,SAAS,GAGzB,MAAOmlB,GAMX,QAASitB,GAAW5jC,EAAIiqB,GACpB,GAAIvmB,GAAS5F,EAAQ4O,YAAY7E,IAAI7H,GACjCmM,EAA0C,QAAjCrO,EAAQqO,OAAOtd,cAA0B,MAAQ,OAC1D8U,EAAW7F,EAAQ6O,cAAc9E,IAAI7H,GACrC1Y,EAAO2e,EAAQjG,EAKnB,OAHA0D,GAAO5F,EAAQ0O,UAAY9D,EAAQ1I,GACnC0D,EAAO5F,EAAQ0d,eAAiBl0B,EAEzB0sB,EAAQkX,oBACX/e,OAAQA,EACRxI,SAAUA,EACVD,OAAQA,EACRgY,aAAc5d,EAAQ4d,aACtByP,WAAYlB,EAAO3iC,OArD3B,GAAI0sB,GAAUpuB,KACVqgB,EAAUkd,EAAMld,QAChByC,EAAUya,EAAMza,QAChBhd,EAAMy3B,EAAMz3B,GAsDhB9F,MAAKgiC,WAAa,SAAS5nB,GACvB,GAGInJ,GAHA1H,EAAQ6kB,EAAQ5U,SAASY,GACzBiqB,EAASjW,EAAQiX,cAAcjrB,GAC/B3O,EAAU,GAAI9L,IAAG+L,OA8BrB,OA3BAuF,GAAO+sC,EAAW5jC,EAAIiqB,GACtBpzB,EAAKE,YAAY5H,GAEjB6kB,EAAQ8W,iBAAiBb,EAAQ,SAAS4Z,GACtCn4C,EAAI,gBAEJ,IAAIirB,GAAWktB,EAAsBA,EAAsBN,EAAqBvjC,EAAIiqB,EAEpFjW,GAAQ4W,iBAAiB5qB,GAGpBlC,EAAQ8O,KAAKqI,UACd1vB,GAAG0kC,GAAQtjC,SAGXgwB,EAASnlB,QACTH,EAAQG,QAAQmlB,GAGhBtlB,EAAQK,QAAQilB,KAIxBjrB,EAAI,8BAAgCsU,GACpCnJ,EAAK8rC,SACLp9C,GAAGsR,GAAMlQ,SAEF0K,GAGX9L,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGokC,mBACnB7rB,SACIgsB,OAAQhsB,EAAQ8O,KAAKqI,SACrBvF,UAAW5R,EAAQ4R,WAGvByT,OACIzS,SAAU5S,EAAQ4S,SAClBzK,QAASA,EACTyC,QAASA,EACThd,IAAKA,OC5GjBnG,GAAG2iC,YAAc3iC,GAAG2iC,gBACpB3iC,GAAG2iC,YAAYmD,iBAAmB,SAASpqB,EAAMkiB,GAC7C,YAEA,IAAInP,GAAUpuB,KACVqgB,EAAUkd,EAAMld,QAChBkC,EAAUgb,EAAMhb,QAChBO,EAAUya,EAAMza,QAChBhd,EAAMy3B,EAAMz3B,IACZo4C,EAAY7iC,EAAKwa,gBAAkBxa,EAAKya,aAExCqoB,EAA4B,SAAS/jC,EAAI0D,EAAQwN,GAC7C,GAAI9P,GAAO+G,EAAQnI,GACf1Y,EAAO2e,EAAQjG,EAEnB0D,GAAOzC,EAAK/F,SAAS8hB,WAAWC,WAAa/L,EAAUqc,KACvD7pB,EAAOzC,EAAK/F,SAAS8hB,WAAWE,gBAAkBhM,EAAU3gB,MAC5DmT,EAAOzC,EAAK/F,SAAS8hB,WAAWG,WAAajM,EAAU9P,KACvDsC,EAAOzC,EAAK/F,SAAS8hB,WAAWK,YAAcnM,EAAUsc,MACxD9pB,EAAOzC,EAAK0a,mBAAqBva,EAM7B0iC,IACApgC,EAAOzC,EAAKua,eAAiBl0B,IAIrC08C,EAAyB,GAAIz+C,IAAG2iC,YAAY+b,4BACxCr3B,KAAM3L,EAAK2L,KACXjJ,SAAU1C,EAAK/F,SAAS1J,QAAQmS,SAChCjY,IAAKA,IAGTw4C,EAAiC,SAASlkC,EAAI7G,GAC1C,GAAI9H,GAAU,GAAI9L,IAAG+L,OAerB,OAbA6H,GAAIonB,mBAAqB,WACrB,GAAuB,IAAnBpnB,EAAI8nB,WAAkB,CACtB,GAAI/4B,GAASi8C,EAAwBnkC,EAAI7G,EAErCjR,GAAOsJ,QACPH,EAAQG,QAAQtJ,EAAOyuB,SAAUxd,GAGjC9H,EAAQK,QAAQxJ,EAAOyuB,SAAUxd,KAKtC9H,GAGX+yC,EAA0B,SAASpkC,GAC/B,GAAI0D,GAASzC,EAAKyL,YAAY7E,IAAI7H,GAC9B1Y,EAAO2e,EAAQjG,GACfoB,EAAO+G,EAAQnI,EAOnB,OALA0D,GAAOzC,EAAKuL,UAAY9D,EAAQ1I,GAChC0D,EAAOzC,EAAKua,eAAiBl0B,EAC7Boc,EAAOzC,EAAK0a,mBAAqBva,EACjCsC,EAAOzC,EAAK/F,SAAS8hB,WAAWK,YAAcrJ,EAAQgS,gBAAgBhmB,GAE/D0D,GAGX2gC,EAAwB,SAASlrC,EAAKwd,GAClC,MAAOpxB,IAAG2F,SAAS,IAAK,IAAK,IAAK,IAAK,KAAMiO,EAAImH,QAAU,IACtDqW,EAASnlB,SACVmlB,EAASjX,OAGjBykC,EAA0B,SAASnkC,EAAI7G,GACnC,GAAIwd,EAOJ,OALAjrB,GAAI,sCAAwCsU,GAC5CtU,EAAI,kBAAoByN,EAAIiiC,cAE5BzkB,EAAW2tB,GAAc,EAAMnrC,IAG3B3H,SAAU6yC,EAAsBlrC,EAAKwd,GACrCA,SAAUA,IAKlB2tB,EAAgB,SAAS70C,EAAQ0J,GAC7B,GAAIwd,KAEJ,KACIjrB,EAAInG,GAAG8H,OAAO,4CAA6C8L,EAAImH,OAAQnH,EAAIiiC,eAC3EzkB,EAAWpxB,GAAGyR,UAAUmC,EAAIiiC,cAEhC,MAAOxrC,GACHH,GAAU/D,EAAI,qDAAuDkE,EAAMjE,QAAU,IAAK,SAG9F,MAAOgrB,IAGX4tB,EAA4B,SAASvkC,GACjC,GAAI3O,GAAU,GAAI9L,IAAG+L,OAcrB,OAZA0yC,GAAuBQ,SACfxkC,EACAgU,EAAQgZ,WAAWhtB,GACnBokC,EAAwBpkC,GACxBiB,EAAKwL,cAAc5E,IAAI7H,IAE1BrD,KAAK,SAASxD,GACX9H,EAAQG,QAAQ8yC,GAAc,EAAOnrC,GAAMA,IAC5C,SAASA,GACR9H,EAAQK,QAAQ4yC,GAAc,EAAOnrC,GAAMA,KAG5C9H,GAGXozC,EAA8B,SAAS/gC,EAAQvK,EAAK7I,EAAY0P,GAC5D,GAAItJ,GAAW,GAAInH,UACf4c,EAASlL,EAAKkL,OACdxI,EAAW1C,EAAK0L,cAAc9E,IAAI7H,GAClC1Y,EAAO2e,EAAQjG,GACfoB,EAAO+G,EAAQnI,EAuBnB,OArBA0D,GAAOzC,EAAKuL,UAAY9D,EAAQ1I,GAChC0D,EAAOzC,EAAKua,eAAiBl0B,EAEzBw8C,IACApgC,EAAOzC,EAAK0a,mBAAqBva,GAIhCH,EAAKya,eACDooB,IACDpgC,EAAOzC,EAAKyO,WAAapoB,GAE7Bqc,EAAWpe,GAAGsQ,QAAQ6N,EAAQC,IAGlCxK,EAAIunB,KAAKvU,EAAQxI,GAAU,GAEvB1C,EAAK2L,KAAKqI,UAAYhU,EAAK2L,KAAK8Q,kBAChCvkB,EAAIC,iBAAkB,GAGtB0qC,GACI7iC,EAAKya,cACLn2B,GAAGkR,aAAaiN,EAAQhN,GAG5BA,EAAS5L,OAAOmW,EAAKyO,UAAWpf,GACzBoG,GAGJpG,GAGXo0C,EAAmB,SAAS1kC,EAAI7G,GAC5B,GAAIwrC,GAAe1jC,EAAKwL,cAAc5E,IAAI7H,GACtC1P,EAAa0jB,EAAQ7M,QAAQnH,EAEjC7G,GAAIooB,iBAAiB,SAAU,oBAC/BpoB,EAAIooB,iBAAiB,mBAAoB,kBACzCpoB,EAAIooB,iBAAiB,gBAAiB,YAEjCuiB,IACD3qC,EAAIooB,iBAAiB,eAAgB,4BAErCpoB,EAAIooB,iBAAiB,cAAejxB,EAAWxK,OAGnDP,GAAG+C,KAAKq8C,EAAc,SAASr9C,EAAMkB,GACjC2Q,EAAIooB,iBAAiBj6B,EAAMkB,KAIvCjD,IAAG6B,OAAOxB,MACNygC,YAAa,SAASrmB,EAAIikB,EAAUzG,GAChC,GAGInsB,GAASuzC,EAAQlhC,EAHjBwN,EAAY8C,EAAQkQ,cAAclkB,EAAIikB,GACtC9qB,EAAM6a,EAAQgZ,WAAWhtB,EAAIikB,EACtB9b,GAAQnI,EAgBnB,OAbA3O,GAAU6yC,EAA+BlkC,EAAI7G,GAC7C6a,EAAQqa,yBAAyBruB,EAAIikB,EAAU/S,EAAU9P,MACzDsC,EAASzC,EAAKyL,YAAY7E,IAAI7H,GAC9B+jC,EAA0B/jC,EAAI0D,EAAQwN,GAElCsM,IACA9Z,EAAOzC,EAAKjF,OAAOghB,WAAWQ,WAAY,GAG9ConB,EAASH,EAA4B/gC,EAAQvK,EAAK+X,EAAUlgB,KAAMgP,GAClE0kC,EAAiB1kC,EAAI7G,GACrBA,EAAIynB,KAAKgkB,GAEFvzC,GAGXu2B,WAAY,SAAS5nB,GACjB,GACI3O,GAAS8H,EAAKuK,EAAQkhC,EADtBt0C,EAAa0jB,EAAQ7M,QAAQnH,EAWjC,OARA7G,GAAM6a,EAAQgZ,WAAWhtB,GACzBgU,EAAQqa,yBAAyBruB,GACjC3O,EAAU6yC,EAA+BlkC,EAAI7G,GAC7CuK,EAASzC,EAAKyL,YAAY7E,IAAI7H,GAC9B4kC,EAASH,EAA4B/gC,EAAQvK,EAAK7I,EAAY0P,GAC9D0kC,EAAiB1kC,EAAI7G,GACrBA,EAAIynB,KAAKgkB,GAEFvzC,KAIf9L,GAAG6B,OAAOxB,KAAM,GAAIL,IAAG8lC,kBACnBvtB,QAASvY,GAAG6B,QAAQ4oB,UAAW,eAAgB/O,GAC/CkiB,MAAO59B,GAAG6B,QAAQugB,YAAa1G,EAAK0L,cAAc9E,KAAMsb,MAG5D59B,GAAGwM,SAASnM,KAAM,SAASsM,GACvB,OACIqyB,eAAgB,SAASvkB,GACrB,MAAIiB,GAAK/F,SAAS1J,QAAQmS,SACf4gC,EAA0BvkC,GAG1B9N,EAAOqyB,eAAevkB,EAAIza,GAAGgQ,KAAK+uC,EAAe1+C,MAAM,SCvOlFL,GAAG2iC,YAAY+b,2BAA6B,SAASvmC,GACjD,YAEA,IAAI2xB,GACAljB,EAAS,OACTrO,GACI8O,MACIsI,UAAU,EACVD,UAAU,EACVyI,iBAAiB,GAErB/Z,SAAU,KACVjY,IAAK,SAAS4B,EAAK1B,MAEvBi5C,KACAC,GACIj9B,IAAK,SAAS7H,GACV,MAAOlC,GAAQ6F,UAI3Bpe,IAAG6B,OAAO0W,EAASJ,GAEnB2xB,EAAY9pC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGk5B,eAC/B6C,aAAc,mBACdM,cAAezV,GACfA,OAAQA,EACRQ,cAAem4B,EACftjB,oCAAoC,EACpC5U,KAAM9O,EAAQ8O,KACdlhB,IAAKoS,EAAQpS,IACb8kB,WAAY,SAASxQ,EAAI7G,EAAK8T,GAC1B,GAAI5b,GAAUwzC,EAAS7kC,SAEhB6kC,GAAS7kC,GAEZiN,EACA5b,EAAQK,QAAQyH,GAGhB9H,EAAQG,QAAQ2H,OAK5B5T,GAAG6B,OAAOxB,MACN4+C,SAAU,SAASxkC,EAAI7G,EAAKuK,EAAQsG,GAChC,GAAI3Y,GAAU,GAAI9L,IAAG+L,OAWrB,OATAwM,GAAQpS,IAAI,0CAA4CsU,GAExD6kC,EAAS7kC,GAAM3O,EAEfg+B,EAAUnN,cAAcliB,GACnBuiB,WAAW7e,GACXgf,YAAY1Y,GACZ4W,KAAKznB,GAEH9H,MCjEnB9L,GAAGw/C,YAAc,SAASrnC,GACtB,YAoBA,SAASsnC,GAAmB9/B,EAAO+/B,GAE/B,GAAIC,GAAe13C,MAAMvB,UAAUwB,MAAMtB,KAAK+Y,EAE9CpH,GAAQiO,UAAUo5B,QAAQ,WAAajgC,EAAM5Z,OAAS,mBACtD25C,EAAeG,cAAa,GAC5BtnC,EAAQiO,UAAUs5B,+BAA+BH,EAAcD,EAAeK,cAGlF,QAASC,GAAiB/mB,GACtB,GAAIgnB,GAAoB,GAAIjgD,IAAG+L,OAoD/B,OAlDIktB,GAAMxwB,OACNwwB,EAAMrZ,KAAK,SAASA,GAChB,GAAI7d,GAAOk3B,EAAMl3B,KACbm+C,EAAWjnB,EAAMinB,SACjBC,EAAwBD,EAASv6C,QAAQ5D,EAG7Cm+C,GAAWA,EAAShuC,OAAO,EAAGiuC,GAGH,MAAvBD,EAASnwC,OAAO,KAChBmwC,EAAWA,EAAShuC,OAAO,IAG/B0N,EAAKwgC,OAASF,EACdG,EAAan9C,KAAK0c,GAClBqgC,EAAkBh0C,WAEtB,SAASq0C,GACL/nC,EAAQiO,UAAUo5B,QAAQ,oBAAsB3mB,EAAMinB,SAAW,sBAAwBI,EAAUtwB,KAAO,IAAK,SAC/GiwB,EAAkB9zC,YAGjB8sB,EAAMsnB,aACXC,EAAoBvnB,GAAO7hB,KACvB,SAAwBoD,GACpB,GAAIimC,GAAcjmC,EAAQzU,MAE1B/F,IAAG+C,KAAKyX,EAAS,SAASxX,EAAKi2B,GAC3B+mB,EAAiB/mB,GAAOphB,KAAK,WACzB4oC,GAAe,EAEK,IAAhBA,GACAR,EAAkBh0C,cAKzBuO,EAAQzU,QACTk6C,EAAkBh0C,WAI1B,SAAqBq0C,GACjB/nC,EAAQiO,UAAUo5B,QAAQ,oBAAsB3mB,EAAMinB,SAAW,sBAAwBI,EAAUtwB,KAAO,IAAK,SAC/GiwB,EAAkB9zC,YAKvB8zC,EAIX,QAASO,GAAoBvnB,EAAO2f,EAAQ8H,EAAcC,GACtD,GAAI70C,GAAU60C,GAAmB,GAAI3gD,IAAG+L,QACpC60C,EAAYhI,GAAU3f,EAAM4nB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqBtmC,GACjB,GAAIumC,GAAaL,EAAeA,EAAatwC,OAAOoK,GAAWA,CAE3DA,GAAQzU,OACRujB,WAAW,WACPk3B,EAAoBvnB,EAAO2nB,EAAWG,EAAYj1C,IACnD,GAGHA,EAAQG,QAAQ80C,IAIxBj1C,EAAQK,SAGLL,EAGX,QAASk1C,GAAmBz2C,EAAcm1C,GACtC,GAAIuB,MACAC,EAA4B,GAAIlhD,IAAG+L,OA4CvC,OA1CAwM,GAAQiO,UAAU26B,yBAClBzB,EAAeG,cAAa,GAExBt1C,EAAaoV,MAAM5Z,OAAS,IAAMwS,EAAQ6oC,oBAC1C7oC,EAAQiO,UAAUs5B,mCAClBvnC,EAAQiO,UAAU66B,UAAU,oBAAqB,IACjD3B,EAAeG,cAAa,GAC5BqB,EAA0B/0C,YAG1Bk0C,KAEIrgD,GAAGsK,sBAAsBC,GACzBvK,GAAG+C,KAAKwH,EAAaC,MAAO,SAASxH,EAAKsE,GACtC,GAAI2xB,GAAQ3xB,EAAKmD,kBAEbwuB,KAEIA,EAAMxwB,OACN43C,EAAan9C,KAAKoE,EAAKq1C,aAIvBsE,EAAsB/9C,KAAK88C,EAAiB/mB,GAAOphB,KAAK,WACpDopC,EAAsB/e,MACe,IAAjC+e,EAAsBl7C,QACtBm7C,EAA0Bj1C,gBAQ9Co0C,EAAe91C,EAAaoV,MAGK,IAAjCshC,EAAsBl7C,QACtBm7C,EAA0Bj1C,WAI3Bi1C,EAGX,QAASI,GAAcC,GACnB,GAAIC,GAAW,GAAIxhD,IAAGyhD,gBAClBC,sBAAuBA,EACvBzhD,QAASshD,EACTI,QAAS,SAASzyC,GACdlP,GAAGuhD,GAAUl/C,SAASkW,EAAQwR,QAAQ63B,YACtC1yC,EAAE2yC,mBAENC,sBAAuB,SAAS5yC,GAC5BlP,GAAGuhD,GAAUj/C,YAAYiW,EAAQwR,QAAQ63B,aAE7CG,OAAQ,SAAS7yC,GACb8xC,EAAmB9xC,EAAE3E,aAAci3C,GAAUpqC,KACzC,WACIqoC,EAAmBY,EAAcmB,IAErC,WACIjpC,EAAQiO,UAAUo5B,QAAQ,sEAAuE,aAcjH,OARAtmC,GAAe3G,YAAY,WACvB6uC,EAAShvC,YAGbxS,GAAGuhD,GAAUz9C,aAAak+C,IAA2BhiD,GAAGuhD,GAAUrhD,OAElE+hD,EAAgB/+C,KAAKs+C,GAEdA,EAGX,QAASU,GAAWC,GAChB,GAAIC,EASJ,OAPApiD,IAAG+C,KAAKo/C,EAAU53C,aAAa83C,MAAO,SAASxyC,EAAK5M,GAChD,GAAY,UAARA,EAEA,MADAm/C,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBpzC,GACxB,MAAIlP,IAAGqO,WACKa,EAAEqzC,cAGVviD,GAAGiO,SACIiB,EAAE0rC,EAAI,GAAK1rC,EAAEszC,EAAI,EAGb,IAARtzC,EAAE0rC,GAAmB,IAAR1rC,EAAEszC,EAG1B,QAASC,KACL,GAAIC,GAAYnqC,EAAQoqC,iBAEpBC,EAAqB,WACjBt5B,WAAW,WACPtpB,GAAG+C,KAAK2/C,EAAW,SAAS1/C,EAAKw+C,GAC7BxhD,GAAGwhD,GAAU19C,aAAak+C,IAA2BhiD,GAAGwhD,GAAUthD,OAClEF,GAAGwhD,GAAUl/C,YAAYiW,EAAQwR,QAAQ63B,eAE9C,IAGX5hD,IAAG+C,KAAK2/C,EAAW,SAAS1/C,EAAKw+C,GAC7B,GAAI9B,GAAiB4B,EAAcE,EAG/BkB,GAAU38C,QAAU/F,GAAGkT,kBAAkB+C,UACzCqD,EAAehZ,OAAOuJ,SAAU,YAAa,SAASqF,IAC7CwwC,EAAeG,gBAAkBqC,EAAWhzC,IAC7ClP,GAAG+C,KAAK2/C,EAAW,SAAS1/C,EAAKw+C,GAGzBA,YAAoBqB,cACpB7iD,GAAGwhD,GAAU19C,aAAak+C,IAE1BhiD,GAAGwhD,GAAUlgD,KAAKlB,QAAS,gBAQnDkZ,EAAehZ,OAAOuJ,SAAU,YAAa,SAASqF,GAC9CozC,EAAmBpzC,IACnB0zC,MAORtpC,EAAehZ,OAAON,GAAG6J,UAAUzG,WAAW,GAAI,aAAc,SAAS8L,GACrE0zC,MAGJtpC,EAAehZ,OAAOuJ,SAAU,OAAQ,SAASqF,GAC7CA,EAAED,iBACF2zC,MAGJtpC,EAAehZ,OAAOuJ,SAAU63C,EAAuBkB,GAnR3D,GAAIrqC,GACAmpC,EAAwB,eACxBM,EAAyB,mBACzBC,KACA5B,KACA/mC,EAAiB,GAAItZ,IAAGsS,cAE5BiG,IACIoqC,oBACAvB,oBAAoB,EACpBr3B,SACI63B,WAAY,MAEhBp7B,UAAW,GAAIxmB,IAAGw/C,YAAYh5B,WAGlCxmB,GAAG6B,OAAO0W,EAASJ,GAAG,GAsQtBsqC,IAEAziD,GAAG6B,OAAOxB,MACNyiD,mBAAoB,SAAS7iD,GACzBsY,EAAQoqC,iBAAiBz/C,KAAKjD,GAC9BqhD,EAAcrhD,IAGlB8iD,eAAgB,SAAS9iD,GACrB,GAAI6Q,GACAkyC,EAAMzqC,EAAQoqC,gBAElB,KAAK7xC,IAAKkyC,GACN,GAAIA,EAAIlyC,KAAO7Q,EACX,MAAO+iD,GAAIzmC,OAAOzL,EAAG,IAKjC0B,QAAS,WACL8G,EAAe9G,UACfxS,GAAG+C,KAAKk/C,EAAiB,SAASj/C,EAAKw+C,GACnCA,EAAShvC,gBAMzBxS,GAAGw/C,YAAYh5B,UAAY,WACvB,YAEA,QACI26B,uBAAwB,aACxBrB,+BAAgC,SAASngC,EAAOsjC,KAChD5B,UAAW,SAASrxB,EAAMkzB,GACtBljD,GAAGmG,IAAI,2BAA6B6pB,EAAO,2BAA6BkzB,EAAiB,IAAK,UAElGtD,QAAS,SAASx5C,EAASC,GACvBrG,GAAGmG,IAAIC,EAASC,MAK5BrG,GAAGyhD,eAAiB,SAAStpC,GACzB,YAiBA,SAASgrC,KACL,MAAOnjD,IAAGiO,UAAajO,GAAGqO,WAAarO,GAAGsO,UAG9C,QAAS80C,GAAmBl0C,GAEnBm0C,IAGGF,EACA7pC,EAAehZ,OAAOuJ,SAAU,WAAY,SAASqF,GACjDA,EAAED,mBAGNqK,EAAehZ,OAAOuJ,SAAU,WAAY,SAASqF,GAC7CA,EAAE3E,eACF2E,EAAE3E,aAAa+4C,WAAa,OAC5Bp0C,EAAED,oBAKdo0C,GAAsB,GAI9B,QAASE,GAAgBr0C,GAGrB,IAAKlP,GAAGkT,kBAAkB+C,SACtB,OAAO,CAGX,IAAIutC,GAAYC,EAAKv0C,EAAE3E,aAEvBm5C,EAAW1jD,GAAGiO,QAQd,OADAu1C,MAAaxjD,GAAGyN,OAAQzN,GAAGkT,kBAAkB+C,WAAuC,SAArBwtC,EAAGE,cAC3DF,GAAMD,IAAeC,EAAG9jC,QAAW+jC,GAAYD,EAAGpB,MAAMvhD,UAAY2iD,EAAGpB,MAAMvhD,SAAS,UAGjG,QAAS8iD,GAAoBC,GAIzB,MAHmB1/C,UAAf0/C,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiBp6C,SAASq6C,YAAY,SACtCD,EAAeE,UAAU5rC,EAAQmpC,uBAAuB,GAAM,GAJlE,GAAIuC,EAOJ,IAAI/+C,OAAOk/C,YACP,IACIH,EAAiB,GAAIG,aAAY7rC,EAAQmpC,uBAE7C,MAAOnM,GACHyO,QAIJA,IAGJn6C,UAASw6C,cAAcJ,GAG3B,QAASK,KACLhrC,EAAehZ,OAAOL,EAAS,WAAY,SAASiP,GAChD,GAAKq0C,EAAgBr0C,GAArB,CAMA,GAAIq1C,GAASvkD,GAAGyN,MAAQzN,GAAGkT,kBAAkB+C,SAAW,KAAO/G,EAAE3E,aAAao5C,aAC/D,UAAXY,GAAgC,aAAXA,EACrBr1C,EAAE3E,aAAa+4C,WAAa,OAE5Bp0C,EAAE3E,aAAa+4C,WAAa,OAGhCp0C,EAAE2yC,kBACF3yC,EAAED,oBAGNqK,EAAehZ,OAAOL,EAAS,YAAa,SAASiP,GACjD,IAAK00C,IAAuB,CACxB,IAAKL,EAAgBr0C,GACjB,MAEJqJ,GAAQopC,QAAQzyC,MAIxBoK,EAAehZ,OAAOL,EAAS,YAAa,SAASiP,GACjD,GAAKq0C,EAAgBr0C,GAArB,CAIAqJ,EAAQ8b,QAAQnlB,EAEhB,IAAIqzC,GAAgB14C,SAAS26C,iBAAiBt1C,EAAEu1C,QAASv1C,EAAEw1C,QAEvD1kD,IAAGK,MAAMS,SAASyhD,IAItBhqC,EAAQupC,sBAAsB5yC,MAGlCoK,EAAehZ,OAAOL,EAAS,OAAQ,SAASiP,GAC5C,IAAK00C,IAAuB,CACxB,IAAKL,EAAgBr0C,GACjB,MAGJA,GAAED,iBACFC,EAAE2yC,kBACFtpC,EAAQwpC,OAAO7yC,GAEf60C,OAjJZ,GACIxrC,GAAStY,EAAS6jD,EAAaT,EAD/B/pC,EAAiB,GAAItZ,IAAGsS,cAG5BiG,IACItY,QAAS,KACT0hD,QAAS,SAASzyC,KAClBmlB,QAAS,SAASnlB,KAElB4yC,sBAAuB,SAAS5yC,KAChC6yC,OAAQ,SAAS7yC,MAGrBlP,GAAG6B,OAAO0W,EAASJ,GACnBlY,EAAUsY,EAAQtY,QAyIlBmjD,IACAkB,IAEAtkD,GAAG6B,OAAOxB,MACNw/C,aAAc,SAASgE,GACnB,MAAOD,GAAoBC,IAG/BrxC,QAAS,WACL8G,EAAe9G,WAGnButC,WAAY,WACR,MAAO9/C,OCvelB,WACG,YAEAD,IAAG2kD,aACCrmC,gBAAiB,SAASC,GACtBle,KAAKukD,QAAQl+C,UAAU4X,gBAAgBjO,MAAMhQ,KAAM8H,WACnD9H,KAAKwkD,YAAYC,iBAGrBzkC,iBAAkB,WACdhgB,KAAKukD,QAAQl+C,UAAU2Z,iBAAiBhQ,MAAMhQ,KAAM8H,WACpD9H,KAAKwkD,YAAYE,cAGrBC,iBAAkB,SAAS/kD,GACvBI,KAAK4kD,MAAQ5kD,KAAK4kD,KAAKnC,mBAAmB7iD,IAG9CilD,oBAAqB,SAASjlD,GAC1B,GAAII,KAAK4kD,KACL,MAAO5kD,MAAK4kD,KAAKlC,eAAe9iD,IAIxCklD,gBAAiB,SAAS1qC,GACtB,IAAKpa,KAAKwkD,YAAYO,gBAAgB3qC,GAClC,MAAOpa,MAAKwkD,YAAYQ,iBAAiB5qC,IAIjDN,MAAO,WACH9Z,KAAKukD,QAAQl+C,UAAUyT,MAAM9J,MAAMhQ,KAAM8H,WACzC9H,KAAKwkD,YAAY1qC,SAEZ9Z,KAAK0e,SAAS2E,QAAUrjB,KAAKwkD,YAAY5iC,cAC1C5hB,KAAK+sB,iBAAmB/sB,KAAKkpB,qBACzBtpB,QAASI,KAAKwkD,YAAY5iC,YAC1BzJ,MAAOnY,KAAK0e,SAASrb,KAAK2mB,iBAC3BvQ,eAGHzZ,KAAK4kD,OACL5kD,KAAK4kD,KAAKzyC,UACVnS,KAAK4kD,KAAO5kD,KAAKilD,qBAGrBjlD,KAAKklD,mBAAqB,EAC1BllD,KAAKmlD,uBAAyB,EAE9BnlD,KAAKolD,mCAGTjgC,QAAS,SAAS/K,EAAImC,GAClB,GAAI8oC,GAAoBrlD,KAAK0e,SAAS0R,eAAe7T,EAErDvc,MAAKukD,QAAQl+C,UAAU8e,QAAQnV,MAAMhQ,KAAM8H,WAC3C9H,KAAKwkD,YAAYc,eAAelrC,EAAIirC,IAGxCriC,YAAa,SAAS5I,GAClB,GAAI2sB,GAAS/mC,KAAKukD,QAAQl+C,UAAU2c,YAAYhT,MAAMhQ,KAAM8H,UAG5D,OADAi/B,IAAU/mC,KAAKwkD,YAAYe,aAAanrC,GACjC2sB,GAGX9mB,eAAgB,SAAS7F,GACrB,GAAIorC,GAAYxlD,KAAKukD,QAAQl+C,UAAU4Z,eAAejQ,MAAMhQ,KAAM8H,UAGlE,OADA09C,IAAaxlD,KAAKwkD,YAAYiB,gBAAgBrrC,GACvCorC,GAGXE,MAAO,SAASC,GACZ,MAAO3lD,MAAKwkD,YAAYoB,UAAUD,IAGtCE,cAAe,SAAShlC,GACpB,GAAItB,GAAOvf,KAAKuhB,QAAQV,EAExB,OAAOtB,GAAKumC,eAOpBnmD,GAAGomD,cACClkC,WAAY,SAAS5J,GACjB,GAAIoL,GAASrjB,KAAKukD,QAAQl+C,UAAUwb,WAAW7R,MAAMhQ,KAAM8H,UAQ3D,OANKub,IACGpL,IAAajY,KAAK+sB,mBAClB1J,EAASrjB,KAAKwkD,YAAY5iC,aAI3ByB,GAGX2iC,gBAAiB,SAASnlC,GACtB7gB,KAAKwkD,YAAYyB,WAAWplC,IAGhCukC,gCAAiC,WAC7BplD,KAAKkmD,yBAA2BvmD,GAAGwmD,yBAA2BnmD,KAAKomD,6BAInEpmD,KAAKqmD,wBAA0B1mD,GAAGqO,UAE9BhO,KAAKsmD,2BAELtmD,KAAKumD,sBAAwBvmD,KAAKwmD,0BAClCxmD,KAAKymD,6BAA+BzmD,KAAK0mD,iCACzC1mD,KAAK2mD,2BAA6B3mD,KAAK4mD,iCAI/C3B,kBAAmB,WACf,GAAI7sC,GAAOpY,KACPsiD,EAAmBtiD,KAAK0e,SAASmoC,YAAYC,eAC7CC,EAAa/mD,KAAKwkD,YAClBwC,EAAkBD,EAAWE,aAIjC,OAFAD,IAAmB1E,EAAiBz/C,KAAKmkD,GAElC,GAAIrnD,IAAGw/C,aACVmD,iBAAkBA,EAClBvB,mBAAoB/gD,KAAK0e,SAAShV,SAClCggB,SACI63B,WAAYvhD,KAAK0e,SAASgL,QAAQ63B,YAEtCp7B,WACI26B,uBAAwB,WACpBiG,EAAWG,sBAEfzH,+BAAgC,SAASngC,EAAOsjC,GAC5CmE,EAAWI,qBAEXxnD,GAAG+C,KAAK4c,EAAO,SAAS3c,EAAK4c,GACzBA,EAAKumC,aAAelD,IAGpBtjC,EAAM5Z,QACN0S,EAAK4F,SAASsB,EAAO,KAAM,OAGnC0hC,UAAW,SAASrxB,EAAMy3B,GACtBhvC,EAAKmN,WAAWoK,EAAMy3B,IAE1B7H,QAAS,SAASx5C,EAASC,GACvBoS,EAAKtS,IAAIC,EAASC,QAMlCogD,2BAA4B,WACxB,GAAIhuC,GAAOpY,IAEX,OAAO,IAAIL,IAAGwmD,yBACVY,WAAY/mD,KAAKwkD,YAEjB1+C,IAAK,SAASC,EAASshD,GACnBjvC,EAAKtS,IAAIC,EAASshD,IAGtBC,aAAc,SAASzmC,GACnBzI,EAAKmI,WAAWM,IAGpBiK,SAAU,SAASjK,GACfzI,EAAKuH,OAAOkB,IAGhB0mC,QAAS,SAAS1mC,GACdzI,EAAK0L,MAAMjD,IAGf2mC,QAAS,SAAS3mC,GACdzI,EAAK4K,YAAYnC,IAGrB4mC,WAAY,SAAS5mC,GACjBzI,EAAK6H,eAAeY,IAGxB6mC,UAAW,SAAS7mC,GAChB,MAAOzI,GAAKiI,QAAQQ,OAKhCylC,uBAAwB,WAEpB,MAAOtmD,MAAKwkD,YAAYmD,2BAChB3nD,KAAK0e,SAASuQ,YACftvB,GAAGioD,sBACHjoD,GAAGkoD,2BACHloD,GAAGkoD,2BAGdC,qBAAsB,WAClB,GAAI1vC,GAAOpY,KACP+mD,EAAa/mD,KAAKwkD,WAEtB,QACIuC,WAAYA,EACZjhD,IAAK,SAASC,EAASshD,GACnBjvC,EAAKtS,IAAIC,EAASshD,IAEtBU,kBAAmB,SAASlnC,GACxB,MAAOzI,GAAKiK,YAAYjI,GAAIyG,IAASnG,QAEzCgtC,UAAW,SAAS7mC,GAChB,MAAOzI,GAAKiI,QAAQQ,IAExBmnC,UAAW,SAAS5tC,EAAImC,GACpBnE,EAAK+M,QAAQ/K,EAAImC,IAErB0rC,sBAAuB,SAAS7tC,EAAI8tC,GAChC,GAAIC,GAAUxoD,GAAGonD,EAAWqB,aAAahuC,IACrCiuC,EAAkB1oD,GAAGonD,EAAW/B,iBAAiB5qC,GAEjD8tC,IACAC,EAAQnmD,SAAS,cACjB+kD,EAAWuB,aAAaluC,GACxB2sC,EAAWwB,aAAanuC,KAGxB+tC,EAAQlmD,YAAY,cACpB8kD,EAAWyB,aAAapuC,GACxB2sC,EAAW0B,aAAaruC,IAI5BiuC,EAAgBrmD,SAAS,WAAWC,YAAY,cAK5D8mB,sBAAuB,SAAS3O,EAAI4B,EAAWD,GAC3C/b,KAAKukD,QAAQl+C,UAAU0iB,sBAAsB/Y,MAAMhQ,KAAM8H,WAErD9H,KAAKsmD,0BAEDtmD,KAAKwkD,YAAYQ,iBAAiB5qC,IAAO2B,IAAcpc,GAAG+a,OAAOqC,YACjE/c,KAAKwkD,YAAYkE,qBAAqBtuC,GACtCpa,KAAKwkD,YAAY+D,aAAanuC,IAIlC4B,IAAcrc,GAAG+a,OAAO2C,iBAAmBtB,IAAcpc,GAAG+a,OAAO0C,WACnEpd,KAAKwkD,YAAYmE,UAAUvuC,GAC3Bpa,KAAKwkD,YAAYoE,cAAcxuC,GAC/Bza,GAAGK,KAAKwkD,YAAYQ,iBAAiB5qC,IAAKnY,YAAYjC,KAAK6oD,SAASC,WAE/D/sC,IAAcpc,GAAG+a,OAAO6C,eAC7Bvd,KAAKwkD,YAAYuE,UAAU3uC,IAInCssC,+BAAgC,WAC5B,GAAIrrC,GAAO1b,GAAG6B,UAAWxB,KAAK8nD,uBAE9B,OAAO,IAAInoD,IAAGqpD,4BAA4B3tC,IAG9CurC,6BAA8B,WAC1B,GAAIvrC,GAAO1b,GAAG6B,UAAWxB,KAAK8nD,uBAE9B,OAAO,IAAInoD,IAAGkoD,0BAA0BxsC,IAG5CmrC,wBAAyB,WACrB,GAAInrC,GAAO1b,GAAG6B,UAAWxB,KAAK8nD,uBAE9B,OAAO,IAAInoD,IAAGioD,qBAAqBvsC,IAGvCsX,eAAgB,SAASvY,GACrBpa,KAAKukD,QAAQl+C,UAAUssB,eAAe3iB,MAAMhQ,KAAM8H,WAClD9H,KAAKwkD,YAAYyE,YAAY7uC,IAGjCsW,eAAgB,SAASe,EAAYC,GACjC1xB,KAAKukD,QAAQl+C,UAAUqqB,eAAe1gB,MAAMhQ,KAAM8H,WAClD9H,KAAKwkD,YAAY0E,sBAGrB32B,UAAW,SAASnY,EAAI1Y,GACpB,GAAI6d,GAAOvf,KAAKuhB,QAAQnH,EAEpBmF,IAAQA,EAAKwgC,QAAU//C,KAAK0e,SAASmoC,YAAYsC,sBACjDnpD,KAAKsjB,aAAauF,YAAYzO,GAC1BgvC,OAAQ7pC,EAAKwgC,SAIrB//C,KAAKukD,QAAQl+C,UAAUksB,UAAUviB,MAAMhQ,KAAM8H,WAC7C9H,KAAKqpD,WAAWjvC,EAAI1Y,IAIxB+wB,aAAc,SAASrY,GAEfpa,KAAKsmD,2BACLtmD,KAAKwkD,YAAYkE,qBAAqBtuC,GACtCpa,KAAKwkD,YAAYiE,aAAaruC,GAGzBpa,KAAKqmD,wBACNrmD,KAAK2mD,2BAA2B2C,WAAWtpD,KAAKwkD,YAAY4D,aAAahuC,MAMrFuQ,YAAa,SAASvQ,EAAI1Y,EAAM+oB,EAAQC,GACpC1qB,KAAKukD,QAAQl+C,UAAUskB,YAAY3a,MAAMhQ,KAAM8H,WAE/C9H,KAAKwkD,YAAY+E,eAAenvC,EAAIqQ,EAAQC,GAE9B,IAAVA,GAAoD,MAArCppB,KAAKC,MAAMkpB,EAASC,EAAQ,MAC3C1qB,KAAKwkD,YAAYgF,WAAWpvC,GAC5Bpa,KAAKwkD,YAAYuE,UAAU3uC,GAC3Bpa,KAAKwkD,YAAYiF,aAAarvC,GAC9Bpa,KAAKwkD,YAAYoE,cAAcxuC,EAAIpa,KAAK0e,SAASrb,KAAKqmD,oBAGtD1pD,KAAK2pD,iBAAiBvvC,IAItBpa,KAAK2pD,iBAAiBvvC,EAAIqQ,EAAQC,IAI1CwI,iBAAkB,SAASzI,EAAQC,GAC/B1qB,KAAKukD,QAAQl+C,UAAU6sB,iBAAiBljB,MAAMhQ,KAAM8H,WACpD9H,KAAKwkD,YAAY5I,oBAAoBnxB,EAAQC,IAGjDG,YAAa,SAASzQ,EAAI1Y,EAAMY,EAAQiR,GAMpC,QAASq2C,GAAetnD,GAGfmd,IAILsnC,EAAW6B,cAAcxuC,GAEzBza,GAAG8f,GAAexd,YAAYmW,EAAKywC,SAASC,UAC5C/B,EAAW0C,aAAarvC,GAEpBhC,EAAKiK,YAAYjI,GAAIA,IAAKM,SAAW/a,GAAG+a,OAAO6C,eAC/CwpC,EAAWyC,WAAWpvC,GAE1B2sC,EAAWkC,YAAY7uC,GAEnB9X,EAAOsJ,QACPwM,EAAKyxC,sBAAsBzvC,IAG3Bza,GAAG8f,GAAezd,SAASoW,EAAKywC,SAASiB,MACzC/C,EAAWgD,WAAW3vC,GAElB2sC,EAAWiD,oBAAsB5xC,EAAK+K,gBAAgB/I,KACtDza,GAAG8f,GAAezd,SAASoW,EAAKywC,SAASpN,WACzCsL,EAAWkD,UAAU7vC,IAEzBhC,EAAK8xC,2BAA2B9vC,EAAI9X,KAjC5C,GAAI6nD,GAAenqD,KAAKukD,QAAQl+C,UAAUwkB,YAAY7a,MAAMhQ,KAAM8H,WAC9Di/C,EAAa/mD,KAAKwkD,YAClB/kC,EAAgBsnC,EAAW/B,iBAAiB5qC,GAC5ChC,EAAOpY,IA6CX,OAVImqD,aAAwBxqD,IAAG+L,QAC3By+C,EAAa3yC,KAAK,SAAS4yC,GACvBR,EAAeQ,KAKnBR,EAAetnD,GAGZ6nD,GAGXN,sBAAuB,SAASzvC,GAC5B,GAAI2sC,GAAa/mD,KAAKwkD,WAElBxkD,MAAKovB,qBACL23B,EAAWsD,iBAAiBjwC,GAGhCza,GAAGonD,EAAW/B,iBAAiB5qC,IAAKpY,SAAShC,KAAK6oD,SAASj9C,SAE3D5L,KAAKsqD,sBAAsBlwC,IAG/B8Q,cAAe,SAAS9Q,GACpBpa,KAAKukD,QAAQl+C,UAAU6kB,cAAclb,MAAMhQ,KAAM8H,WACjD9H,KAAKwkD,YAAY+F,YAAYnwC,IAGjCgR,UAAW,SAAShR,EAAI1Y,GACpB,GAAIyoD,GAAenqD,KAAKukD,QAAQl+C,UAAU+kB,UAAUpb,MAAMhQ,KAAM8H,UAIhE,OAFA9H,MAAKwkD,YAAY+F,YAAYnwC,GAEtB+vC,GAGX5+B,eAAgB,SAASnR,EAAIkR,GACzBtrB,KAAKukD,QAAQl+C,UAAUklB,eAAevb,MAAMhQ,KAAM8H,WAI9CwjB,EAAU+L,UAAY,GAAKr3B,KAAK4f,SAAS4jB,YAAYppB,IACrDpa,KAAKwkD,YAAYgG,WAAWpwC,IAIpC4Q,UAAW,SAAS5Q,EAAI1Y,GACpB1B,KAAKukD,QAAQl+C,UAAU2kB,UAAUhb,MAAMhQ,KAAM8H,WAC7C9H,KAAKgmD,gBAAgB5rC,GAEU,IAA3Bpa,KAAKotB,mBACLptB,KAAKwkD,YAAY0E,sBAIzBn3B,mBAAoB,SAAS3X,GACzB,GAAIqwC,GAAoBC,EAASC,CAEjC3qD,MAAKukD,QAAQl+C,UAAU0rB,mBAAmB/hB,MAAMhQ,KAAM8H,WAEtD9H,KAAK4qD,gBAAgBxwC,GAEjBpa,KAAK0e,SAASoF,MAAM+mC,oBACpBJ,EAAqBzqD,KAAKijB,aAAa7I,GACvCswC,EAAU1qD,KAAK0e,SAASoF,MAAM2Q,gBAE9Bk2B,EAAY3qD,KAAK0e,SAASoF,MAAMgnC,cAAc5oD,QAAQ,gBAAiBuoD,GACvEE,EAAYA,EAAUzoD,QAAQ,eAAgBwoD,GAE9C1qD,KAAKwkD,YAAYoE,cAAcxuC,EAAIuwC,GACnChrD,GAAGK,KAAKwkD,YAAYQ,iBAAiB5qC,IAAKpY,SAAShC,KAAK6oD,SAASC,YAKzEt4B,qBAAsB,SAASpW,GAC3B,MAAIpa,MAAKukD,QAAQl+C,UAAUmqB,qBAAqBxgB,MAAMhQ,KAAM8H,YACxD9H,KAAKwkD,YAAYuG,cAAc3wC,GAC/Bza,GAAGK,KAAKwkD,YAAYQ,iBAAiB5qC,IAAKnY,YAAYjC,KAAK6oD,SAASiB,MACpE9pD,KAAKwkD,YAAYoE,cAAcxuC,GAC/Bpa,KAAKwkD,YAAY+F,YAAYnwC,GAC7Bpa,KAAK4qD,gBAAgBxwC,IACd,IAGPza,GAAGK,KAAKwkD,YAAYQ,iBAAiB5qC,IAAKpY,SAAShC,KAAK6oD,SAASpN,WACjEz7C,KAAKwkD,YAAYyF,UAAU7vC,IACpB,IAIfoG,gBAAiB,SAASpG,GACtB,GAAIwY,GAAoBjzB,GAAGgQ,KAAK3P,KAAKgrD,uBAAwBhrD,KAE7DA,MAAKukD,QAAQl+C,UAAUma,gBAAgBja,KAAKvG,KAAMoa,EAAIwY,IAG1Do4B,uBAAwB,SAAS5wC,EAAIG,EAAMsY,GACnC7yB,KAAK0e,SAAS6B,WAAW0qC,aACzBjrD,KAAKkrD,mBAAmBl7C,MAAMhQ,KAAM8H,WAGpC9H,KAAKmrD,mBAAmBn7C,MAAMhQ,KAAM8H,YAI5Cwf,kBAAmB,SAASlN,EAAI7G,EAAK8T,GACjCrnB,KAAKukD,QAAQl+C,UAAUihB,kBAAkBtX,MAAMhQ,KAAM8H,WAErD9H,KAAKwkD,YAAYyE,YAAY7uC,GAEzBiN,GACArnB,KAAKwkD,YAAYoE,cAAcxuC,EAAIpa,KAAK0e,SAAS6B,WAAW6qC,oBAC5DprD,KAAKwkD,YAAY6F,iBAAiBjwC,IAGlCpa,KAAKgmD,gBAAgB5rC,IAI7B+wC,mBAAoB,SAAS/wC,EAAIG,EAAMsY,GACnC7yB,KAAKwkD,YAAY6G,iBAAiBjxC,GAClCpa,KAAKwkD,YAAY+F,YAAYnwC,GAC7Bpa,KAAKwkD,YAAYoE,cAAcxuC,EAAIpa,KAAK0e,SAAS6B,WAAW+qC,oBAC5DtrD,KAAKgzB,eAAeC,WAAWjjB,MAAMhQ,KAAM8H,YAG/CojD,mBAAoB,SAAS9wC,EAAIG,EAAM2f,GAEnC,GAKI5qB,GALA0C,EAAWhS,KAAKqgB,QAAQjG,GACxBmxC,EAAiBvrD,KAAK0e,SAAS6B,WAAWgrC,eAAerpD,QAAQ,gBAAiB8P,GAElFw5C,GADOxrD,KAAK8iB,QAAQ1I,GACAtS,WACpBsQ,EAAOpY,IAGXsP,GAAStP,KAAK0e,SAAS+sC,YAAYF,GAE/B5rD,GAAGkX,iBAAiBvH,GACpBA,EAAOyH,KAAK,WACRqB,EAAK+yC,mBAAmBn7C,MAAMoI,EAAMozC,KAGnCl8C,KAAW,GAChB8I,EAAK+yC,mBAAmBn7C,MAAMoI,EAAMozC,IAI5CnC,WAAY,SAASjvC,EAAI1Y,EAAMgqD,GAC3B,GAAIC,GAGA9U,EAFA+U,EAAe,EACfC,EAAc7rD,KAAK4f,SAAS2jB,UAAUnpB,IAAOpa,KAAK0e,SAASrI,QAAQy1C,UAGnE9rD,MAAK0e,SAAS3e,QAAQgsD,eAClB/rD,KAAKklD,mBAAqB,GAAKllD,KAAKmlD,uBAAyB,IAC7DyG,EAAe5rD,KAAKmlD,uBAAyB,GAGjDwG,GACI9wC,MAAO+wC,IAIVF,IACG1rD,KAAK0e,SAASiX,8BAAgCh2B,GAAGkT,kBAAkBsC,eACnEnV,KAAKwkD,YAAYwH,gBAMhBhsD,KAAK0e,SAAShV,WACfmtC,EAAS72C,KAAKqiB,YAAYjI,GAAIA,IAE9Bpa,KAAKisD,mBAAqBjsD,KAAKisD,oBAAsBpV,EAAOn7B,aAExDm7B,EAAOn7B,eAAiB1b,KAAKisD,oBAAuBpV,EAAOn7B,eAC3D1b,KAAK4f,SAASC,YACd7f,KAAKksD,aACLlsD,KAAKisD,mBAAqB,QAKlCP,GACA1rD,KAAKwkD,YAAY2H,eAAe/xC,EAAIpa,KAAK0e,SAAS0R,eAAe1uB,GAAOiqD,EAAaE,GACrF7rD,KAAKwkD,YAAY4H,gBAAgBhyC,EAAIpa,KAAKqhB,eAAejH,IAAK,EAAMpa,KAAK0e,SAAS2tC,WAAWr0B,iBAG7Fh4B,KAAKwkD,YAAYppC,QAAQhB,EAAIpa,KAAK0e,SAAS0R,eAAe1uB,GAAOiqD,EAAaE,GAC9E7rD,KAAKwkD,YAAY8H,gBAAgBlyC,EAAIpa,KAAKuhB,QAAQnH,GAAKpa,KAAK0e,SAAS2tC,WAAWr0B,gBAGpFh4B,KAAKmlD,wBAA0B,GAE3BuG,GACC1rD,KAAK0e,SAAS3e,QAAQwsD,kBAAoB5sD,GAAGkT,kBAAkBsC,gBAEhEnV,KAAK2pD,iBAAiBvvC,IAI9B8xC,WAAY,WACRlsD,KAAKwkD,YAAYE,aACjB1kD,KAAKggB,oBAGT2pC,iBAAkB,SAASvvC,EAAIoyC,EAAYpR,GACvC,GAAI5/B,GAAOxb,KAAKuiB,QAAQnI,GACpBqyC,EAAiBzsD,KAAKosB,YAAY5Q,EAElCA,IAAQ,IACW1X,SAAf0oD,GAA0C1oD,SAAds3C,IAC5BqR,EAAiBzsD,KAAK0sD,gBAAgBF,EAAYpR,IAGtDp7C,KAAKwkD,YAAYhoC,WAAWpC,EAAIqyC,KAIxCC,gBAAiB,SAASC,EAAcvR,GAEpC,QAASnuC,GAAEvL,EAAMmuB,GAAe9pB,EAAUA,EAAQ7D,QAAQR,EAAMmuB,GADhE,GAAI9pB,GAAU/F,KAAK0e,SAASrb,KAAKupD,cAKjC,OAFA3/C,GAAE,YAAa3L,KAAKC,MAAMorD,EAAevR,EAAY,MACrDnuC,EAAE,eAAgBjN,KAAKosB,YAAYgvB,IAC5Br1C,GAGXmkD,2BAA4B,SAAS9vC,EAAI2W,GACrC,GAAI87B,GAAMC,EAAkBC,CAE5BF,GAAO7sD,KAAK0e,SAASsuC,wBAAwBH,KAC7CC,EAAmB9sD,KAAK0e,SAASsuC,wBAAwBF,iBAE5C,WAATD,GACAE,EAAgBh8B,EAAS+7B,GACpBC,IACDA,EAAgB/sD,KAAK0e,SAASrb,KAAK4pD,YAGvCjtD,KAAKwkD,YAAYoE,cAAcxuC,EAAI2yC,GAE/B/sD,KAAK0e,SAASsuC,wBAAwBE,eACtCltD,KAAKmtD,aAAa/yC,EAAI2yC,IAGZ,YAATF,EACL7sD,KAAKwkD,YAAYoE,cAAcxuC,EAAIpa,KAAK0e,SAASrb,KAAK4pD,YAExC,SAATJ,GACL7sD,KAAK8F,IAAI,0CAA4C+mD,EAAO,iBAAkB,SAItFM,aAAc,SAAS/yC,EAAI/W,GACvBrD,KAAKwkD,YAAYQ,iBAAiB5qC,GAAIjC,MAAQ9U,GAGlDunD,gBAAiB,SAASxwC,GACjBpa,KAAK0e,SAASiX,8BAA+Bh2B,GAAGkT,kBAAkBsC,eACnEnV,KAAKwkD,YAAYuF,WAAW3vC,IAIpCmL,WAAY,SAASoK,EAAMjuB,EAAMuF,GAC7B,GAAIlB,GAAU/F,KAAKukD,QAAQl+C,UAAUkf,WAAWvV,MAAMhQ,KAAM8H,UAC5D9H,MAAK0e,SAAS0uC,YAAYrnD,IAG9BmgB,YAAa,SAASngB,GAClB/F,KAAKukD,QAAQl+C,UAAU6f,YAAYlW,MAAMhQ,KAAM8H,WAC/C9H,KAAK0e,SAAS0uC,YAAYrnD,IAG9BsnD,kBAAmB,WACf,GAAIj1C,GAAOpY,IAEXA,MAAK0e,SAASyH,UAAU0B,gBAAkB,WACtC,GAAI9hB,GAAUqS,EAAKsG,SAASgJ,MAAM4lC,kBAC9BC,EAAan1C,EAAKsG,SAASgJ,MAAM9I,WAErC,OAAOxG,GAAKsG,SAAS8uC,WAAWznD,EAASwnD,KAIjDphC,oBAAqB,SAAS/R,EAAI1Y,GAC9B1B,KAAKklD,oBAAsB,EAC3BllD,KAAKukD,QAAQl+C,UAAU8lB,oBAAoBnc,MAAMhQ,KAAM8H,YAG3D4X,uBAAwB,SAASvV,EAAO2T,EAAQC,GAC5C/d,KAAKklD,mBAAqB/6C,EAAMzE,OAChC1F,KAAKmlD,uBAAyB,EAC9BnlD,KAAKukD,QAAQl+C,UAAUqZ,uBAAuB1P,MAAMhQ,KAAM8H,YAG9DwiD,sBAAuB,SAASzpC,GAC5B,GAAIgF,GAAe7lB,KAAKqhB,eAAeR,GACnC4sC,EAAaztD,KAAKqiB,YAAYjI,GAAIyG,IAASnG,MAE3C+yC,KAAe9tD,GAAG+a,OAAOgD,UACxBmI,IACD7lB,KAAK0e,SAAS2tC,WAAWqB,aAAaC,mBACrChuD,GAAGkT,kBAAkBkD,eAItB/V,KAAKwkD,YAAY4H,gBAAgBvrC,EAAQgF,EAAc7lB,KAAK0e,SAAS2tC,WAAWr0B,gBAIxF5Z,eAAgB,SAASsH,GACrB,GAAItL,GAAKpa,KAAKukD,QAAQl+C,UAAU+X,eAAepO,MAAMhQ,KAAM8H,UAO3D,OALA9H,MAAKqpD,WAAWjvC,EAAIpa,KAAKqgB,QAAQjG,IAAK,GACtCpa,KAAKwkD,YAAYyE,YAAY7uC,GAC7Bpa,KAAKwkD,YAAYgF,WAAWpvC,GAC5Bpa,KAAK6pD,sBAAsBzvC,GAEpBA,GAGX2R,SAAU,SAAS3R,EAAIqC,GACnBzc,KAAKukD,QAAQl+C,UAAU0lB,SAAS/b,MAAMhQ,KAAM8H,WAE5C9H,KAAKwkD,YAAYhoC,WAAWpC,EAAIpa,KAAKosB,YAAY3P,KAGrD4X,wBAAyB,WACrBr0B,KAAKwkD,YAAYC,gBACjBzkD,KAAKukD,QAAQl+C,UAAUguB,wBAAwBrkB,MAAMhQ,KAAM8H,gBC7sBvEnI,GAAGiuD,aAAe,SAAS91C,EAAGsS,GAC1B,YAEA,IAAIhS,GAAOpY,IAKXA,MAAKukD,QAAUn6B,EAAYzqB,GAAGyqB,GAAWsL,kBAAoB/1B,GAAG+1B,kBAChE11B,KAAKukD,QAAQv0C,MAAMhQ,KAAM8H,WAGzBnI,GAAG6B,OAAOxB,KAAK0e,UACX9e,QAAS,KAETyjB,OAAQ,KAERwqC,YAAa,KAEbhH,aACIC,kBACAqC,sBAAsB,GAG1B9lD,MACIupD,eAAgB,6BAChBK,WAAY,gBACZvD,mBAAoB,gBACpB3iB,OAAQ,UAGZ+mB,SAAU,cAEVpkC,SACIo/B,SAAU,qBACVrN,UAAW,sBACX7vC,QAAS,oBACTk+C,KAAM,iBACNiE,SAAU,cACVluD,KAAM,UACN0hD,WAAY,8BAGhByL,yBACIH,KAAM,UACNC,iBAAkB,QAClBI,eAAe,GAGnBl9B,UACIg+B,kBAAmB,6BACnBC,mBAAoB,kFAGxBnqC,OACI+mC,mBAAmB,EACnBC,cAAe,oCAGnBvqC,YACI0qC,cAAc,EACdM,eAAgB,8CAChBD,mBAAoB,cACpBF,mBAAoB,iBAIxBrrD,SACIwsD,kBAAkB,EAClBR,cAAc,GAGlBrkC,OACIwmC,eAAe,EACfZ,kBAAmB,0BAGvBjB,YACIr0B,cAAe,KACfm2B,SAAU,EACVT,cACIC,mBAAmB,EACnBS,iBAAkB,KAClBC,YAAa,MAEjBC,kBAAmB,KAGvBj4C,SACIy1C,YAAY,GAGhBsB,YAAa,SAASrnD,GAClB,MAAIqS,GAAKosC,YAAY+J,UAAU,SACpBn2C,EAAKosC,YAAYgK,WAAW,QAASzoD,OAG5CkjB,YAAW,WACPpkB,OAAO+rB,MAAM7qB,IACd,IAIX0lD,YAAa,SAAS1lD,GAClB,MAAIqS,GAAKosC,YAAY+J,UAAU,WACpBn2C,EAAKosC,YAAYgK,WAAW,UAAWzoD,GAGvClB,OAAO4pD,QAAQ1oD,IAI9BynD,WAAY,SAASznD,EAAS2oD,GAC1B,MAAIt2C,GAAKosC,YAAY+J,UAAU,UACpBn2C,EAAKosC,YAAYgK,WAAW,SAAUzoD,EAAS2oD,GAG/C7pD,OAAO8pD,OAAO5oD,EAAS2oD,MAGvC,GAGH/uD,GAAG6B,OAAOxB,KAAK0e,SAAU5G,GAAG,GAE5B9X,KAAKwkD,YAAc,GAAI7kD,IAAGivD,YACtB9oD,IAAKnG,GAAGgQ,KAAK3P,KAAK8F,IAAK9F,MACvB6uD,eAAgB7uD,KAAK0e,SAASovC,SAC9BgB,YAAa9uD,KAAK0e,SAAS9e,QAC3BmvD,gBAAiB/uD,KAAK0e,SAASmvC,YAC/BxqC,OAAQrjB,KAAK0e,SAAS2E,OACtB40B,eAAgBj4C,KAAKohB,gBACrBsI,SACI7pB,KAAMG,KAAK0e,SAASgL,QAAQ7pB,KAC5BkuD,SAAU/tD,KAAK0e,SAASgL,QAAQqkC,UAEpC/Z,QACIgb,UAAWhvD,KAAK0e,SAAS2tC,WAAW8B,SACpCG,kBAAmBtuD,KAAK0e,SAAS2tC,WAAWiC,mBAEhDZ,cACIuB,gBAAiBjvD,KAAK0e,SAAS2tC,WAAWqB,aAAaC,kBACvDuB,sBAAuBlvD,KAAK0e,SAAS2tC,WAAWqB,aAAaU,iBAC7De,oBAAqBnvD,KAAK0e,SAAS2tC,WAAWqB,aAAaW,aAE/DhrD,KAAMrD,KAAK0e,SAASrb,OAGpBrD,KAAK0e,SAAS0K,YAAYuH,mBAAqBhxB,GAAG6O,UAAY7O,GAAG+O,YACjE1O,KAAKwkD,YAAY4K,cAAcpvD,KAAK0e,SAASsR,SAASa,+BAEhDlxB,GAAGkT,kBAAkB2D,WAAcxW,KAAK0e,SAASsI,KAAKqI,WAAa1vB,GAAGkT,kBAAkB4D,WAC9FzW,KAAKwkD,YAAY4K,cAAcpvD,KAAK0e,SAASsR,SAASi+B,qBAGtDjuD,KAAKo1B,iBAELp1B,KAAKwkD,YAAY5W,SAEjB5tC,KAAK6oD,SAAW7oD,KAAK0e,SAASgL,SAEzB1pB,KAAK0e,SAAS2E,QAAUrjB,KAAKwkD,YAAY5iC,cAC1C5hB,KAAK+sB,iBAAmB/sB,KAAKkpB,qBACzBtpB,QAASI,KAAKwkD,YAAY5iC,YAC1BzJ,MAAOnY,KAAK0e,SAASrb,KAAK2mB,iBAC3BvQ,eAGPzZ,KAAKolD,kCAEDzlD,GAAGw/C,aAAex/C,GAAGkT,kBAAkB+C,WACvC5V,KAAK4kD,KAAO5kD,KAAKilD,qBAGjBjlD,KAAK0e,SAASgJ,MAAMD,eAAiBznB,KAAK0e,SAASgJ,MAAMwmC,gBACrDvuD,GAAG6nB,aACHxnB,KAAKqtD,oBAGLrtD,KAAK8F,IAAI,kCAAmC,UAIpD9F,KAAKklD,mBAAqB,EAC1BllD,KAAKmlD,uBAAyB,IAKtCxlD,GAAG6B,OAAO7B,GAAGiuD,aAAavnD,UAAW1G,GAAGge,eACxChe,GAAG6B,OAAO7B,GAAGiuD,aAAavnD,UAAW1G,GAAG8lB,gBAGxC9lB,GAAG6B,OAAO7B,GAAGiuD,aAAavnD,UAAW1G,GAAG2kD,aACxC3kD,GAAG6B,OAAO7B,GAAGiuD,aAAavnD,UAAW1G,GAAGomD,cC5LxCpmD,GAAGivD,WAAa,SAASvzC,GACrB,YAEA,IA4EIvV,GACAupD,EACAC,EACAC,EACA/tC,EACAiN,EACA+gC,EACAC,EAnFAC,EAAe,aACfC,EAAoB,cACpBC,EAA0B,cAC1BC,EAA8B,kBAE9BC,EAAqB,mBACrBC,EAAsB,oBACtBC,EAAoB,iBACpBC,EAAuB,oBACvBC,GACIC,QAAS3mD,SAAS4mD,yBAClBC,QAEJC,GAAmB,EACnBC,EAAsB,EACtBC,GAA+B,EAC/BC,KACAC,GAAmB,EACnBx4C,GACIpS,IAAK,KACLkuC,QACIgb,UAAW,EACXV,kBAAmB,KAEvBO,eAAgB,cAChBC,YAAa,KACbC,gBAAiB,KACjB1rC,OAAQ,KACR40B,eAAgB,KAChBvuB,SACI7pB,KAAM,UACNkuD,SAAU,eAEdL,cACIuB,iBAAiB,EACjBC,sBAAuB,KACvBC,oBAAqB,MAEzB9rD,MACI0jC,OAAQ,WAGhB4pB,GACIttC,OAAQ,4BACRutC,YAAa,2BACbC,mBAAoB,4BACpBC,cAAe,6BACfC,cAAe,6BACfC,eAAgB,wBAChBC,aAAc,4BACdC,SAAU,uBACVC,KAAM,+BACNC,KAAM,0BACNC,qBAAsB,qCACtBl7C,YAAa,2BACbm7C,0BAA2B,2CAC3BC,iBAAkB,iCAClBhyC,KAAM,0BACNiyC,QAAS,6BACTh2C,KAAM,0BACNmE,OAAQ,4BACRzJ,MAAO,2BACPu7C,eAAgB,8BAChBC,aAAc,4BACd5tC,MAAO,2BACP6tC,WAAY,iCACZC,kBAAmB,4BACnBC,aAAc,iCACdC,SAAU,oCACVC,eAAgB,8BAChBC,sBAAuB,sCACvBC,UAAW,yBAEfC,KACAC,EAAiC,GAAIxyD,IAAG+L,QACxC0mD,EAA+B,GAAIzyD,IAAG+L,QAatC2mD,EAA6B,WACzB,GAAIC,GAAmBp6C,EAAQw1C,aAAawB,sBACxCqD,EAAar6C,EAAQw1C,aAAayB,oBAClC9zC,GACI0F,QAAS2vC,EACTpvC,MAAOmuC,EAGXD,KACI8C,EACAp6C,EAAQ+/B,eAAex2B,SAAS6wC,EAAiB,GAAIjlB,OAAShyB,GAAMtE,KAChE,SAASy7C,GACLL,EAA+BvmD,QAAQ4mD,IAE3C,WACIL,EAA+BrmD,UAC/BhG,EAAI,wDAA0DwsD,EAAiB,WAKvFH,EAA+BrmD,UAG/BymD,EACAr6C,EAAQ+/B,eAAex2B,SAAS8wC,EAAY,GAAIllB,OAAShyB,GAAMtE,KAC3D,SAASy7C,GACLJ,EAA6BxmD,QAAQ4mD,IAEzC,WACIJ,EAA6BtmD,UAC7BhG,EAAI,gEAAkEysD,EAAY,WAK1FH,EAA6BtmD,YAOzC2mD,EAAoB,SAASR,GACzB,GAAIS,GAAsB,GAAI/yD,IAAG+L,OAwBjC,OAtBA0mD,GAA6Br7C,KAAK,SAAS4yB,GACvCgpB,EAA4BhpB,EAAKsoB,GAE5BA,EAAUxkB,IASXilB,EAAoB9mD,WARpBqmD,EAAUxkB,IAAM9D,EAAI8D,IACpBwkB,EAAUtmD,OAAS,WACfsmD,EAAUtmD,OAAS,KACnBinD,GAAKX,GACLS,EAAoB9mD,aAM7B,WAIC/L,EAAKoyD,GACLS,EAAoB9mD,YAGjB8mD,GAGXG,EAAqB,SAASz4C,EAAIhP,EAAMiQ,GACpC,GAAI42C,GAAYa,EAAa14C,EAK7B,OAHAtU,GAAI,gCAAkCsU,GACtChP,EAAK2nD,cAAgB34C,EAEdlC,EAAQ+/B,eAAex2B,SAASrW,EAAM6mD,EAAW52C,GAAMtE,KAC1D,WACIw5C,IACAqC,GAAKX,GACLC,EAAkB93C,GAAIxO,WAE1B,WACIsmD,EAAkB93C,GAAItO,UAIjBoM,EAAQw1C,aAAauB,iBACtB+D,EAA+B54C,EAAI63C,MAKnDgB,EAA4B,WACxB,GAAIxC,EAAqB/qD,OAAQ,CAC7B8qD,GAA+B,CAE/B,IAAI0C,GAAqBzC,EAAqBp+C,OAE1C6gD,GAAmBC,OACnBC,EAAkCF,GAGlCG,EAA+BH,OAInC1C,IAA+B,GAIvC8C,EAAY,SAASl5C,GACjB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBhxC,SAGtD6zC,EAAc,SAASp5C,GACnB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBc,iBAGtDgC,EAAY,SAASvzD,GACjB,MAAOqzD,GAAc/xC,EAAWmvC,EAAgBzwD,EAAO,YAG3DwzD,EAAY,SAASt5C,GACjB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBe,eAGtDiC,EAAoB,WAChB,MAAOJ,GAAc/xC,EAAWmvC,EAAgBoB,iBAGpD6B,EAAc,SAASx5C,GACnB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBkB,eAGtDtwC,EAAU,SAASnH,GACf,MAAO81C,GAAUG,IAAIj2C,IAAOza,GAAG8uB,GAAU3rB,gBAAgB6sD,EAAoBv1C,IAGjFtI,EAAc,SAASsI,GACnB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBpxC,OAGtDs0C,EAAW,SAASz5C,GAChB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBz6C,QAGtD49C,EAAc,SAAS15C,GAGnB,MAAU,OAANA,EACOm5C,EAAc/xC,EAAWmvC,EAAgBW,4BAC5CiC,EAAc/xC,EAAWmvC,EAAgBY,kBAI1CgC,EAAchyC,EAAQnH,GAAKu2C,EAAgBU,uBAC9CkC,EAAchyC,EAAQnH,GAAKu2C,EAAgBx6C,cAGnD49C,EAAW,SAAS35C,GAChB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgB7sC,QAGtDvB,EAAU,SAASnI,GACf,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBn1C,OAGtDw4C,EAAa,SAAS55C,GAClB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBa,UAGtD+B,EAAgB,SAAS1jD,EAASokD,GAC9B,MAAOpkD,IAAWlQ,GAAGkQ,GAAS/M,gBAAgBmxD,IAGlDnB,EAAe,SAAS14C,GACpB,MAAOo1C,IAAkB+D,EAAchyC,EAAQnH,GAAKu2C,EAAgBsB,YAGxEpyD,EAAO,SAASwuC,GACZA,GAAM1uC,GAAG0uC,GAAIrsC,SAASkW,EAAQwR,QAAQ7pB,OAM1C8yD,EAA8B,SAASpiC,EAAa0hC;AAChD,GAAIh8B,GAAW1F,EAAYzwB,MAAMm2B,SAC7BD,EAAYzF,EAAYzwB,MAAMk2B,SAE9BA,IAAaC,IAAag8B,EAAUnyD,MAAMm2B,WAAag8B,EAAUnyD,MAAMk2B,WACvEr2B,GAAGsyD,GAAWhxD,KACVg1B,SAAUA,EACVD,UAAWA,KAQvBg9B,EAAiC,SAAS54C,EAAI63C,GAC1C,GAAIiC,GAAahC,EAAkB93C,KAAO,GAAIza,IAAG+L,SAAUI,UACvDqoD,EAA2B,GAAIx0D,IAAG+L,OAqBtC,OAnBAymD,GAA+Bp7C,KAAK,SAAS4yB,GACzCuqB,EAAWn9C,KACP,WACIo9C,EAAyBvoD,WAE7B,WACI+mD,EAA4BhpB,EAAKsoB,GAEjCA,EAAUtmD,OAAS,WACfsmD,EAAUtmD,OAAS,KACnBwoD,EAAyBvoD,WAG7BqmD,EAAUxkB,IAAM9D,EAAI8D,IACpBmlB,GAAKX,OAKVkC,GAWXC,EAAsB,WAClB,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACAxT,EACA+Q,EACAF,EACA4C,EACAC,CAKJ,IAHA9uD,EAAI,oBAG0B,MAA1BoS,EAAQ22C,eACR,KAAM,IAAI1tD,OAAM,oDAIpB,IAAIxB,GAAGwH,SAAS+Q,EAAQ22C,gBAAiB,CAGrC,GAFAwF,EAAW7qD,SAAS86B,eAAepsB,EAAQ22C,gBAE1B,OAAbwF,EACA,KAAM,IAAIlzD,OAAMxB,GAAG8H,OAAO,0CAA2CyQ,EAAQ22C,gBAGjFyF,GAAaD,EAASnlD,cAErB,CACD,GAAyCpL,SAArCoU,EAAQ22C,eAAe3/C,UACvB,KAAM,IAAI/N,OAAM,gGAIpBmzD,GAAap8C,EAAQ22C,eAAe3/C,UA4ExC,GAzEAolD,EAAa30D,GAAG0H,QAAQitD,GACxBE,EAAiBhrD,SAASC,cAAc,OACxC+qD,EAAerjD,YAAYxR,GAAGoP,UAAUulD,IACxCM,EAAaj1D,GAAG60D,GAAgB1xD,gBAAgB6tD,EAAgBO,UAI5Dh5C,EAAQmL,SACRqxC,EAAgB/0D,GAAG60D,GAAgB1xD,gBAAgB6tD,EAAgBttC,QAC/DqxC,GACA/0D,GAAG+0D,GAAe3zD,UASrBpB,GAAGw/C,aAAgBx/C,GAAGkT,kBAAkB+C,WACzCm8C,EAAiBpyD,GAAG60D,GAAgB1xD,gBAAgB6tD,EAAgBoB,gBAChEA,GACApyD,GAAGoyD,GAAgBhxD,UAI3BmgD,EAAWvhD,GAAG60D,GAAgB1xD,gBAAgB6tD,EAAgBQ,MAI1DjQ,IAAavhD,GAAGw/C,cAChBr5C,EAAI,0BAA2B,QAC/BnG,GAAGuhD,GAAUngD,UAGZpB,GAAGkT,kBAAkB+C,SAajBjW,GAAGi1D,GAAYnxD,aAAassD,IAAwB7O,IACzDyT,EAAah1D,GAAGuhD,GAAUp+C,gBAAgB6tD,EAAgBmB,UAC1D6C,GAAch1D,GAAGg1D,GAAY5zD,WAb7B6zD,EAAWh7C,gBAAgBm2C,GAEvB7O,GAAYvhD,GAAGuhD,GAAUz9C,aAAaqsD,IAItCnwD,GAAGuhD,GAAUjgD,KACTlB,QAAS,UAWrBkyD,EAAYtyD,GAAG60D,GAAgB1xD,gBAAgB6tD,EAAgBsB,WAC1DzC,EAGIyC,IACLvB,EAAmB/uB,SAASswB,EAAUpuD,aAAa+rD,IAEnDc,EAAmBA,EAAmB,EAAIA,EAAmB,KAE7DjB,EAAc9vD,GAAGsyD,GAAWxuD,aAAaosD,IAPzCoC,GAAatyD,GAAGsyD,GAAWlxD,SAS/ByuD,EAAiBA,GAAkByC,EAEnC5C,EAAsB1vD,GAAG60D,GAAgBryD,WAAWwuD,EAAgBiB,mBAAmBlsD,OAAS,EAChG4pD,EAAsB3vD,GAAG60D,GAAgBryD,WAAWwuD,EAAgB7sC,OAAOpe,OAAS,EAEpF6uD,EAAe50D,GAAG60D,GAAgB1xD,gBAAgB6tD,EAAgBS,MAE9C,MAAhBmD,EACA,KAAM,IAAIpzD,OAAM,0DAapB,OAVAszD,GAAeF,EAAarlD,UAC5BqlD,EAAarlD,UAAY,GAGrBslD,EAAe/xD,qBAAqB,UAAUiD,QAC9C8D,SAASC,cAAc,UAG3B3D,EAAI,8BAGAgoD,SAAUnuD,GAAG0H,QAAQmtD,EAAetlD,WACpC2lD,aAAcl1D,GAAG0H,QAAQotD,KAIjCK,EAAc,SAASzmB,EAAIxzB,EAAO4T,GAC9B,GAAIsmC,GAAWtmC,EACXumC,EAAWD,EAAS9xD,UAEpB4X,GAAQ,IACRm6C,EAAWr1D,GAAGo1D,GAAUhyD,WAAW8X,GAAO1X,aAI9C4xD,EAASn0D,aAAaytC,EAAI2mB,IAG9B3B,EAAiC,SAASH,GACtC,GAAI94C,GAAK84C,EAAmB94C,GACxB66C,EAAgB/B,EAAmB+B,cACnCC,EAAqBD,GAAiBA,EAAclC,cACpDd,EAAYa,EAAa14C,GACzBiB,GACI4F,qBAAsBiyC,EAAmBjyC,qBACzCF,QAAS2vC,EACTx4B,QAAQ,EACR5W,OAAO,EAGX3hB,IAAGkT,kBAAkBkD,cACjBk8C,EACI/5C,EAAQ87B,OAAOgb,WAAa92C,EAAQ87B,OAAOgb,WAAauB,GACxDyC,EAA+B54C,EAAI63C,GACnCgB,KAGAR,EAAkBR,GAAWz6C,KAAK,WAC9B06C,EAAkB93C,GAAM,GAAIza,IAAG+L,QAE/BwmD,EAAkB93C,GAAI5C,KAAK,WACvByR,WAAWgqC,EAA2B/6C,EAAQ87B,OAAOsa,qBAM/B,MAAtB4G,EACAC,GAAiB/6C,EAAI86C,GAGrBrC,EAAmBz4C,EAAI66C,EAAe55C,KAOlD43C,IAGChB,IACLQ,EAAkBR,GAClBgB,MAIRG,EAAoC,SAASF,GACzC,GAAI94C,GAAK84C,EAAmB94C,GACxByL,EAAeqtC,EAAmBrtC,aAClCuvC,EAAiBlC,EAAmBkC,eACpCnD,EAAYa,EAAa14C,GACzBiB,GACI4F,qBAAsBiyC,EAAmBjyC,qBACzCK,MAAOmuC,EACP1uC,QAAS2vC,EAGjB,IAAIuB,EACA,GAAIpsC,EAAc,CACd,KAAI3N,EAAQ87B,OAAOgb,WAAa92C,EAAQ87B,OAAOgb,WAAauB,GASxD,MAJI6E,IACA3C,EAAkBR,GAGf/5C,EAAQ+/B,eAAex2B,SAASoE,EAAcosC,EAAW52C,GAAMtE,KAClE,WACI67C,GAAKX,GACL1B,IACAtnC,WAAWgqC,EAA2B/6C,EAAQ87B,OAAOsa,oBAGzD,WACI0E,EAA+B54C,EAAI63C,GACnChpC,WAAWgqC,EAA2B/6C,EAAQ87B,OAAOsa,oBAjB7D0E,GAA+B54C,EAAI63C,GACnCgB,QAsBJD,GAA+B54C,EAAI63C,GACnCgB,KAKZoC,GAAsB,SAASj7C,EAAIk7C,GAC/B,GAAIC,GAAMzB,EAAY15C,GAElBo7C,EAA4B,MAANp7C,EAAau2C,EAAgBY,iBAAmBZ,EAAgBx6C,WAEtFo/C,KAAQ51D,GAAG41D,GAAK9zD,SAAS+zD,KACzBD,EAAM51D,GAAG41D,GAAKzyD,gBAAgB0yD,IAG9BD,IACA51D,GAAG41D,GAAKt0D,KAAKgpC,MAAOqrB,EAAU,MAC9BC,EAAIrkD,aAAa,gBAAiBokD,KAI1C1C,GAAO,SAASvkB,GACZA,GAAM1uC,GAAG0uC,GAAIpsC,YAAYiW,EAAQwR,QAAQ7pB,OAG7Cs1D,GAAmB,SAASM,EAAmBC,GAC3C,GAAIC,GAAkB7C,EAAa2C,GAC/BG,EAAkB9C,EAAa4C,EAEnC5vD,GAAInG,GAAG8H,OAAO,qFAAsFguD,EAAmBC,EAAmBA,IAG1IxD,EAAkBwD,GAAmB3+C,KAAK,WACtCw5C,IACA2B,EAAkBuD,GAAmB7pD,UACrC9F,EAAInG,GAAG8H,OAAO,uEAAwEiuD,EAAmBD,IACzGE,EAAgBloB,IAAMmoB,EAAgBnoB,IACtCmlB,GAAK+C,IAET,WACIzD,EAAkBuD,GAAmB3pD,UAChCoM,EAAQw1C,aAAauB,iBACtB+D,EAA+ByC,EAAmBE,KAKlEh2D,IAAG6B,OAAO0W,EAASmD,GACnBvV,EAAMoS,EAAQpS,IAITnG,GAAGkT,kBAAkBkD,gBACtBmC,EAAQ87B,OAAOsa,kBAAoB,EACnCp2C,EAAQ87B,OAAOgb,UAAY,GAG/BxtC,EAAYtJ,EAAQ42C,YACpBU,EAA4C1rD,SAA3BoU,EAAQ+/B,eACzBsX,EAAe6E,IAEf/B,IAEA1yD,GAAG6B,OAAOxB,MACN4tC,OAAQ,WACJ9nC,EAAI,8BAEJyqD,EAAsB,EAEtB/uC,EAAUtS,UAAYqgD,EAAazB,SACnCjuD,EAAK8zD,KACL3zD,KAAK61D,oBACLpnC,EAAWvW,EAAQ62C,iBAAmBwE,EAAc/xC,EAAWmvC,EAAgBS,MAE/EtrD,EAAI,gCAGRspD,cAAe,SAASrpD,GACpB,GAAI+vD,GAAen2D,GAAGoP,UAAUhJ,EAChCyb,GAAUtS,UAAY,GACtBsS,EAAUrQ,YAAY2kD,IAG1Bh8C,MAAO,WACH9Z,KAAK4tC,UAGT8W,WAAY,WACRj2B,EAASvf,UAAY,IAGzB88C,cAAe,WACXsE,GAAmB,GAGvBl1C,QAAS,SAAShB,EAAI1Y,EAAMq0D,EAAaC,EAAaC,GAClD,GAIIC,GAJAC,EAASx2D,GAAGoP,UAAUwgD,EAAasF,cACnCuB,EAAa7C,EAAc4C,EAAQxF,EAAgBpxC,MACnDq1C,EAAarB,EAAc/xC,EAAWmvC,EAAgBO,UACtDzxC,EAAgBw2C,EAAQ/F,EAAUC,QAAU1hC,CAG5CwnC,KACA/F,EAAUG,IAAIj2C,GAAM+7C,GAGxBx2D,GAAGw2D,GAAQn0D,SAAS2tD,EAAoBv1C,GACxCw6C,EAAWh7C,gBAAgBm2C,GAEvBqG,IACAz2D,GAAGy2D,GAAYhzD,QAAQ1B,GACvB00D,EAAWllD,aAAa,QAASxP,IAGrCy0D,EAAOjlD,aAAaw+C,EAAct1C,GAE9B27C,EACAjB,EAAYqB,EAAQJ,EAAYl7C,MAAO4E,GAGvCA,EAActO,YAAYglD,GAG1BH,GACAG,EAAOr2D,MAAMC,QAAU,OACvBJ,GAAGw2D,GAAQn0D,SAASiuD,KAGpBpwD,EAAKi0D,EAAY15C,IACjBva,EAAK0iB,EAAQnI,IACbva,EAAK6zD,EAAUt5C,IACfva,EAAKk0D,EAAS35C,IACdva,EAAKg0D,EAASz5C,IACdva,EAAK2zD,EAAYp5C,IAEbk2C,GACAtwD,KAAKwpD,WAAWpvC,GAGpB87C,EAAQpD,EAAa14C,GACjB87C,IAAUA,EAAMzoB,KAChB2kB,EAA6Br7C,KAAK,SAASs/C,GACvCH,EAAMzoB,IAAM4oB,EAAW5oB,IACnB4oB,EAAWv2D,MAAMk2B,WAAaqgC,EAAWv2D,MAAMm2B,UAC/Ct2B,GAAGu2D,GAAOj1D,KACN+0B,UAAWqgC,EAAWv2D,MAAMk2B,UAC5BC,SAAUogC,EAAWv2D,MAAMm2B,WAInC28B,GAAKsD,OAMrB/J,eAAgB,SAAS/xC,EAAI1Y,EAAMq0D,EAAaC,GAC5Ch2D,KAAKob,QAAQhB,EAAI1Y,EAAMq0D,EAAaC,GAAa,IAGrDvR,cAAe,WACXh2B,EAAStd,YAAY++C,EAAUC,SAC/BD,EAAUC,QAAU3mD,SAAS4mD,yBAC7BF,EAAUG,QAGdpK,WAAY,SAAS7rC,GACjBza,GAAG4hB,EAAQnH,IAAKrZ,UAGpB6kD,UAAW,SAASvX,GAChB,GAAIioB,GAAcjoB,CAElB,IAAIioB,EAAa,CAEb,KAAiD,MAA1CA,EAAYzyD,aAAa6rD,IAC5B4G,EAAcA,EAAYx1D,UAG9B,OAAO6gC,UAAS20B,EAAYzyD,aAAa6rD,MAIjD6G,YAAa,WACT,MAAO9nC,IAGXi6B,qBAAsB,SAAStuC,GAC3B,GAAI1I,GAAWI,EAAYsI,EAE3B1I,IAAY/R,GAAG+R,GAAU1P,SAASkW,EAAQwR,QAAQqkC,WAGtDzI,eAAgB,SAASlrC,EAAI1Y,GACzB,GAAI80D,GAAa1kD,EAAYsI,EAEzBo8C,KACA72D,GAAG62D,GAAYpzD,QAAQ1B,GACvB80D,EAAWtlD,aAAa,QAASxP,KAIzC4mD,aAAc,SAASluC,GACnBva,EAAKiS,EAAYsI,KAGrBouC,aAAc,SAASpuC,GACnBw4C,GAAK9gD,EAAYsI,KAGrBq8C,WAAY,SAASpoB,GACjB,MAAO1uC,IAAG0uC,GAAI5sC,SAASkvD,EAAgBpxC,OAG3CqC,UAAW,WACP,MAAO1J,GAAQmL,QAAUkwC,EAAc/xC,EAAWmvC,EAAgBttC,SAGtE8jC,mBAAoB,WAChBtnD,EAAK8zD,MAGTzM,mBAAoB,WAChB0L,GAAKe,MAGT1M,YAAa,WACT,MAAOsM,GAAc/xC,EAAWmvC,EAAgBQ,OAGpDxJ,uBAAwB,WACpB,MAAO0H,IAGX1G,UAAW,SAASvuC,GAChBva,EAAKk0D,EAAS35C,KAGlB4vC,gBAAiB,WACb,MAAOsF,IAGXrF,UAAW,SAAS7vC,GAChBw4C,GAAKmB,EAAS35C,KAGlB4qC,iBAAkB,SAAS5qC,GACvB,MAAOmH,GAAQnH,IAGnBquC,aAAc,SAASruC,GACnB,GAAIs8C,GAAO9C,EAAYx5C,EAEvBs8C,IAAQ/2D,GAAG+2D,GAAM10D,SAASkW,EAAQwR,QAAQqkC,WAG9ChJ,gBAAiB,SAAS3qC,GACtB,MAAOza,IAAG4hB,EAAQnH,IAAK3Y,SAASwuD,IAGpC1H,aAAc,SAASnuC,GACnB,GAAIs8C,GAAO9C,EAAYx5C,EAEvBs8C,IAAQ/2D,GAAG+2D,GAAMz0D,YAAYiW,EAAQwR,QAAQqkC,WAGjD4I,WAAY,SAAStoB,GACjB,MAAO1uC,IAAG0uC,GAAI5sC,SAASkvD,EAAgBkB,cAAc,IAGzDzJ,aAAc,SAAShuC,GACnB,MAAOm5C,GAAchyC,EAAQnH,GAAKu2C,EAAgBiB,oBAGtDgF,YAAa,SAASvoB,GAClB,MAAO1uC,IAAG0uC,GAAI5sC,SAASkvD,EAAgBiB,mBAAmB,IAG9DrI,eAAgB,SAASnvC,EAAIqQ,EAAQC,GACjC,GACI4qC,GADAC,EAAMzB,EAAY15C,EAGlBm7C,IAAO7qC,EAAQ,IACf4qC,EAAUh0D,KAAKC,MAAMkpB,EAASC,EAAQ,KAEtB,MAAZ4qC,EACAz1D,EAAK01D,GAGL3C,GAAK2C,GAGTF,GAAoBj7C,EAAIk7C,KAIhC1Z,oBAAqB,SAASnxB,EAAQC,GAClC1qB,KAAKupD,eAAe,KAAM9+B,EAAQC,IAGtC++B,aAAc,SAASrvC,GACnB,GAAIm7C,GAAMzB,EAAY15C,EAEtBm7C,IAAO11D,EAAK01D,IAGhBM,kBAAmB,WACf71D,KAAKypD,gBAGTsB,cAAe,SAAS3wC,GACpBi7C,GAAoBj7C,EAAI,GACxBpa,KAAK61D,kBAAkBz7C,IAG3B8uC,mBAAoB,WAChBlpD,KAAK+qD,iBAGThB,WAAY,SAAS3vC,GACjB,IAAKk2C,EAAkB,CACnB,GAAI3wC,GAAS2zC,EAAUl5C,EAEvBuF,IAAUhgB,GAAGggB,GAAQ1d,YAAYiW,EAAQwR,QAAQ7pB,QAIzD2pD,WAAY,SAASpvC,GACjBva,EAAKyzD,EAAUl5C,KAGnBy8C,SAAU,SAASxoB,GACf,MAAO1uC,IAAG0uC,GAAI5sC,SAASkvD,EAAgBhxC,QAAQ,IAGnD6qC,WAAY,SAASpwC,GACjBw4C,GAAKiB,EAASz5C,IACdva,EAAK2zD,EAAYp5C,KAGrBmrC,aAAc,SAASnrC,GACnBpa,KAAK4oD,cAAcxuC,EAAIlC,EAAQ7U,KAAK0jC,QACpC/mC,KAAK82D,oBAAoB18C,GACzBva,EAAKm0D,EAAW55C,KAGpB2uC,UAAW,SAAS3uC,GAChBva,EAAKg0D,EAASz5C,KAGlB28C,QAAS,SAAS1oB,GACd,MAAO1uC,IAAG0uC,GAAI5sC,SAASkvD,EAAgBz6C,OAAO,IAGlD8gD,iBAAkB,SAAS3oB,GACvB,MAAO1uC,IAAG0uC,GAAI5sC,SAASkvD,EAAgBc,gBAAgB,IAG3DqF,oBAAqB,SAAS18C,GAC1Bw4C,GAAKY,EAAYp5C,IACjBva,EAAKg0D,EAASz5C,KAGlBqrC,gBAAiB,SAASrrC,GACtBpa,KAAK4oD,cAAcxuC,EAAI,IACvBpa,KAAKwqD,WAAWpwC,GAChBw4C,GAAKoB,EAAW55C,KAGpBiwC,iBAAkB,SAASjwC,GACvBw4C,GAAKc,EAAUt5C,KAGnBixC,iBAAkB,SAASjxC,GACvBva,EAAK6zD,EAAUt5C,KAGnB68C,eAAgB,SAAS5oB,GACrB,MAAO1uC,IAAG0uC,GAAI5sC,SAASkvD,EAAgBe,cAAc,IAGzDwF,QAAS,SAAS7oB,GACd,MAAO1uC,IAAG0uC,GAAI5sC,SAASkvD,EAAgB7sC,OAAO,IAGlDtH,WAAY,SAASpC,EAAI/W,GACrB,GAAImY,GAAO+G,EAAQnI,EAEfoB,KACAo3C,GAAKp3C,GACL7b,GAAG6b,GAAMpY,QAAQC,KAIzBulD,cAAe,SAASxuC,EAAI/W,GACxB,GAAI8zD,GAAS5D,EAAchyC,EAAQnH,GAAKu2C,EAAgBgB,WAEpDwF,KAEY,MAAR9zD,EACA1D,GAAGw3D,GAAQ3zD,YAGX7D,GAAGw3D,GAAQ/zD,QAAQC,KAK/B4lD,YAAa,SAAS7uC,GAClBza,GAAG4hB,EAAQnH,IAAKnY,YAAY+tD,GAC5BnwD,EAAKm0D,EAAW55C,KAGpBmwC,YAAa,SAASnwC,GAClBza,GAAG4hB,EAAQnH,IAAKpY,SAASguD,GACzB4C,GAAKoB,EAAW55C,KAGpBkyC,gBAAiB,SAASlyC,EAAI66C,EAAeh0C,GACpCjhB,KAAK+kD,gBAAgB3qC,KACtBq2C,EAAqB5tD,MAAMuX,GAAIA,EAAI6G,qBAAsBA,EAAsBg0C,cAAeA,KAC7FzE,GAAgCyC,MAIzC7G,gBAAiB,SAAShyC,EAAIyL,EAAcuvC,EAAgBn0C,GACnDjhB,KAAK+kD,gBAAgB3qC,KACtBq2C,EAAqB5tD,MAAMoe,qBAAsBA,EAAsBkyC,QAAQ,EAAM/4C,GAAIA,EAAIyL,aAAcA,EAAcuvC,eAAgBA,KACxI5E,GAAgCyC,MAIzC1E,UAAW,SAASruD,GAChB,MAAOP,IAAGkT,kBAAkB6C,iBAAmB+9C,EAAUvzD,IAG7DsuD,WAAY,SAAStuD,EAAM6F,EAAS2oD,GAChC,GAAI0I,GAAS3D,EAAUvzD,GACnBm3D,EAAY9D,EAAc6D,EAAQzG,EAAgBI,eAClDuG,EAAUF,EAAO30D,qBAAqB,SAAS,GAC/C80D,EAAYhE,EAAc6D,EAAQzG,EAAgBE,oBAClD2G,EAAQjE,EAAc6D,EAAQzG,EAAgBK,gBAC9CvlD,EAAU,GAAI9L,IAAG+L,QAEjB+rD,EAAe,WACXF,EAAUh3D,oBAAoB,QAASm3D,GACvCF,GAASA,EAAMj3D,oBAAoB,QAASo3D,GAC5ClsD,EAAQK,WAGZ4rD,EAAqB,WACjBH,EAAUh3D,oBAAoB,QAASm3D,GACvCN,EAAOQ,SAGXD,EAAiB,WACbP,EAAO72D,oBAAoB,QAASk3D,GACpCD,EAAMj3D,oBAAoB,QAASo3D,GACnCP,EAAOQ,QAEPnsD,EAAQG,QAAQ0rD,GAAWA,EAAQ5wD,OAc3C,OAXA0wD,GAAOh3D,iBAAiB,QAASq3D,GACjCF,EAAUn3D,iBAAiB,QAASs3D,GACpCF,GAASA,EAAMp3D,iBAAiB,QAASu3D,GAErCL,IACAA,EAAQ5wD,MAAQgoD,GAEpB2I,EAAU9zD,YAAcwC,EAExBqxD,EAAOS,YAEApsD,MC/gCnB9L,GAAGm4D,eAAiB,SAASC,EAAGC,GAC5B,YAqBA,SAAS1O,GAAW1pD,GAChBwS,EAASnS,OAAOL,EAASyb,EAAK48C,UAAW,SAASlkC,GAE9CA,EAAQA,GAASlvB,OAAOkvB,KAGxB,IAAI3nB,GAAS2nB,EAAM3nB,QAAU2nB,EAAMmkC,UAEnC78C,GAAK88C,UAAU/rD,EAAQ2nB,KA3B/B,GAAI3hB,GAAW,GAAIzS,IAAGsS,eAClBoJ,GACI48C,UAAW,QACXG,SAAU,KACVD,UAAW,SAAS/rD,EAAQ2nB,KAKpCp0B,IAAG6B,OAAOxB,MACNspD,WAAY,SAAS1pD,GACjB0pD,EAAW1pD,IAGfuS,QAAS,WACLC,EAASD,aAiBjBxS,GAAG6B,OAAOw2D,GACNK,kBAAmB,SAASpxD,GACxB,MAAOA,GAAKqxD,UAGhBC,kBAAmB,WACf,MAAOnmD,MAIfzS,GAAG6B,OAAO6Z,EAAM08C,GAEZ18C,EAAK+8C,UACL9O,EAAWjuC,EAAK+8C,WClDxBz4D,GAAGwmD,wBAA0B,SAAS4R,GAClC,YAqBA,SAASS,GAAapsD,EAAQ2nB,GAC1Bp0B,GAAG+C,KAAK+1D,EAAgB,SAASC,EAAYtqC,GACzC,GACIvN,GADA83C,EAA2BD,EAAWhpD,OAAO,GAAG8W,cAAgBkyC,EAAW7wD,MAAM,EAGrF,IAAIwT,EAAK0rC,WAAW,KAAO4R,GAA0BvsD,GAKjD,MAJAyU,GAASxF,EAAK0rC,WAAWnB,UAAUx5C,GACnCzM,GAAGiP,eAAemlB,GAClB1Y,EAAKvV,IAAInG,GAAG8H,OAAO,+DAAgE4T,EAAKqsC,UAAU7mC,GAASA,IAC3GuN,EAAQvN,IACD,IA7BnB,GAAI+3C,MACAv9C,GACI0rC,WAAY,KACZjhD,IAAK,SAASC,EAASshD,KACvBC,aAAc,SAASzmC,KACvBiK,SAAU,SAASjK,KACnB0mC,QAAS,SAAS1mC,KAClB2mC,QAAS,SAAS3mC,KAClB4mC,WAAY,SAAS5mC,KACrB6mC,UAAW,SAAS7mC,MAExB43C,GACI94C,OAAQ,SAASvF,GAAMiB,EAAKyP,SAAS1Q,IACrC0J,MAAQ,SAAS1J,GAAMiB,EAAKksC,QAAQntC,IACpCs3C,aAAc,SAASt3C,GAAMiB,EAAKisC,aAAaltC,IAC/ClE,MAAO,SAASkE,GAAMiB,EAAKmsC,QAAQptC,IACnCq3C,eAAgB,SAASr3C,GAAMiB,EAAKosC,WAAWrtC,IAkBvDza,IAAG6B,OAAO6Z,EAAM08C,GAEhB18C,EAAK48C,UAAY,QACjB58C,EAAK88C,UAAYK,EACjBn9C,EAAK+8C,SAAW/8C,EAAK0rC,WAAWwP,cAEhC52D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGm4D,eAAez8C,EAAMu9C,KC1ChDj5D,GAAGioD,qBAAuB,SAASmQ,GAC/B,YAiBA,SAASS,GAAapsD,EAAQ2nB,GAC1B,GAAI1Y,EAAK0rC,WAAW0P,WAAWrqD,IAAWiP,EAAK0rC,WAAW4P,WAAWvqD,GAAS,CAC1E,GAAIyU,GAASxF,EAAK0rC,WAAWnB,UAAUx5C,GACnCsO,EAASW,EAAK0sC,kBAAkBlnC,EAGhCnG,KAAW/a,GAAG+a,OAAOqC,YACrB1B,EAAKvV,IAAInG,GAAG8H,OAAO,4DAA6D4T,EAAKqsC,UAAU7mC,GAASA,IACxGlhB,GAAGiP,eAAemlB,GAElB6kC,EAAqBC,mBAAmBh4C,EAAQzU,GAAQ,KAzBpE,GAAIwsD,MACAv9C,GACI0rC,WAAY,KACZjhD,IAAK,SAASC,EAASshD,KACvB39B,SACInK,KAAM,iBACNsyC,aAAc,yBAElB9J,kBAAmB,SAASlnC,KAC5B6mC,UAAW,SAAS7mC,KAG5BlhB,IAAG6B,OAAO6Z,EAAM08C,GAkBhB18C,EAAK48C,UAAY,QACjB58C,EAAK88C,UAAYK,EAEjB74D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGm5D,oBAAoBz9C,EAAMu9C,KCpCrDj5D,GAAGqpD,4BAA8B,SAAS+O,EAAGa,GACzC,YAaA,SAASG,GAAiB3sD,EAAQ2nB,GAC9B,GAAI1Y,EAAK0rC,WAAW6P,YAAYxqD,GAAS,CACrC,GAAIyU,GAASxF,EAAK0rC,WAAWnB,UAAUx5C,GACnCsO,EAASW,EAAK0sC,kBAAkBlnC,EAEhCnG,KAAW/a,GAAG+a,OAAOqC,YACrB1B,EAAKvV,IAAInG,GAAG8H,OAAO,kEAAmE4T,EAAKqsC,UAAU7mC,GAASA,IAC9G+3C,EAAqBC,mBAAmBh4C,EAAQzU,KAlB5D,GAAIiP,IACI0rC,WAAY,KACZgB,kBAAmB,SAASlnC,KAC5B/a,IAAK,SAASC,EAASshD,KAG1BuR,KACDA,MAgBJv9C,EAAK48C,UAAY,UACjB58C,EAAK88C,UAAYY,EAEjBp5D,GAAG6B,OAAO6Z,EAAM08C,GAChBp4D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGm5D,oBAAoBz9C,EAAMu9C,KCzBrDj5D,GAAGkoD,0BAA4B,SAASxsC,GACpC,YAEAA,GAAK48C,UAAY,QACjB58C,EAAK+8C,SAAW,KAEhBz4D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGqpD,4BAA4B3tC,QCVvD1b,GAAGm5D,oBAAsB,SAASf,EAAGa,GACjC,YAWA,SAASI,GAAyBn4C,GAC9B,GAAIo4C,GAAkB59C,EAAKqsC,UAAU7mC,GACjClP,EAASsnD,EAAgBrnD,YAAY,IAMzC,OAJID,GAAS,IACTsnD,EAAkBA,EAAgBpnD,OAAO,EAAGF,IAGzCsnD,EAGX,QAASC,GAAqBr4C,GAC1B,GAAIs4C,GAAW99C,EAAKqsC,UAAU7mC,EAC9B,OAAOlhB,IAAG8R,aAAa0nD,GAI3B,QAASC,GAAiBC,EAAoBx4C,GAC1C,GACIy4C,GADA/8C,EAAU88C,EAAmB3yD,KAGjB5C,UAAZyY,GAAyB5c,GAAG0H,QAAQkV,GAAS7W,OAAS,IACtD4zD,EAAgBJ,EAAqBr4C,GAEf/c,SAAlBw1D,IACA/8C,EAAUA,EAAU,IAAM+8C,GAG9Bj+C,EAAK2sC,UAAUnnC,EAAQtE,IAG3BlB,EAAK4sC,sBAAsBpnC,GAAQ,GAIvC,QAAS04C,GAAyBjC,EAASz2C,GACvC+3C,EAAqBL,oBAAoBt4D,OAAOq3D,EAAS,OAAQ,WAC7D8B,EAAiB9B,EAASz2C,KAKlC,QAAS24C,GAA6BlC,EAASz2C,GAC3C+3C,EAAqBL,oBAAoBt4D,OAAOq3D,EAAS,QAAS,SAASvjC,GAEvE,GAAIpE,GAAOoE,EAAM0lC,SAAW1lC,EAAM2lC,KAErB,MAAT/pC,GACAypC,EAAiB9B,EAASz2C,KAzDtC,GAAIxF,IACI0rC,WAAY,KACZjhD,IAAK,SAASC,EAASshD,KACvBU,kBAAmB,SAASlnC,KAC5B6mC,UAAW,SAAS7mC,KACpBmnC,UAAW,SAASnnC,EAAQtE,KAC5B0rC,sBAAuB,SAASpnC,EAAQqnC,KAwDhDvoD,IAAG6B,OAAO6Z,EAAM08C,GAEhB18C,EAAK+8C,SAAW/8C,EAAK0rC,WAAWwP,cAEhC52D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGm4D,eAAez8C,EAAMu9C,IAE5Cj5D,GAAG6B,OAAOo3D,GACNC,mBAAoB,SAASz+C,EAAIhO,EAAQutD,GACrC,GAAIN,GAAqBh+C,EAAK0rC,WAAWqB,aAAahuC,EAEtDiB,GAAK4sC,sBAAsB7tC,GAAI,GAE/Bi/C,EAAmB3yD,MAAQsyD,EAAyB5+C,GAEhDu/C,GACAN,EAAmBO,QAGvBL,EAAyBF,EAAoBj/C,GAC7Co/C,EAA6BH,EAAoBj/C,Q3CvF9BvV","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css b/styles/bootstrap/fine-uploader/fine-uploader.min.css index 488d8eba2..9aff7b49b 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css @@ -1 +1 @@ -.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #DDD;color:#FFF}.qq-upload-button-hover{background:#C00}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#FF9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FF7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#FFF0BD}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#D60000}.qq-upload-list li.qq-upload-success{background-color:#5DA30C;color:#FFF}.qq-upload-list li.qq-upload-fail{background-color:#D60000;color:#FFF}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file +.qq-uploader{position:relative;width:100%}.qq-upload-button{display:block;width:105px;padding:7px 0;text-align:center;background:#800;border-bottom:1px solid #ddd;color:#fff}.qq-upload-button-hover{background:#c00}.qq-upload-button-focus{outline:1px dotted #000}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#ff9797;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#ff7171}.qq-upload-list{margin:0;padding:0;list-style:none}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;background-color:#fff0bd}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-continue,.qq-upload-delete,.qq-upload-pause{display:inline}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry{color:#000}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text{display:inline}.qq-upload-retrying .qq-upload-failed-text{display:inline;color:#d60000}.qq-upload-list li.qq-upload-success{background-color:#5da30c;color:#fff}.qq-upload-list li.qq-upload-fail{background-color:#d60000;color:#fff}.qq-progress-bar{display:block;background:-moz-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(30,87,153,1)),color-stop(50%,rgba(41,137,216,1)),color-stop(51%,rgba(32,124,202,1)),color-stop(100%,rgba(125,185,232,1)));background:-webkit-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-o-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:-ms-linear-gradient(top,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);background:linear-gradient(to bottom,rgba(30,87,153,1) 0,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%);width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin:9px}INPUT.qq-edit-filename{position:absolute;opacity:0;z-index:-1}.qq-upload-file.qq-editable{cursor:pointer}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}INPUT.qq-edit-filename.qq-editing{position:static;margin-top:-5px;margin-right:10px;margin-bottom:-5px;opacity:1}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:5px}.qq-hide{display:none}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG{display:none}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map index 3ee17ba9b..f1896da99 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.css.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAoB,KAAP,OAAJ,IAEb,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAwB,yLACxB,WAA8C,wHAC9C,WAAyE,mHACzE,WAA4F,oHAC5F,WAAwG,sHACxG,MAA6G,EAC7G,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EACT,OAAQ,iBACR,QAAS,GACT,WAAY,qDAGhB,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAuBZ,SAaA,oBACI,QAAS,KAlCb,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EACT,OAAQ,mBACR,WAAY,uDAGhB,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAoBlB,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file +{"version":3,"sources":["_build/fine-uploader.css"],"names":[],"mappings":"AAAA,aACI,SAAU,SACV,MAAO,KAEX,kBACI,QAAS,MACT,MAAO,MACP,QAAS,IAAI,EACb,WAAY,OACZ,WAAY,KACZ,cAAe,IAAI,MAAM,KACzB,MAAO,KAEX,wBACI,WAAY,KAEhB,wBACI,QAAS,IAAI,OAAO,KAExB,qBAAsB,2BAClB,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KACR,WAAY,KACZ,QAAS,EACT,WAAY,QACZ,WAAY,OAEhB,0BACI,QAAS,MACT,SAAU,SACV,IAAK,IACL,MAAO,KACP,WAAY,KACZ,UAAW,KAEf,2BACI,SAAU,SACV,WAAY,KACZ,UAAW,KACX,YAAa,KACb,OAAQ,KACR,WAAY,KAEhB,4BACI,WAAY,QAEhB,gBACI,OAAQ,EACR,QAAS,EACT,WAAY,KAEhB,mBACI,OAAQ,EACR,QAAS,IACT,YAAa,KACb,UAAW,KACX,iBAAkB,QAGtB,kBACqC,oBAArC,kBADqC,uBADrC,gBAEmB,iBADA,iBADkB,gBAApB,mBAGb,aAAc,KACd,QAAS,OAIb,mBACI,QAAS,aACT,WAAY,iBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAEpB,oBACI,QAAS,MAEb,4BACI,QAAS,aACT,WAAY,oBACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAGiB,oBAArC,kBAAmB,iBACf,QAAS,OAGwB,kBACnB,oBADA,kBAClB,iBADA,iBAEI,MAAO,KAGM,kBACoB,oBAArC,kBAAmB,iBADiB,iBAApC,gBAEI,UAAW,KACX,YAAa,IAEjB,uBACI,QAAS,KACT,WAAY,OACZ,YAAa,IAEjB,uBACI,QAAQ,KACR,MAAM,KACN,OAAO,KACP,eAAe,YAEnB,uCACI,QAAS,OAEb,2CACI,QAAS,OACT,MAAO,QAEX,qCACI,iBAAkB,QAClB,MAAO,KAEX,kCACI,iBAAkB,QAClB,MAAO,KAEX,iBACI,QAAS,MACT,WAAY,qHACZ,WAAY,yLACZ,WAAY,wHACZ,WAAY,mHACZ,WAAY,oHACZ,WAAY,sHACZ,MAAO,EACP,OAAQ,KACR,cAAe,IACf,cAAe,IAGnB,uBACI,OAAQ,KACR,cAAe,IAGnB,iCACI,OAAQ,IAGZ,uBACI,SAAU,SACV,QAAS,EAET,QAAS,GAIb,4BACI,OAAQ,QAGZ,mCACI,QAAS,aACT,OAAQ,QAGZ,kCACI,SAAU,OACV,WAAY,KACZ,aAAc,KACd,cAAe,KAEf,QAAS,EAKb,uBACI,QAAS,KACT,WAAY,cACZ,MAAO,KACP,OAAQ,KACR,eAAgB,YAChB,aAAc,IAGlB,SACI,QAAS,KAIb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,oBACI,QAAS,KAGb,0BACI,QAAS,MAGb,uCACI,WAAY,OACZ,YAAa,KAGjB,8CACI,YAAa,IACb,aAAc,IAGlB,gDACI,eAAgB,KAGpB,8BACI,iBAAkB"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js b/styles/bootstrap/fine-uploader/fine-uploader.min.js index bcee499fc..add39e107 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,q,f,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),q=p&&qq.isFileChunkingSupported(),f=p&&q&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:q,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:q,progressBar:w,resume:f,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e); -}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e); -},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=q(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,q=o.onUuidChanged,f=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?f(e,r,i,i):f(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),q=l;s[t]=h,qq.each(s,function(e,t){q+=t}),f(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,q=l.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
c&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d,f=new qq.Identify(q,t);return f.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit; -qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA;KCCT,SAASC;QACN;QACA,IAAIC,KACAC,kBAAiB,gBAAgB;QAErC,SAASC,KAAKC;YACV,IAAIC,cAAcC,mBAAmBF,gBACjCG,sBAAsBC,uBAAuBH;YAEjDI,SAASF;YACTG,aAAaL,aAAaE;YAE1B,OAAON;;QAGX,SAASO,uBAAuBG;YAC5B,IAAIC,eAAeC,aAAa,iBAC5BC,YAAYD,aAAa;YAG7B,IAAID,cAAc;gBAGdA,eAAeA,aAAaG,OAAO,GAAGC,gBAAgBJ,aAAaK,MAAM,GAAGC;gBAE5E,IAAIJ,WAAW;oBACX,OAAO,IAAIK,GAAGL,WAAW,iBAAiBF,cAAcD;;gBAG5D,OAAO,IAAIQ,GAAG,iBAAiBP,cAAcD;mBAE5C;gBACD,IAAIG,WAAW;oBACX,OAAO,IAAIK,GAAGL,WAAWM,aAAaT;;gBAG1C,OAAO,IAAIQ,GAAGC,aAAaT;;;QAInC,SAASU,UAAUC,KAAKC;YACpB,IAAIC,OAAOvB,IAAIuB,KAAK;YAEpB,IAAID,KAAK;gBACL,IAAIC,SAASC,WAAW;oBACpBD;;gBAEJA,KAAKF,OAAOC;gBACZtB,IAAIuB,KAAK,gBAAgBA;mBAExB;gBACD,IAAIA,SAASC,WAAW;oBACpB,OAAO;;gBAEX,OAAOD,KAAKF;;;QAMpB,SAASb,SAASiB;YACd,OAAOL,UAAU,YAAYK;;QAGjC,SAASb,aAAac,QAAQC;YAC1B,OAAOP,UAAUM,QAAQC;;QAK7B,SAASlB,aAAamB,iBAAiBtB;YACnC,IAAIuB,YAAYD,gBAAgBC;YAEhC9B,EAAE+B,KAAKxB,oBAAoByB,SAASF,WAAW,SAASG,MAAMC;gBAC1D,IAAIC,MAAMC;gBAEVD,OAAO,WAAWE,KAAKJ,MAAM;gBAC7BE,OAAOA,KAAKG,UAAU,GAAG,GAAGpB,gBAAgBiB,KAAKG,UAAU;gBAC3DF,sBAAsBnC;gBAEtB6B,UAAUG,QAAQ;oBACd,IAAIM,eAAeC,MAAMC,UAAUxB,MAAMyB,KAAKC,YAC1CC,sBACAC,yBAAyBC;oBAE7B9C,EAAE+B,KAAKQ,cAAc,SAASQ,KAAKC;wBAC/BJ,gBAAgBK,KAAKC,kBAAkBF;;oBAG3CH,0BAA0BX,kBAAkBiB,MAAMC,MAAMb;oBAExD;wBACIO,4BAA4BV,oBAAoBiB,eAAelB,MAAMS;sBAEzE,OAAOU;wBACHnC,GAAGoC,IAAI,yDAAyDD,MAAME,SAAS;;oBAInF,IAAIX,2BAA2B,MAAM;wBACjC,OAAOA;;oBAEX,OAAOC;;;YAIfvC,oBAAoByB,SAASF,YAAYA;;QAI7C,SAASxB,mBAAmBmD,QAAQC;YAChC,IAAIC,SAASC;YAEb,IAAIF,SAASjC,WAAW;gBACpB,IAAIgC,OAAO7C,iBAAiB,SAAS;oBACjC+C;wBAAYE,SAAS5D,IAAI;;uBAExB;oBACD0D;;mBAGH;gBACDA,UAAUD;;YAGd1D,EAAE+B,KAAK0B,QAAQ,SAASxB,MAAMV;gBAC1B,IAAIvB,EAAE8D,QAAQ7B,MAAM/B,kBAAkB,GAAG;oBACrCW,aAAaoB,MAAMV;uBAElB,IAAIA,eAAevB,GAAG;oBACvB2D,QAAQ1B,QAAQV,IAAI;uBAEnB,IAAIvB,EAAE+D,cAAcxC,MAAM;oBAC3BoC,QAAQ1B;oBACR3B,mBAAmBiB,KAAKoC,QAAQ1B;uBAE/B,IAAIjC,EAAEgE,QAAQzC,MAAM;oBACrBqC;oBACA5D,EAAE+B,KAAKR,KAAK,SAASwB,KAAKkB;wBACtB,IAAIC;wBAEJ,IAAID,oBAAoBjE,GAAG;4BACvBA,EAAEmE,MAAMP,WAAWK;+BAElB,IAAIjE,EAAE+D,cAAcE,WAAW;4BAChC3D,mBAAmB2D,UAAUC;4BAC7BN,UAAUX,KAAKiB;+BAEd;4BACDN,UAAUX,KAAKgB;;;oBAGvBN,QAAQ1B,QAAQ2B;uBAEf;oBACDD,QAAQ1B,QAAQV;;;YAIxB,IAAImC,SAASjC,WAAW;gBACpB,OAAOkC;;;QAIf,SAASS,eAAeC;YACpB,OAAOrE,EAAEsE,KAAKD,aAAa,aACtBA,QAAQE,MAAM,SACf9D,WAAW4D,aAAa5C;;QAKhC,SAAS+C,gBAAgBH;YACrB,IAAII,kBACAC,WAAWlC,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW,IACjDgC;YAEJrE,mBAAmBoE,UAAUD;YAE7BE,SAASlE,WAAW4D,SAASlB,MAAM1C,YAAYgE;YAE/C,OAAOvB,kBAAkByB;;QAI7B,SAASzB,kBAAkB3B;YACvB,IAAIqD,iBAAiBrD;YAIrB,IAAIA,OAAO,eAAeA,QAAQ,aAC9BA,IAAIsD,aAAa,KAAKtD,IAAIsD,aAAa,MAAMtD,IAAIuD,WAAW;gBAE5DF,iBAAiB5E,EAAEuB;;YAGvB,OAAOqD;;QAGX5E,EAAE+E,GAAGC,eAAe,SAASC;YACzB,IAAIC,OAAO9B,MAAM+B,WAAWxC,WAAWyC;YAEvChC,KAAKrB,KAAK,SAASsD,OAAOC;gBACtBrF,MAAMD,EAAEsF;gBAER,IAAI7E,cAAc2D,eAAea,mBAAmB;oBAChDG,QAAQnC,KAAKuB,gBAAgBrB,MAAM+B,MAAMC;oBAEzC,IAAID,KAAKK,WAAW,GAAG;wBACnB,OAAO;;uBAGV,WAAWN,qBAAqB,aAAaA,kBAAkB;oBAChE9E,KAAKgD,MAAM+B,MAAMC;uBAEhB;oBACDnF,EAAEsD,MAAM,YAAa2B,mBAAmB;;;YAIhD,IAAIG,QAAQG,WAAW,GAAG;gBACtB,OAAOH,QAAQ;mBAEd,IAAIA,QAAQG,SAAS,GAAG;gBACzB,OAAOH;;YAGX,OAAOhC;;OAGboC;KCtOD,SAASxF;QACN;QACA,IAAIyF,cAAc,mBACdxF;QAEJ,SAASE,KAAKC;YACV,KAAKA,SAAS;gBACVA;;YAGJA,QAAQsF,qBAAoBzF;YAC5B,IAAII,cAAcC,mBAAmBF;YACrCM,aAAaL;YACbsF,IAAI,IAAIxE,GAAGyE,YAAYvF;YAEvB,OAAOJ;;QAGX,SAASoB,UAAUC,KAAKC;YACpB,IAAIC,OAAOvB,IAAIuB,KAAKiE;YAEpB,IAAIlE,KAAK;gBACL,IAAIC,SAASC,WAAW;oBACpBD;;gBAEJA,KAAKF,OAAOC;gBACZtB,IAAIuB,KAAKiE,aAAajE;mBAErB;gBACD,IAAIA,SAASC,WAAW;oBACpB,OAAO;;gBAEX,OAAOD,KAAKF;;;QAIpB,SAASqE,IAAIjE;YACT,OAAOL,UAAU,eAAeK;;QAGpC,SAAShB,aAAamB;YAClB,IAAIC,YAAYD,gBAAgBC;YAEhC9B,EAAE+B,KAAK,IAAIZ,GAAGyE,YAAY9D,aAAa,SAASG,MAAM4D;gBAClD,IAAI1D,OAAOF,MACP6D;gBAEJA,cAAc7F;gBAEd6B,UAAUG,QAAQ;oBACd,IAAI8D,OAAOvD,MAAMC,UAAUxB,MAAMyB,KAAKC,YAClCqD,sBAAsBF,YAAYzC,eAAelB,MAAM4D;oBAE3D,OAAOC;;;;QAMnB,SAAS1F,mBAAmBmD,QAAQC;YAChC,IAAIC,SAASC;YAEb,IAAIF,SAASjC,WAAW;gBACpBkC;mBAEC;gBACDA,UAAUD;;YAGd1D,EAAE+B,KAAK0B,QAAQ,SAASxB,MAAMV;gBAC1B,IAAIA,eAAevB,GAAG;oBAClB2D,QAAQ1B,QAAQV,IAAI;uBAEnB,IAAIvB,EAAE+D,cAAcxC,MAAM;oBAC3BoC,QAAQ1B;oBACR3B,mBAAmBiB,KAAKoC,QAAQ1B;uBAE/B,IAAIjC,EAAEgE,QAAQzC,MAAM;oBACrBqC;oBACA5D,EAAE+B,KAAKR,KAAK,SAASwB,KAAKkB;wBACtB,IAAIA,oBAAoBjE,GAAG;4BACvBA,EAAEmE,MAAMP,WAAWK;+BAElB;4BACDL,UAAUX,KAAKgB;;;oBAGvBN,QAAQ1B,QAAQ2B;uBAEf;oBACDD,QAAQ1B,QAAQV;;;YAIxB,IAAImC,SAASjC,WAAW;gBACpB,OAAOkC;;;QAIf,SAASS,eAAeC;YACpB,OAAOrE,EAAEsE,KAAKD,aAAa,YACvBA,YAAY,aACZsB,MAAMtB,aAAa5C;;QAG3B,SAAS+C,gBAAgBH;YACrB,IAAII,kBAAkBC,WAAWlC,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW;YACvErC,mBAAmBoE,UAAUD;YAC7B,OAAOkB,MAAMtB,SAASlB,MAAMwC,OAAOlB;;QAGvCzE,EAAE+E,GAAGkB,kBAAkB,SAAShB;YAC5B,IAAIC,OAAO9B,MAAM+B,WAAWxC,WAAWyC;YAEvChC,KAAKrB,KAAK,SAASsD,OAAOC;gBACtBrF,MAAMD,EAAEsF;gBAER,IAAIK,SAASvB,eAAea,mBAAmB;oBAC3CG,QAAQnC,KAAKuB,gBAAgBrB,MAAM+B,MAAMC;oBAEzC,IAAID,KAAKK,WAAW,GAAG;wBACnB,OAAO;;uBAGV,WAAWN,qBAAqB,aAAaA,kBAAkB;oBAChE9E,KAAKgD,MAAM+B,MAAMC;uBAEhB;oBACDnF,EAAEsD,MAAM,YAAa2B,mBAAmB;;;YAIhD,IAAIG,QAAQG,WAAW,GAAG;gBACtB,OAAOH,QAAQ;mBAEd,IAAIA,QAAQG,SAAS,GAAG;gBACzB,OAAOH;;YAGX,OAAOhC;;OAGboC;IC7IF,IAAIrE,KAAK,SAAS0C;QACd;QAEA;YACIqC,MAAM;gBACFrC,QAAQsC,MAAMC,UAAU;gBACxB,OAAOhD;;YAIXiD,QAAQ,SAAS/B,MAAMS;gBACnB,IAAIlB,QAAQyC,kBAAkB;oBAC1BzC,QAAQyC,iBAAiBhC,MAAMS,IAAI;uBAChC,IAAIlB,QAAQ0C,aAAa;oBAC5B1C,QAAQ0C,YAAY,OAAOjC,MAAMS;;gBAErC,OAAO;oBACH5D,GAAG0C,SAAS2C,OAAOlC,MAAMS;;;YAIjCyB,QAAQ,SAASlC,MAAMS;gBACnB,IAAIlB,QAAQ4C,qBAAqB;oBAC7B5C,QAAQ4C,oBAAoBnC,MAAMS,IAAI;uBACnC,IAAIlB,QAAQ0C,aAAa;oBAC5B1C,QAAQ6C,YAAY,OAAOpC,MAAMS;;gBAErC,OAAO3B;;YAGXuD,UAAU,SAASC;gBAKf,KAAKA,YAAY;oBACb,OAAO;;gBAIX,IAAI/C,YAAY+C,YAAY;oBACxB,OAAO;;gBAGX,IAAI/C,QAAQ8C,UAAU;oBAClB,OAAO9C,QAAQ8C,SAASC;uBACrB;oBAEH,UAAUA,WAAWC,wBAAwBhD,WAAW;;;YAOhEiD,cAAc,SAASC;gBACnBA,SAASC,WAAWF,aAAajD,SAASkD;gBAC1C,OAAO3D;;YAGX6D,QAAQ;gBACJpD,QAAQmD,WAAWE,YAAYrD;gBAC/B,OAAOT;;YAOX+D,KAAK,SAASC;gBAEV,IAAIvD,QAAQsC,SAAS,MAAM;oBACvB,MAAM,IAAIhF,GAAGkG,MAAM;;gBAIvB,IAAID,OAAOE,WAAW,MAAM;oBACxB,WAAWzD,QAAQsC,MAAMmB,YAAY,mBAAoBzD,QAAe,YAAM,aAAa;wBACvFuD,OAAOG,SAAS,mBAAmBC,KAAKC,MAAM,MAAML,OAAOE,WAAW;;;gBAG9EnG,GAAGuG,OAAO7D,QAAQsC,OAAOiB;gBAEzB,OAAOhE;;YAGXuE,UAAU,SAASxF,MAAMyF;gBACrB,IAAIC,KAAK,IAAIC,OAAO,UAAU3F,OAAO;gBACrC,OAAO0F,GAAGE,KAAKlE,QAAQmE,iBAAiBJ,kBAAkBC,GAAGE,KAAKlE,QAAQmD,WAAWgB;;YAGzFC,UAAU,SAAS9F;gBACf,KAAKhB,GAAG0C,SAAS8D,SAASxF,OAAO;oBAC7B0B,QAAQmE,aAAa,MAAM7F;;gBAE/B,OAAOiB;;YAGX8E,aAAa,SAAS/F;gBAClB,IAAI0F,KAAK,IAAIC,OAAO,UAAU3F,OAAO;gBACrC0B,QAAQmE,YAAYnE,QAAQmE,UAAUG,QAAQN,IAAI,KAAKM,QAAQ,cAAc;gBAC7E,OAAO/E;;YAGXgF,YAAY,SAASJ,WAAWK;gBAC5B,IAAIC,YACAC;gBAEJ,IAAIF,SAASxE,QAAQ2E,eAAe;oBAChC,OAAO3E,QAAQ2E,cAAc,MAAMR;uBAElC,IAAInE,QAAQ4E,kBAAkB;oBAC/B,OAAO5E,QAAQ4E,iBAAiB,MAAMT;;gBAG1CM,aAAazE,QAAQ6E,qBAAqB;gBAE1CvH,GAAGY,KAAKuG,YAAY,SAASvF,KAAKxB;oBAC9B,IAAIJ,GAAGI,KAAKoG,SAASK,YAAY;wBAC7BO,OAAOtF,KAAK1B;;;gBAGpB,OAAO8G,QAAQE,OAAO,KAAKA;;YAG/BI,iBAAiB,SAASX;gBACtB,OAAO7G,GAAG0C,SAASuE,WAAWJ,WAAW;;YAG7CY,UAAU;gBACN,IAAIA,eACAC,QAAQhF,QAAQiF;gBAEpB,OAAOD,OAAO;oBACV,IAAIA,MAAMhE,aAAa,GAAG;wBACtB+D,SAAS3F,KAAK4F;;oBAElBA,QAAQA,MAAME;;gBAGlB,OAAOH;;YAGXI,SAAS,SAASC;gBACdpF,QAAQqF,YAAYD;gBACpBpF,QAAQsF,cAAcF;gBACtB,OAAO7F;;YAGXgG,WAAW;gBACP,OAAOjI,GAAG0C,SAASmF,QAAQ;;YAK/BK,cAAc,SAASC;gBACnB,IAAIC;gBAEJ,IAAI1F,QAAQwF,cAAc;oBAEtB,KAAKxF,QAAQwF,aAAaC,WAAW;wBACjC,OAAO;;oBAIX,OAAO,WAAajH,KAAKwB,QAAQ2F,aAAaF,cAAc;uBAE3D;oBACDC,UAAU1F,QAAQyF;oBAElB,IAAIC,YAAY9H,WAAW;wBACvB,OAAO;;oBAIX,OAAO,WAAaY,KAAKkH,YAAY;;;;;KAMpD;QACG;QAEApI,GAAGsI,eAAe,SAASC,QAAQC,MAAMC;YACrC,OAAOzI,GAAG0I,cAAcH,OAAOI,UAAUH,MAAMC;;QAGnDzI,GAAG0I,gBAAgB,SAASE;YACxB,IAAIC,aAAaC,YACbC,aAAa,SAAS1I,MAAMmI;gBACxB,IAAIQ,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;gBAErC,IAAIK,aAAa;oBACbA,YAAYC,OAAOjJ;oBACnB,OAAOgJ,YAAYE,QAAQf;uBAE1B;oBACD,OAAO,IAAIgB,OAAMnJ;wBAAQ8C,MAAMqF;;;eAGvCiB,UAAUC;YAGd,IAAId,QAAQe,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cd,aAAae,KAAKjB,QAAQe,MAAM,KAAK;mBAEpC;gBACDb,aAAagB,UAAUlB,QAAQe,MAAM,KAAK;;YAI9CD,aAAad,QAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBd,cAAc,IAAIkB,YAAYjB,WAAW1E;YACzCqF,WAAW,IAAIO,WAAWnB;YAC1B7I,GAAGY,KAAKkI,YAAY,SAASlH,KAAKqI;gBAC9BR,SAAS7H,OAAOqI,UAAUC,WAAW;;YAGzC,OAAOnB,WAAWF,aAAaa;;QAGnC1J,GAAGoC,MAAM,SAASC,SAAS8H;YACvB,IAAIlB,OAAOmB,SAAS;gBAChB,KAAKD,SAASA,UAAU,QAAQ;oBAC5BlB,OAAOmB,QAAQhI,IAAIC;uBAGvB;oBACI,IAAI4G,OAAOmB,QAAQD,QAAQ;wBACvBlB,OAAOmB,QAAQD,OAAO9H;2BAErB;wBACD4G,OAAOmB,QAAQhI,IAAI,MAAM+H,QAAQ,OAAO9H;;;;;QAMxDrC,GAAGqK,WAAW,SAASC;YACnB,OAAOA,aAAaA,SAAS5G,YAAY6G,OAAOjJ,UAAUkJ,SAASjJ,KAAK+I,cAAc;;QAG1FtK,GAAGyK,aAAa,SAASH;YACrB,cAAc,aAAe;;QASjCtK,GAAG6C,UAAU,SAAS6H;YAClB,OAAOH,OAAOjJ,UAAUkJ,SAASjJ,KAAKmJ,WAAW,oBAC5CA,SAASzB,OAAOc,eAAeW,MAAMC,UAAUD,MAAMC,OAAOC,gBAAgBb;;QAIrF/J,GAAG6K,aAAa,SAASC;YACrB,OAAOP,OAAOjJ,UAAUkJ,SAASjJ,KAAKuJ,mBAAmB;;QAK7D9K,GAAG+K,aAAa,SAASC;YACrB,OAAOT,OAAOjJ,UAAUkJ,SAASjJ,KAAKyJ,mBAAmB,uBAGpDA,cAAcC,QAAQD,cAAcE;;QAG7ClL,GAAGmL,WAAW,SAASC;YACnB,OAAOb,OAAOjJ,UAAUkJ,SAASjJ,KAAK6J,iBAAiB;;QAG3DpL,GAAGqL,UAAU,SAASC;YAClB,IAAIC,OAAOjK,UAAUkK,MAAM;gBACvB,OAAOF,OAAOE;;YAGlB,OAAOF,OAAOtE,QAAQ,cAAc;;QAOxChH,GAAGyL,SAAS,SAASC;YAEjB,IAAI9G,OAAQvD,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW,IAC9CmK,SAASD,KACTE,mBAAmBD,OAAO/B,QAAQ;YAEtC5J,GAAGY,KAAKgE,MAAM,SAAShD,KAAKxB;gBACxB,IAAIyL,YAAYF,OAAOxK,UAAU,GAAGyK,mBAChCE,WAAWH,OAAOxK,UAAUyK,mBAAmB;gBAEnDD,SAASE,YAAYzL,MAAM0L;gBAC3BF,mBAAmBD,OAAO/B,QAAQ,MAAMgC,mBAAmBxL,IAAIgE;gBAG/D,IAAIwH,mBAAmB,GAAG;oBACtB,OAAO;;;YAIf,OAAOD;;QAGX3L,GAAG+L,SAAS,SAASC;YACjB,OAAO/C,OAAOgD,QAAQ1B,OAAOjJ,UAAUkJ,SAASjJ,KAAKyK,eAAe;;QAGxEhM,GAAGkM,aAAa,SAASC;YACrB,OAAOlD,OAAOmD,YAAY7B,OAAOjJ,UAAUkJ,SAASjJ,KAAK4K,mBAAmB;;QAGhFnM,GAAGqM,gBAAgB,SAASC;YACxB,OAAOtM,GAAG+L,OAAOO,qBAAqBtM,GAAGuM,QAAQD;;QAGrDtM,GAAGuM,UAAU,SAASC,YAAYC;YAC9B,IAAIC,eAAe,SAASvJ;gBACxB,IAAIwJ,iBAAiBxJ,KAAKpD;gBAE1B,IAAI0M,SAAS;oBACT,OAAOE,mBAAmB;;gBAG9B,OAAOA,mBAAmB;;YAG9B,IAAI1D,OAAO2D,kBAAkB;gBACzB,IAAIrC,OAAOjJ,UAAUkJ,SAASjJ,KAAKiL,gBAAgB,6BAA6B;oBAC5E,IAAIA,WAAWrJ,QAAQuJ,aAAaF,WAAWrJ,OAAO;wBAClD,OAAO;;;;YAInB,IAAIqJ,WAAWK,SAAS;gBACpB,IAAIL,WAAWK,QAAQ9M,kBAAkB,SAAS;oBAC9C,IAAIyM,WAAWrJ,QAAQuJ,aAAaF,WAAWrJ,OAAO;wBAClD,OAAO;;;;YAKnB,OAAO;;QAGXnD,GAAG8M,SAAS,SAASC;YACjB,IAAI9D,OAAOO,QAAQe,OAAOjJ,UAAUkJ,SAASjJ,KAAKwL,eAAe,iBAAiB;gBAC9E,OAAO;;;QAIf/M,GAAGgN,uBAAuB;YACtB,IAAIC,QAAQC,SAASC,cAAc;YACnCF,MAAM9J,OAAO;YAEb,OACI8J,MAAMG,aAAa9M,oBACR2L,SAAS,sBACToB,aAAa,sBACZrN,GAAGsN,oBAAqBC,WAAW;;QAIvDvN,GAAGsN,oBAAoB;YACnB,IAAIrE,OAAOuE,gBAAgB;gBACvB,OAAO,IAAIA;;YAGf;gBACI,OAAO,IAAIC,cAAc;cAE7B,OAAOtL;gBACHnC,GAAGoC,IAAI,yCAAyC;gBAChD,OAAO;;;QAIfpC,GAAG0N,wBAAwB,SAASC;YAChC,OAAOA,aAAaC,SAChBD,aAAaC,MAAMxJ,SAAS,KAC5BuJ,aAAaC,MAAM,GAAGC;;QAG9B7N,GAAG8N,0BAA0B;YACzB,QAAQ9N,GAAG+N,kBACP/N,GAAGgN,2BACFf,KAAK3K,UAAUxB,UAAUQ,aAAa2L,KAAK3K,UAAU0M,gBAAgB1N,aAAa2L,KAAK3K,UAAU2M,aAAa3N;;QAGvHN,GAAGkO,YAAY,SAASC,YAAYC,OAAOC;YACvC,IAAIC,SAASH,WAAWrO,SAASqO,WAAWF,YAAYE,WAAWH;YAEnE,OAAOM,OAAO/M,KAAK4M,YAAYC,OAAOC;;QAG1CrO,GAAGuO,mBAAmB,SAAS5D;YAC3B,IAAI6D,aAAa,IACbC,QAAQ,IAAIzE,WAAWW;YAE3B3K,GAAGY,KAAK6N,OAAO,SAAS7M,KAAK8M;gBACzB,IAAIC,eAAeD,IAAIlE,SAAS;gBAEhC,IAAImE,aAAavK,SAAS,GAAG;oBACzBuK,eAAe,MAAMA;;gBAGzBH,cAAcG;;YAGlB,OAAOH;;QAGXxO,GAAG4O,gBAAgB,SAASC,MAAMC,aAAa1K;YAC3C,IAAI2K,cAAc/O,GAAGkO,UAAUW,MAAMC,aAAaA,cAAc1K,SAC5D4K,aAAa,IAAIC,cACjBC,UAAU,IAAIlP,GAAGmP;YAErBH,WAAWI,SAAS;gBAChBF,QAAQG,QAAQrP,GAAGuO,iBAAiBS,WAAW5H;;YAGnD4H,WAAWM,UAAUJ,QAAQK;YAE7BP,WAAWQ,kBAAkBT;YAE7B,OAAOG;;QAGXlP,GAAGuG,SAAS,SAASW,OAAOuI,QAAQC;YAChC1P,GAAGY,KAAK6O,QAAQ,SAAS3O,MAAMV;gBAC3B,IAAIsP,gBAAgB1P,GAAGqK,SAASjK,MAAM;oBAClC,IAAI8G,MAAMpG,UAAUR,WAAW;wBAC3B4G,MAAMpG;;oBAEVd,GAAGuG,OAAOW,MAAMpG,OAAOV,KAAK;uBAE3B;oBACD8G,MAAMpG,QAAQV;;;YAItB,OAAO8G;;QAaXlH,GAAG2P,WAAW,SAASC,QAAQC;YAC3B,IAAIC,aACAxN,SAASuN,SAASC;YAEtB9P,GAAGY,KAAK0B,QAAQ,SAASyN,aAAaC;gBAClC,IAAIJ,OAAOG,iBAAiBzP,WAAW;oBACnCwP,OAAOC,eAAeH,OAAOG;;gBAGjCH,OAAOG,eAAeC;;YAG1B,OAAOJ;;QAMX5P,GAAG4J,UAAU,SAASqG,KAAKC,KAAKC;YAC5B,IAAIF,IAAIrG,SAAS;gBACb,OAAOqG,IAAIrG,QAAQsG,KAAKC;;YAG5BA,OAAOA,QAAQ;YACf,IAAIC,MAAMH,IAAI7L;YAEd,IAAI+L,OAAO,GAAG;gBACVA,QAAQC;;YAGZ,MAAOD,OAAOC,KAAKD,QAAQ,GAAG;gBAC1B,IAAIF,IAAII,eAAeF,SAASF,IAAIE,UAAUD,KAAK;oBAC/C,OAAOC;;;YAGf,QAAQ;;QAIZnQ,GAAGsQ,cAAc;YACb,OAAO,uCAAuCtJ,QAAQ,SAAS,SAASuJ;gBAEpE,IAAIC,IAAInK,KAAKoK,WAAW,KAAK,GAAGC,IAAIH,KAAK,MAAMC,IAAKA,IAAI,IAAM;gBAC9D,OAAOE,EAAElG,SAAS;;;QAM1BxK,GAAG2Q,KAAK;YACJ,OAAOC,UAAUC,UAAUjH,QAAQ,aAAa,KAC5CgH,UAAUC,UAAUjH,QAAQ,gBAAgB;;QAGpD5J,GAAG8Q,MAAM;YACL,OAAOF,UAAUC,UAAUjH,QAAQ,eAAe;;QAGtD5J,GAAG+Q,MAAM;YACL,OAAOH,UAAUC,UAAUjH,QAAQ,eAAe;;QAGtD5J,GAAGgR,OAAO;YACN,OAAOJ,UAAUC,UAAUjH,QAAQ,gBAAgB;;QAGvD5J,GAAGiR,OAAO;YACN,OAAOjR,GAAG2Q,QAAQC,UAAUC,UAAUjH,QAAQ,cAAc;;QAGhE5J,GAAGkR,OAAO;YACN,OAAON,UAAUC,UAAUjH,QAAQ,WAAW;;QAGlD5J,GAAGmR,SAAS;YACR,OAAOP,UAAUQ,WAAW9Q,aAAasQ,UAAUQ,OAAOxH,QAAQ,cAAc;;QAGpF5J,GAAGqR,SAAS;YACR,OAAOT,UAAUQ,WAAW9Q,aAAasQ,UAAUQ,OAAOxH,QAAQ,eAAe;;QAGrF5J,GAAGsR,QAAQ;YACP,OAAOV,UAAUQ,WAAW9Q,aAAasQ,UAAUQ,OAAOxH,QAAQ,cAAc;;QAGpF5J,GAAGuR,UAAU;YACT,QAASvR,GAAGkR,WAAWlR,GAAGiR,UAAUL,UAAUC,UAAUjH,QAAQ,gBAAgB,KAAKgH,UAAUQ,WAAW9Q,aAAasQ,UAAUQ,WAAW;;QAGhJpR,GAAGwR,UAAU;YACT,OAAOZ,UAAUa,aAAa;;QAGlCzR,GAAG0R,UAAU;YACT,OAAOd,UAAUC,UAAU9Q,cAAc6J,QAAQ,gBAAgB;;QAKrE5J,GAAG+N,eAAe;YACd,OAAO/N,GAAG0R,aAAad,UAAUC,UAAU9Q,cAAc6J,QAAQ,YAAY;;QAGjF5J,GAAG2R,OAAO;YACN,OAAO3R,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,eAAe;;QAGlE5J,GAAG6R,OAAO;YACN,OAAO7R,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,eAAe;;QAGlE5J,GAAG8R,OAAO;YACN,OAAO9R,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,eAAe;;QAIlE5J,GAAG+R,SAAS;YACR,OAAO/R,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,iBAAiB;;QAGpE5J,GAAG4R,MAAM;YAEL,OAAOhB,UAAUC,UAAUjH,QAAQ,aAAa,KACzCgH,UAAUC,UAAUjH,QAAQ,aAAa,KACzCgH,UAAUC,UAAUjH,QAAQ,eAAe;;QAGtD5J,GAAGgS,YAAY;YACX,OAAOhS,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,cAAc;;QAGjE5J,GAAGiS,YAAY;YACX,OAAOjS,GAAG4R,UAAU5R,GAAGgS,eAAepB,UAAUC,UAAUjH,QAAQ,eAAe;;QAGrF5J,GAAGkS,mBAAmB;YAClB,OAAOlS,GAAG4R,UAAU5R,GAAGgS,gBAAgBhS,GAAGiS;;QAM9CjS,GAAGmS,iBAAiB,SAASC;YACzB,IAAIA,EAAED,gBAAgB;gBAClBC,EAAED;mBACC;gBACHC,EAAEC,cAAc;;;QAQxBrS,GAAGsS,YAAa;YACZ,IAAIC,MAAMrF,SAASC,cAAc;YACjC,OAAO,SAASqF;gBACZD,IAAIE,YAAYD;gBAChB,IAAI9P,UAAU6P,IAAI5K;gBAClB4K,IAAIxM,YAAYrD;gBAChB,OAAOA;;;QAKf1C,GAAGY,OAAO,SAAS8R,cAAcC;YAC7B,IAAIC,YAAYpP;YAEhB,IAAIkP,cAAc;gBAEd,IAAIzJ,OAAO4J,WAAWH,aAAa9H,gBAAgB3B,OAAO4J,SAAS;oBAC/D,KAAKD,aAAa,GAAGA,aAAaF,aAAatO,QAAQwO,cAAc;wBACjEpP,SAASmP,SAASD,aAAavS,IAAIyS,aAAaF,aAAaI,QAAQJ,aAAavS,IAAIyS;wBACtF,IAAIpP,WAAW,OAAO;4BAClB;;;uBAMP,IAAIxD,GAAG6C,QAAQ6P,iBAAiB1S,GAAG6K,WAAW6H,iBAAiB1S,GAAG+K,WAAW2H,eAAe;oBAC7F,KAAKE,aAAa,GAAGA,aAAaF,aAAatO,QAAQwO,cAAc;wBACjEpP,SAASmP,SAASC,YAAYF,aAAaE;wBAC3C,IAAIpP,WAAW,OAAO;4BAClB;;;uBAIP,IAAIxD,GAAGmL,SAASuH,eAAe;oBAChC,KAAKE,aAAa,GAAGA,aAAaF,aAAatO,QAAQwO,cAAc;wBACjEpP,SAASmP,SAASC,YAAYF,aAAa9S,OAAOgT;wBAClD,IAAIpP,WAAW,OAAO;4BAClB;;;uBAIP;oBACD,KAAKoP,cAAcF,cAAc;wBAC7B,IAAInI,OAAOjJ,UAAU+O,eAAe9O,KAAKmR,cAAcE,aAAa;4BAChEpP,SAASmP,SAASC,YAAYF,aAAaE;4BAC3C,IAAIpP,WAAW,OAAO;gCAClB;;;;;;;QASxBxD,GAAG+S,OAAO,SAASC,SAASC;YACxB,IAAIjT,GAAGyK,WAAWuI,UAAU;gBACxB,IAAIpO,OAAQvD,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW;gBAElD,OAAO;oBACH,IAAI0R,UAAUlT,GAAGuG,WAAW3B;oBAC5B,IAAIpD,UAAU4C,QAAQ;wBAClB8O,UAAUA,QAAQC,OAAO9R,MAAMC,UAAUxB,MAAMyB,KAAKC;;oBAExD,OAAOwR,QAAQhR,MAAMiR,SAASC;;;YAItC,MAAM,IAAIhN,MAAM;;QAmBpBlG,GAAGoT,UAAU,SAASC,KAAKC,MAAMC;YAE7B,IAAIC,iBACAC,SAAS,KACTC,MAAM,SAASC,SAASC;gBACpB,IAAIC,WAAWP,OACR,QAAQ1M,KAAK0M,QACdA,OACAA,OAAO,MAAMM,IAAI,MACjBA;gBACN,IAAKC,aAAa,eAAiBD,MAAM,aAAc;oBACnDJ,WAAW1R,YACC6R,YAAY,WACd3T,GAAGoT,QAAQO,SAASE,UAAU,QAC7BtJ,OAAOjJ,UAAUkJ,SAASjJ,KAAKoS,aAAa,sBAC7CG,mBAAmBD,YAAY,MAAMC,mBAAmBH,aACxDG,mBAAmBD,YAAY,MAAMC,mBAAmBH;;;YAK9E,KAAKJ,cAAcD,MAAM;gBACrBG,SAAU,KAAK7M,KAAK0M,QAAU,MAAM1M,KAAK0M,QAAS,KAAK,MAAM;gBAC7DE,WAAW1R,KAAKwR;gBAChBE,WAAW1R,KAAK9B,GAAGoT,QAAQC;mBACxB,IAAK9I,OAAOjJ,UAAUkJ,SAASjJ,KAAK8R,SAAS,2BAA6BA,QAAQ,aAAc;gBACnGrT,GAAGY,KAAKyS,KAAK,SAASzR,KAAKxB;oBACvBsT,IAAItT,KAAKwB;;mBAEV,WAAYyR,QAAQ,eAAiBA,QAAQ,eAAiBA,QAAQ,UAAW;gBACpFrT,GAAGY,KAAKyS,KAAK,SAASvS,MAAMV;oBACxBsT,IAAItT,KAAKU;;mBAEV;gBACH0S,WAAW1R,KAAKgS,mBAAmBR,QAAQ,MAAMQ,mBAAmBT;;YAGxE,IAAIC,MAAM;gBACN,OAAOE,WAAWO,KAAKN;mBACpB;gBACH,OAAOD,WAAWO,KAAKN,QAClBzM,QAAQ,MAAM,IACdA,QAAQ,QAAQ;;;QAI7BhH,GAAGgU,eAAe,SAASX,KAAKY,UAAUC;YACtC,KAAKD,UAAU;gBACXA,WAAW,IAAI5G;;YAGnBrN,GAAGY,KAAKyS,KAAK,SAASlT,KAAKC;gBACvBD,MAAM+T,eAAeA,eAAe,MAAM/T,MAAM,MAAMA;gBAEtD,IAAIH,GAAGqK,SAASjK,MAAM;oBAClBJ,GAAGgU,aAAa5T,KAAK6T,UAAU9T;uBAE9B,IAAIH,GAAGyK,WAAWrK,MAAM;oBACzB6T,SAAS3K,OAAOnJ,KAAKC;uBAEpB;oBACD6T,SAAS3K,OAAOnJ,KAAKC;;;YAI7B,OAAO6T;;QAGXjU,GAAGmU,aAAa,SAASd,KAAKe;YAC1B,IAAInH;YAEJ,KAAKmH,MAAM;gBACPA,OAAOlH,SAASC,cAAc;;YAGlCnN,GAAGgU,aAAaX;gBACZ/J,QAAQ,SAASnJ,KAAKC;oBAClB6M,QAAQC,SAASC,cAAc;oBAC/BF,MAAMoH,aAAa,QAAQlU;oBAC3B8M,MAAMoH,aAAa,SAASjU;oBAC5BgU,KAAKE,YAAYrH;;;YAIzB,OAAOmH;;QAOXpU,GAAGuU,YAAY,SAASC;YAEpB,IAAIvL,OAAOwL,QAAQzU,GAAGyK,WAAWgK,KAAKC,QAAQ;gBAC1C,OAAOD,KAAKC,MAAMF;mBACf;gBACH,OAAOG,KAAK,MAAMH,OAAO;;;QAUjCxU,GAAG4U,eAAe,SAASC;YACvB,IAAIC,SAASD,SAASE,YAAY,OAAO;YAEzC,IAAID,SAAS,GAAG;gBACZ,OAAOD,SAASG,OAAOF,QAAQD,SAASzQ,SAAS0Q;;;QAIzD9U,GAAGiV,cAAc,SAASC;YAGtB,IAAIlV,GAAGuM,QAAQ2I,kBAAkB;gBAE7B,OAAOA,gBAAgBxK,MAAM1D,QAAQ,aAAa;mBAEjD,IAAIhH,GAAG+L,OAAOmJ,kBAAkB;gBACjC,IAAIA,gBAAgBC,aAAa,QAAQD,gBAAgBC,aAAa7U,WAAW;oBAC7E,OAAO4U,gBAAgBC;;;YAI/B,OAAOD,gBAAgBlU;;QAM3BhB,GAAGoV,iBAAiB;YAChB,IAAIC;YAEJ;gBAEIC,SAAS;oBACL,IAAIC;oBACJ,GAAG;wBACCA,WAAWF,UAAUG;wBACrB,IAAID,UAAU;4BACVA;;6BAGDA;;gBAIXrQ,QAAQ;oBACJ,IAAIN,OAAOpD;oBAEXS,KAAKwT,YAAYzV,GAAG4E,KAAK,IAAIM,OAAOlD,MAAMC,MAAMZ,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW;;gBAI1FiU,aAAa,SAASC;oBAClBL,UAAUvT,KAAK4T;;;;;KCt2B9B;QACG;QACA,WAAWC,WAAW,cAAcA,OAAOC,KAAK;YAC5CD,OAAO;gBACH,OAAO3V;;eAGV,WAAW6V,WAAW,eAAeA,OAAOC,SAAS;YACtDD,OAAOC,UAAU9V;eAEhB;YACDpB,OAAOoB,KAAKA;;;KCRnB;QACG;QAEAA,GAAGkG,QAAQ,SAAS7D;YAChBJ,KAAKI,UAAU,oBAAoBrC,GAAG+V,UAAU,OAAO1T;;QAG3DrC,GAAGkG,MAAM5E,YAAY,IAAI4E;;ICV7BlG,GAAG+V,UAAU;ICAb/V,GAAGgW,oBAAqB;QACpB;QAEA,IAAIC,mBACAC,wBACAC,kBACAC,2BACAC,oBACAC,kBACAC,gBACAC,wBACAC,oBACAC,uBACAC,2BACAC,wBACAC,yBACAC,uBACAC;QAEJ,SAASC;YACL,IAAIC,YAAY,MACZC;YAEJ;gBACIA,YAAYhK,SAASC,cAAc;gBACnC+J,UAAU/T,OAAO;gBACjBnD,GAAGkX,WAAWnS;gBAEd,IAAImS,UAAUC,UAAU;oBACpBF,YAAY;;cAGpB,OAAOG;gBACHH,YAAY;;YAGhB,OAAOA;;QAIX,SAASI;YACL,QAAQrX,GAAGqR,YAAYrR,GAAGsR,YACtBV,UAAUC,UAAUzN,MAAM,2CAA2C9C;;QAI7E,SAASgX;YACL,QAAQtX,GAAGqR,YAAYrR,GAAGsR,YACtBV,UAAUC,UAAUzN,MAAM,2CAA2C9C;;QAI7E,SAASiX;YACL,IAAItO,OAAOuE,gBAAgB;gBACvB,IAAIgK,MAAMxX,GAAGsN;gBAGb,OAAOkK,IAAIC,oBAAoBnX;;YAGnC,OAAO;;QAIX,SAASoX;YACL,OAAOzO,OAAO0O,mBAAmBrX;;QAKrC,SAASsX;YACL,IAAIL,6BAA6B;gBAC7B,OAAO;;YAGX,OAAOG;;QAGX,SAASG;YAEL,OAAO3K,SAASC,cAAc,SAAS2K,oBAAoBxX;;QAG/D,SAASyX;YACL;gBACI,SAAS9O,OAAO+O,gBAEZhY,GAAGyK,WAAWxB,OAAO+O,aAAaC;cAE1C,OAAO9V;gBAEH,OAAO;;;QAIf,SAAS+V;YACL,IAAIC,OAAOjL,SAASC,cAAc;YAElC,QAAQ,eAAegL,QAAS,iBAAiBA,QAAQ,YAAYA,UAChEnY,GAAG0R,cAAc1R,GAAG4R;;QAG7BqE,oBAAoBe;QAEpBZ,4BAA4BH,qBAAqBjW,GAAGgN;QAEpDkJ,yBAAyBE,8BAA8BpW,GAAG+N;QAE1DoI,mBAAmBC,6BAA6B8B;QAEhD7B,qBAAqBF,oBAAoBkB;QAEzCf,mBAAmBF,6BAA6BpW,GAAG8N;QAEnDyI,iBAAiBH,6BAA6BE,oBAAoByB;QAElEvB,yBAAyBJ,6BAA6BkB;QAEtDb,qBAAqBR,sBAAsBhN,OAAOmP,gBAAgB9X,aAAa8V;QAE/EO,4BAA4BY;QAE5Bb,wBAAwBgB;QAExBd,yBAAyBgB;QAEzBf,0BAA0BgB;QAE1Bf,wBAAwBV,6BAA6BnN,OAAOgG,eAAe3O;QAE3EyW,yBAA0B;YACtB,IAAIX,2BAA2B;gBAC3B,QAAQpW,GAAG+N,mBAAmB/N,GAAGgS;;YAErC,OAAO;;QAGX;YACIqG,eAAejC;YACfkC,eAAepC;YACfqC,kBAAkBnC;YAClBoC,UAAUlC;YACVmC,gBAAgB7B;YAChB8B,mBAAmBhC;YACnBiC,mBAAmBhC;YACnBiC,iBAAiB3P,OAAO4P;YACxBC,UAAU3C;YACV4C,YAAY1C;YACZ2C,iBAAiBnC;YACjBoC,eAAenC;YACfoC,iBAAiBpC;YACjBqC,oBAAoB/C;YACpBgD,OAAO9C;YACP+C,aAAatC;YACbuC,QAAQ/C;YACRgD,SAASzC,yBAAyBZ;YAClCsD,cAAcxZ,GAAGmR;YACjBsI,2BAA2BzZ,GAAG4R;YAC9B8H,WAAWzD;YACX0D,YAAYlD;YACZmD,qBAAqBxD;YACrByD,oBAAoBzD;YACpB0D,gBAAgBtD;;;IChKxBxW,GAAG+Z,mBAAmB,SAASC;QAC3B;QACA,UAAUA,gBAAgBA,aAAaC,QAAQja,GAAGyK,WAAWuP,aAAaC;;IAG9Eja,GAAGmP,UAAU;QACT;QAEA,IAAI+K,aAAaC,aACbC,uBACAC,uBACAC,oBACAC,QAAQ;QAEZva,GAAGuG,OAAOtE;YACNgY,MAAM,SAASO,WAAWC;gBACtB,IAAIF,UAAU,GAAG;oBACb,IAAIC,WAAW;wBACXJ,iBAAiBtY,KAAK0Y;;oBAE1B,IAAIC,WAAW;wBACXJ,iBAAiBvY,KAAK2Y;;uBAGzB,IAAIF,WAAW,GAAG;oBACnBE,aAAaA,UAAUzY,MAAM,MAAMmY;uBAElC,IAAIK,WAAW;oBAChBA,UAAUxY,MAAM,MAAMkY;;gBAG1B,OAAOjY;;YAGXyY,MAAM,SAAS/H;gBACX,IAAI4H,UAAU,GAAG;oBACbD,cAAcxY,KAAK6Q;uBAElB;oBACDA,SAAS3Q,MAAM,MAAMmY,gBAAgB7Z,YAAY4Z,cAAcC;;gBAGnE,OAAOlY;;YAGXoN,SAAS;gBACLkL,QAAQ;gBACRL,cAAc1Y;gBAEd,IAAI4Y,iBAAiBhW,QAAQ;oBACzBpE,GAAGY,KAAKwZ,kBAAkB,SAASxY,KAAK+Q;wBACpCA,SAAS3Q,MAAM,MAAMkY;;;gBAI7B,IAAII,cAAclW,QAAQ;oBACtBpE,GAAGY,KAAK0Z,eAAe,SAAS1Y,KAAK+Q;wBACjCA,SAAS3Q,MAAM,MAAMkY;;;gBAI7B,OAAOjY;;YAGXsN,SAAS;gBACLgL,SAAS;gBACTJ,cAAc3Y;gBAEd,IAAI6Y,iBAAiBjW,QAAQ;oBACzBpE,GAAGY,KAAKyZ,kBAAkB,SAASzY,KAAK+Q;wBACpCA,SAAS3Q,MAAM,MAAMmY;;;gBAI7B,IAAIG,cAAclW,QAAQ;oBACtBpE,GAAGY,KAAK0Z,eAAe,SAAS1Y,KAAK+Q;wBACjCA,SAAS3Q,MAAM,MAAMmY;;;gBAI7B,OAAOlY;;;;IC3EnBjC,GAAG2a,YAAY,SAASC,eAAeC;QACnC;QAEA7a,GAAGuG,OAAOtE;YACN2Y,eAAeA;YAEfE,QAAQ;gBACJ,OAAOD,SAASD;;;;ICF5B5a,GAAG+a,eAAe,SAASC;QACvB;QAEA,IAAIjX,OAAO9B,MAEPgZ,iBAAiB,IAAIjb,GAAGoV,kBAExBnW;YAEIic,aAAa;YAGbxY,SAAS;YAETyY,YAAY;YAGZC,SAAS;YAGTC,YAAY;YAEZC,4BAA4B;YAG5BlO,UAAU;YAGVpM,MAAM;YAGNua,UAAU,SAAStO;YAEnBuO,OAAO;WAEXvO,OAAOwO;QAGXzb,GAAGuG,OAAOtH,SAAS+b;QAEnBS,WAAWzb,GAAGsQ;QAGd,SAASoL;YACL,IAAIzO,QAAQC,SAASC,cAAc;YAEnCF,MAAMoH,aAAarU,GAAG+a,aAAaY,qBAAqBF;YACxDxO,MAAMoH,aAAa,SAASpV,QAAQuc;YAEpCzX,KAAK6X,YAAY3c,QAAQmO,UAAUH;YAEnC,IAAIhO,QAAQmc,WAAWpb,GAAGgW,kBAAkBgD,iBAAiB;gBAEzD/L,MAAMoH,aAAa,mBAAmB;;YAG1C,IAAIpV,QAAQic,aAAa;gBACrBjO,MAAMoH,aAAa,UAAUpV,QAAQic;;YAGzCjO,MAAMoH,aAAa,QAAQ;YAC3BpH,MAAMoH,aAAa,QAAQpV,QAAQ+B;YAEnChB,GAAGiN,OAAOjH;gBACN6V,UAAU;gBAIVC,OAAO;gBACPC,KAAK;gBACLC,YAAY;gBASZC,UAAUjc,GAAG2Q,SAAS3Q,GAAG+Q,QAAQ,WAAW;gBAC5CmL,QAAQ;gBACRC,SAAS;gBACTC,QAAQ;gBACRjW,SAAS;;aAKZnG,GAAG8Q,SAAS9Q,GAAGiN,OAAOjH;gBAAKqW,QAAQ;;YAEpCpd,QAAQyD,QAAQ4R,YAAYrH;YAE5BgO,eAAe/V,OAAO+H,OAAO,UAAU;gBACnChO,QAAQsc,SAAStO;;YAIrBgO,eAAe/V,OAAO+H,OAAO,aAAa;gBACtCjN,GAAGf,QAAQyD,SAASoE,SAAS7H,QAAQoc;;YAEzCJ,eAAe/V,OAAO+H,OAAO,YAAY;gBACrCjN,GAAGf,QAAQyD,SAASqE,YAAY9H,QAAQoc;;YAG5CJ,eAAe/V,OAAO+H,OAAO,SAAS;gBAClCjN,GAAGf,QAAQyD,SAASoE,SAAS7H,QAAQkc;;YAEzCF,eAAe/V,OAAO+H,OAAO,QAAQ;gBACjCjN,GAAGf,QAAQyD,SAASqE,YAAY9H,QAAQkc;;YAG5C,OAAOlO;;QAIXjN,GAAGf,QAAQyD,SAASsD;YAChB6V,UAAU;YACVS,UAAU;YAEVC,WAAW;;QAIfvc,GAAGuG,OAAOtE;YACNua,UAAU;gBACN,OAAOvP;;YAGXwP,aAAa;gBACT,OAAOhB;;YAGXG,aAAa,SAASc,YAAYC;gBAC9B,IAAI1P,QAAQ0P,YAAY1a,KAAKua;gBAK7B,IAAIvd,QAAQqc,8BAA8Btb,GAAG8R,WAAW9R,GAAGgS,eAAehS,GAAGkS,qBAAqB;oBAC9FjF,MAAMoH,aAAa,YAAY;uBAG9B;oBACD,IAAIqI,YAAY;wBACZzP,MAAMoH,aAAa,YAAY;2BAE9B;wBACDpH,MAAM2P,gBAAgB;;;;YAKlCC,gBAAgB,SAAS3B;gBACrB,IAAIA,gBAAgBjc,QAAQic,aAAa;oBACrCjO,MAAMoH,aAAa,UAAU6G;;;YAIrC4B,OAAO;gBACH,IAAI7P,MAAMpH,YAAY;oBAClB7F,GAAGiN,OAAOnH;;gBAGd9F,GAAGf,QAAQyD,SAASqE,YAAY9H,QAAQkc;gBACxClO,QAAQ;gBACRA,QAAQyO;;;QAIhBzO,QAAQyO;;IAGZ1b,GAAG+a,aAAaY,sBAAsB;ICxLtC3b,GAAG+c,aAAa,SAASC;QACrB;QAEA,IAAI3c,WACA4c,aACAC,eACAC,qBACAC;QAEJ,SAASC,aAAaC;YAClB,IAAItd,GAAG6C,QAAQya,UAAU;gBACrB,IAAIC;gBAEJvd,GAAGY,KAAK0c,SAAS,SAAS1b,KAAK4b;oBAC3BD,QAAQzb,KAAKzB,KAAKmd;;gBAGtB,OAAOD;;YAGX,OAAOld,KAAKid;;QAGhB,SAASG,eAAeC;YACpB,IAAI1d,GAAG6C,QAAQ6a,QAAQ;gBACnB,IAAIH;gBAEJvd,GAAGY,KAAK8c,OAAO,SAAS9b,KAAK+b;oBACzBJ,QAAQzb,KAAKzB,KAAK4c,OAAOU;;gBAG7B,OAAOJ;;YAGX,OAAOld,KAAK4c,OAAOS;;QAGvB,SAASE,gBAAgBC;YACrB,IAAIC,oBACAC,cAAc5K,OAAO0K;YAEzB7d,GAAGY,KAAKmd,UAAU,SAAS7Z,OAAO8Z;gBAC9B,IAAIC,sBAAsBf,SAASc;gBAEnC,IAAIC,wBAAwB3d,WAAW;oBACnCN,GAAGY,KAAKqd,qBAAqB,SAASrK,GAAGsK;wBACrCJ,cAAchc,KAAKzB,KAAK6d;;;;YAKpC,OAAOJ;;QAGX9d,GAAGuG,OAAOtE;YAeNkc,SAAS,SAASC;gBACd,IAAIP,SAASO,KAAKP,UAAU7d,GAAG6d,OAAOQ,YAClCb,KAAKnd,KAAKyB;oBACNd,MAAMod,KAAKpd;oBACXsd,cAAcF,KAAKpd;oBACnB2c,MAAMS,KAAKT;oBACXY,MAAMH,KAAKG,QAAQ,QAAQ,IAAIH,KAAKG;oBACpCV,QAAQA;qBACP;gBAET,IAAIO,KAAKI,SAAS;oBACdne,KAAKmd,IAAIgB,UAAUJ,KAAKI;oBAExB,IAAIpB,UAAUgB,KAAKI,aAAale,WAAW;wBACvC8c,UAAUgB,KAAKI;;oBAEnBpB,UAAUgB,KAAKI,SAAS1c,KAAK0b;;gBAGjC,IAAIY,KAAKK,cAAc;oBACnBpe,KAAKmd,IAAIiB,eAAeL,KAAKK;oBAE7B,IAAItB,eAAeiB,KAAKK,kBAAkBne,WAAW;wBACjD6c,eAAeiB,KAAKK;;oBAExBtB,eAAeiB,KAAKK,cAAc3c,KAAK0b;;gBAG3Cnd,KAAKmd,IAAIA,KAAKA;gBACdP,OAAOmB,KAAKT,QAAQH;gBAEpB,IAAIN,SAASW,YAAYvd,WAAW;oBAChC4c,SAASW;;gBAEbX,SAASW,QAAQ/b,KAAK0b;gBAEtBR,cAAc0B,eAAelB,IAAI,MAAMK;gBAEvC,OAAOL;;YAGXmB,UAAU,SAASC;gBACf,IAAI5e,GAAGqK,SAASuU,mBAAmBve,KAAK+D,QAAS;oBAC7C,IAAIwa,eAAepB,OAAOld,WAAW;wBACjC,OAAO+c,aAAauB,eAAepB;2BAGlC,IAAIoB,eAAejB,SAASrd,WAAW;wBACxC,OAAOmd,eAAemB,eAAejB;2BAGpC,IAAIiB,eAAef,QAAQ;wBAC5B,OAAOD,gBAAgBgB,eAAef;;uBAGzC;oBACD,OAAO7d,GAAGuG,WAAWlG,MAAM;;;YAInCyc,OAAO;gBACHzc;gBACA4c;gBACAC;gBACAE;;YAGJyB,WAAW,SAASrB,IAAIsB;gBACpB,IAAIC,YAAY1e,KAAKmd,IAAIK,QACrBmB,yBAAyBhf,GAAG4J,QAAQsT,SAAS6B,YAAYvB;gBAE7DN,SAAS6B,WAAWE,OAAOD,wBAAwB;gBAEnD3e,KAAKmd,IAAIK,SAASiB;gBAElB,IAAI5B,SAAS4B,eAAexe,WAAW;oBACnC4c,SAAS4B;;gBAEb5B,SAAS4B,WAAWhd,KAAK0b;gBAEzBR,cAAc0B,eAAelB,IAAIuB,WAAWD;;YAGhDI,aAAa,SAAS1B,IAAI2B;gBACtB,IAAIC,UAAU/e,KAAKmd,IAAIG;gBAEvBtd,KAAKmd,IAAIG,OAAOwB;gBAChBlC,OAAOkC,WAAW3B;uBACXP,OAAOmC;;YAGlBC,YAAY,SAAS7B,IAAI8B;gBACrBjf,KAAKmd,IAAIxc,OAAOse;;YAGpBC,YAAY,SAAS/B,IAAIgC;gBACrBnf,KAAKmd,IAAIe,OAAOiB;;YAIpBC,aAAa,SAASC,UAAUC;gBAC5Btf,KAAKqf,UAAUC,WAAWA;;YAG9BC,oBAAoB,SAASpC;gBACzB,IAAIiB,eAAepe,KAAKmd,IAAIiB;gBAE5B,IAAIA,cAAc;oBACd,OAAOtB,eAAesB;;gBAE1B;;YAGJoB,eAAe,SAASrC;gBACpB,IAAIgB,UAAUne,KAAKmd,IAAIgB;gBAEvB,OAAOpB,UAAUoB;;;;IAK7Bxe,GAAG6d;QACCQ,YAAY;QACZyB,WAAW;QACXC,UAAU;QACVC,QAAQ;QACRC,UAAU;QACVC,QAAQ;QACRC,WAAW;QACXC,iBAAiB;QACjBC,mBAAmB;QACnBC,eAAe;QACfC,eAAe;QACfC,UAAU;QACVC,SAAS;;KCxMZ;QACG;QAEAzgB,GAAG0gB;YAECC,UAAU,SAASC,iBAAiBphB,QAAQqhB;gBACxC5e,KAAK6e,SAASF,iBAAiBphB,QAAQqhB;;YAG3CE,iBAAiB,SAASC;gBACtB,IAAIjd,OAAO9B;gBAEXjC,GAAGY,KAAKogB,gBAAgB,SAAS9c,OAAO+c;oBACpCld,KAAKmd,eAAeD;;;YAI5BH,UAAU,SAASzgB,MAAMb,QAAQqhB;gBAC7B5e,KAAKkf;gBAEL,IAAI3C,UAAUvc,KAAKmf,WAAWhd,WAAW,IAAIpE,GAAGsQ,gBAAgBrO,KAAKof,iBAEjEC,cAActhB,GAAG+S,KAAK,SAASlE;oBAC3B5M,KAAKsf;wBACD1S,MAAMA;wBACN7N,MAAMiB,KAAKpB,SAAS2gB,MAAMC;uBAC3BjD,SAASkD;mBACbzf,OAEH0f,kBAAkB3hB,GAAG+S,KAAK,SAAS6O;oBAC/B3f,KAAKsf,eAAeK,UAAUpD,SAASkD;mBACxCzf,OAEH4f,gBAAgB7hB,GAAG+S,KAAK,SAASxK;oBAC7B,IAAIsG,OAAO7O,GAAGsI,aAAaC;oBAE3BtG,KAAKsf;wBACD1S,MAAMA;wBACN7N,MAAMiB,KAAKpB,SAAS2gB,MAAMC,cAAc;uBACzCjD,SAASkD;mBACbzf,OAEH6f,oBAAoB9hB,GAAG+S,KAAK,SAASgP;oBACjC,IAAIC,oBAAoBD,WAAWtZ,WAAWsZ,WAAWtZ,UAAU,KAC/DoG,OAAO7O,GAAGsI,aAAayZ,WAAWxZ,QAAQwZ,WAAW5e,MAAM6e;oBAE/D/f,KAAKsf;wBACD1S,MAAMA;wBACN7N,MAAM+gB,WAAW/gB;uBAClBwd,SAASkD;mBACbzf,OAEHggB,qBAAqBjiB,GAAG+S,KAAK,SAASmP;oBAClC,IAAIliB,GAAGuM,QAAQ2V,gBAAgBliB,GAAGgW,kBAAkBqC,eAAe;wBAC/D,IAAI8J,QAAQ9gB,MAAMC,UAAUxB,MAAMyB,KAAK2gB,YAAYC,QAC/Cpe,OAAO9B;wBAEXjC,GAAGY,KAAKuhB,OAAO,SAASvgB,KAAKwgB;4BACzBre,KAAKwd,eAAea,MAAM5D,SAASkD;;2BAGtC;wBACDzf,KAAKsf,eAAeW,aAAa1D,SAASkD;;mBAE/Czf,OAEHogB,gBAAgB;oBACZ,IAAIriB,GAAGkM,WAAW7L,OAAO;wBACrBA,OAAOgB,MAAMC,UAAUxB,MAAMyB,KAAKlB;;oBAEtCA,UAAU8S,OAAO9S;mBAGrB0D,OAAO9B,MACPyf;gBAEJzf,KAAKof,kBAAkB7C;gBAEvB,IAAIne,MAAM;oBACNgiB;oBAEAriB,GAAGY,KAAKP,MAAM,SAASuB,KAAK0gB;wBACxB,IAAItiB,GAAGqM,cAAciW,gBAAgB;4BACjCL,mBAAmBK;+BAElB,IAAItiB,GAAG8M,OAAOwV,gBAAgB;4BAC/BhB,YAAYgB;+BAEX,IAAItiB,GAAGqK,SAASiY,gBAAgB;4BACjC,IAAIA,cAAczT,QAAQyT,cAActhB,MAAM;gCAC1C2gB,gBAAgBW;mCAEf,IAAIA,cAAc/Z,UAAU+Z,cAActhB,MAAM;gCACjD8gB,kBAAkBQ;;+BAGrB,IAAIA,cAAczV,WAAWyV,cAAczV,QAAQ9M,kBAAkB,UAAU;4BAChF8hB,cAAcS;+BAEb;4BACDve,KAAK3B,IAAIkgB,gBAAgB,8CAA8C;;;oBAI/ErgB,KAAKG,IAAI,cAAcsf,cAActd,SAAS;oBAC9CnC,KAAKsgB,uBAAuBb,eAAeliB,QAAQqhB;;;YAI3D2B,QAAQ,SAAShF;gBACbvb,KAAKwgB,SAASD,OAAOhF;;YAGzBkF,WAAW;gBACP,IAAIC,oBACA5e,OAAO9B;gBAEXjC,GAAGuG,OAAOoc,eAAe1gB,KAAKmf;gBAC9BphB,GAAGY,KAAK+hB,eAAe,SAAS/gB,KAAKghB;oBACjC7e,KAAKye,OAAOI;;gBAGhB3gB,KAAKwgB,SAASC;;YAGlBG,kBAAkB;gBACd5gB,KAAKmf;;YAGT0B,gBAAgB,SAAStF;gBACrB,IAAIuF,aAAa9gB,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;;gBAEhD,KAAKxd,GAAGgW,kBAAkBoD,UAAUnX,KAAKpB,SAAS2X,SAASyK,SAAS;oBAChE,OAAO;;gBAGX,IAAIF,WAAWlF,WAAW7d,GAAG6d,OAAOqC,QAAQ;oBACxCje,KAAKG,IAAIpC,GAAGyL,OAAO,0DAA0D+R,IAAIvb,KAAKihB,QAAQ1F;oBAC9Fvb,KAAKkhB,YAAY3F;oBACjB,OAAO;uBAEN;oBACDvb,KAAKG,IAAIpC,GAAGyL,OAAO,uDAAuD+R,IAAIvb,KAAKihB,QAAQ1F,MAAM;;gBAGrG,OAAO;;YAGX4F,YAAY,SAAS5F;gBACjB,OAAOvb,KAAKohB,gBAAgB7F;;YAIhC8F,WAAW,SAASC;gBAChB,OAAOthB,KAAKwgB,SAASe,QAAQD;;YAOjCE,eAAe,SAASC,QAAQC,aAAaC,SAASC,YAAYC;gBAC9D,IAAIC,kBAAkB,IAAI/jB,GAAGmP,WACzB6U,WAAW/kB;gBAEf,IAAIgD,KAAKgiB,iBAAiB;oBACtBD,YAAY/hB,KAAKiiB,eAAeR;oBAChCzkB;wBACI6kB,sBAAsBA;wBACtBF,SAASA,UAAU,IAAIA,UAAU;wBACjCO,OAAOP,UAAU;;oBAKrB,KAAKC,cAAc7jB,GAAGgW,kBAAkBiD,eAAe;wBACnD+K,YAAY/hB,KAAKmiB,QAAQV;;oBAI7B,IAAIM,aAAa,MAAM;wBACnBD,gBAAgBxU;4BAAS8U,WAAWV;4BAAaxhB,OAAO;;2BAEvD;wBACDF,KAAKgiB,gBAAgBK,SAASN,WAAWL,aAAa1kB,SAASgb,KAC3D,SAAS5K,QAAQkV;4BACbR,gBAAgB1U,QAAQkV;2BAG5B,SAAShV,QAAQ8U,WAAWG;4BACxBT,gBAAgBxU;gCAAS8U,WAAWA;gCAAWliB,OAAOqiB,UAAU;;;;uBAK3E;oBACDT,gBAAgBxU;wBAAS8U,WAAWV;wBAAaxhB,OAAO;;;gBAG5D,OAAO4hB;;YAGXU,WAAW,SAASf;gBAChB,OAAOzhB,KAAKyiB,WAAWziB,KAAK0iB,qBAAqBjB;;YAGrDkB,aAAa,SAASlB;gBAClB,OAAOzhB,KAAK4iB,eAAeC,IAAIpB;;YAGnCU,SAAS,SAASb;gBACd,OAAOthB,KAAKwgB,SAAS2B,QAAQb,iBAAiB;;YAGlDwB,eAAe;gBACX,OAAO9iB,KAAK+gB,YAAYrE;oBACpBd,UACI7d,GAAG6d,OAAOsC,WACVngB,GAAG6d,OAAOuC,iBACVpgB,GAAG6d,OAAOmC;mBAEf5b;;YAGP8e,SAAS,SAAS1F;gBACd,OAAOvb,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;mBAAKxc;;YAI/CgkB,aAAa,SAASxH;gBAClB,IAAIyH,kBAAkBhjB,KAAKijB;oBAAY1H,IAAIA;oBACvCmC,WAAW;gBAEf,IAAIsF,iBAAiB;oBACjB,IAAIA,gBAAgBtF,aAAarf,WAAW;wBACxCqf,WAAWsF,gBAAgBtF;;;gBAInC,OAAOA;;YAGXwF,uBAAuB;gBACnB,OAAOljB,KAAKwgB,SAAS0C;;YAGzBC,SAAS,SAAS5H;gBACd,OAAOvb,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;mBAAKe;;YAG/C8G,eAAe;gBACX,OAAOpjB,KAAKqjB;;YAGhBC,0BAA0B;gBACtB,IAAIC,eAAevjB,KAAKwjB;gBAExB,IAAID,eAAe,GAAG;oBAClB,OAAOA,eAAevjB,KAAKyjB;;gBAG/B,OAAO;;YAGXR,YAAY,SAAStG;gBACjB,OAAO3c,KAAK+gB,YAAYrE,SAASC;;YAGrC+G,SAAS,SAASnI;gBACd,OAAOvb,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;mBAAKG;;YAG/Cvb,KAAK,SAASsJ,KAAKvB;gBACf,IAAIlI,KAAKpB,SAAS+kB,WAAWzb,SAASA,UAAU,SAAS;oBACrDnK,GAAGoC,IAAI,oBAAoBpC,GAAG+V,UAAU,OAAOrK;uBAE9C,IAAIvB,SAASA,UAAU,QAAQ;oBAChCnK,GAAGoC,IAAI,oBAAoBpC,GAAG+V,UAAU,OAAOrK,KAAKvB;;;YAK5D0b,aAAa,SAASrI;gBAClB,IAAIuF,aAAa9gB,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;;gBAEhD,KAAKxd,GAAGgW,kBAAkBoD,UAAUnX,KAAKpB,SAAS2X,SAASyK,SAAS;oBAChE,OAAO;;gBAIX,IAAIjjB,GAAG4J,UAAS5J,GAAG6d,OAAOsC,WAAWngB,GAAG6d,OAAOuC,mBAAkB2C,WAAWlF,WAAW,GAAG;oBACtF,IAAI5b,KAAKwgB,SAASrJ,MAAMoE,KAAK;wBACzBvb,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOqC;wBACzC,OAAO;2BAEN;wBACDje,KAAKG,IAAIpC,GAAGyL,OAAO,oCAAoC+R,IAAIvb,KAAKihB,QAAQ1F,MAAM;;uBAGjF;oBACDvb,KAAKG,IAAIpC,GAAGyL,OAAO,yDAAyD+R,IAAIvb,KAAKihB,QAAQ1F,MAAM;;gBAGvG,OAAO;;YAGXV,OAAO;gBACH7a,KAAKG,IAAI;gBAETH,KAAKwgB,SAAS3F;gBACd7a,KAAKmf;gBACLnf,KAAK6jB;gBACL7jB,KAAK8jB;gBACL9jB,KAAK+jB;gBACL/jB,KAAKiiB;gBAELlkB,GAAGY,KAAKqB,KAAKgkB,UAAU,SAASrkB,KAAKskB;oBACjCA,OAAOpJ;;gBAGX7a,KAAKkkB,aAAarJ;gBAClB7a,KAAK4iB,eAAe/H;gBACpB7a,KAAKyjB,uBAAuB;gBAC5BzjB,KAAKqjB,eAAe;gBACpBrjB,KAAK+gB,YAAYlG;gBACjB7a,KAAK0iB;gBAEL1iB,KAAKmkB,iBAAiBnkB,KAAKmkB,cAActJ;gBACzC7a,KAAKpB,SAASwlB,QAAQC,kBAAkBrkB,KAAKskB;gBAE7CtkB,KAAKukB;gBACLvkB,KAAKwkB;gBAELxkB,KAAKykB,kBAAkBzkB,KAAKykB,eAAe5J;;YAG/C6J,OAAO,SAASnJ;gBACZ,OAAOvb,KAAK2kB,aAAapJ;;YAG7BqJ,YAAY,SAASrJ,IAAIsJ;gBACrB,IAAI/iB,OAAO9B;gBAEX,OAAOjC,GAAG+mB,OAAOzlB,UAAUulB,WAAWrJ,IAAIsJ;oBACtC1kB,KAAKpC,GAAG+S,KAAKhP,KAAK3B,KAAK2B;oBACvBqgB,SAASpkB,GAAG+S,KAAKhP,KAAKqgB,SAASrgB;oBAC/Bgf,YAAYhf,KAAKif;;;YAIzBgE,kBAAkB,SAASC,SAASzJ;gBAChCvb,KAAKilB,oBAAoBC,IAAIF,SAASzJ;;YAG1C4J,4BAA4B,SAASH,SAASzJ;gBAC1Cvb,KAAKolB,8BAA8BF,IAAIF,SAASzJ;;YAGpD8J,uBAAuB,SAASzG,UAAUrD;gBACtCvb,KAAKslB,yBAAyBJ,IAAItG,UAAUrD;;YAGhDgK,qBAAqB,SAAShoB,QAAQge;gBAClCvb,KAAKwlB,uBAAuBN,IAAI3nB,QAAQge;;YAI5CkK,aAAa,SAAS7G,UAAUrD;gBAC5Bvb,KAAK4iB,eAAesC,IAAItG,UAAUrD;;YAGtCmK,SAAS,SAASC;gBACd3lB,KAAK4lB,4BAA4BD;;YAGrCE,cAAc,SAASC;gBACnB9lB,KAAKwjB,oBAAoBsC;;YAG7BC,SAAS,SAASxK,IAAI8B;gBAClBrd,KAAK+gB,YAAY3D,WAAW7B,IAAI8B;;YAGpC2I,WAAW,SAASzoB,QAAQge;gBACxBvb,KAAKkkB,aAAagB,IAAI3nB,QAAQge;;YAGlC0K,SAAS,SAAS1K,IAAI2B;gBAClB,OAAOld,KAAK+gB,YAAY9D,YAAY1B,IAAI2B;;YAG5CgJ,mBAAmB;gBACf,IAAIlmB,KAAKmf,WAAWhd,WAAW,GAAG;oBAC9BnC,KAAKmmB,WAAW;uBAEf;oBACDnmB,KAAKomB;;;;QAQjBroB,GAAGsoB;YAECpH,gBAAgB,SAASqH;gBACrB,IAAI/K,KAAKvb,KAAK+gB,YAAY7E;oBACtBR,MAAM4K,YAAY5K;oBAClB3c,MAAMunB,YAAYvnB;oBAClBud,MAAMgK,YAAYhK;oBAClBV,QAAQ7d,GAAG6d,OAAOwC;;gBAGtBkI,YAAYC,sBAAsBvmB,KAAKqlB,sBAAsBiB,YAAYC,oBAAoBhL;gBAC7F+K,YAAYE,oBAAoBxmB,KAAKulB,oBAAoBe,YAAYE,kBAAkBjL;gBAEvF,IAAI+K,YAAYG,cAAc;oBAC1BzmB,KAAKiiB,eAAe1G,MAAM+K,YAAYG;;gBAG1CzmB,KAAKqjB;gBACLrjB,KAAKyjB;gBAEL,OAAOlI;;YAGXmL,uBAAuB,SAASvG,MAAMwG;gBAClC,IAAI5oB,GAAG+L,OAAOqW,OAAO;oBACjBA,KAAKyG,aAAa5mB,KAAK6mB,aAAaF;;;YAI5CG,aAAa,SAAS1mB;gBAClBJ,KAAKpB,SAASF,UAAUqoB,QAAQ,MAAM,MAAM3mB,SAAS/B;;YAGzD2oB,sBAAsB;gBAClB,IAAIllB,OAAO9B;gBAEX,OAAO,IAAIjC,GAAGkpB;oBACVC,QAAQlnB,KAAKpB,SAASuiB,WAAW+F,OAAOtpB;oBACxCupB,gBAAgBnnB,KAAKpB,SAASuoB;oBAC9BC,eAAepnB,KAAKpB,SAASyoB,QAAQC;oBACrCC,eAAevnB,KAAKolB;oBACpBoC,aAAaxnB,KAAKwlB;oBAClBiC,eAAeznB,KAAKslB;oBACpBoC,MAAM1nB,KAAKpB,SAAS8oB;oBACpBvnB,KAAKpC,GAAG+S,KAAKhP,KAAK3B,KAAK2B;oBACvB6lB,UAAU,SAASpM;wBACfzZ,KAAK8lB,UAAUrM;wBACfzZ,KAAKlD,SAASF,UAAUipB,SAASpM;;oBAErCsM,kBAAkB,SAAStM,IAAIuM,UAAUC;wBACrCjmB,KAAKkmB,kBAAkBzM,IAAIuM,UAAUC;wBACrCjmB,KAAKlD,SAASF,UAAUmpB,iBAAiBtM,IAAIuM,UAAUC;;;;YAMnEE,qBAAqB;gBACjB,IAAInmB,OAAO9B;gBAEX,OAAO,IAAIjC,GAAGmqB;oBACVC,eAAenoB,KAAKpB,SAASwpB,MAAMD;oBACnCzpB;wBACIyB,KAAKpC,GAAG+S,KAAKhP,KAAK3B,KAAK2B;wBACvBumB,eAAe,SAASzb;4BACpB9K,KAAKwmB;gCACDvpB,MAAM;gCACN2R,UAAU3S,GAAG+S,KAAKhP,KAAKlD,SAASF,UAAU6pB,iBAAiBzmB,MAAM8K;gCACjE2L,WAAWxa,GAAG+S,KAAKhP,KAAK0mB,qBAAqB1mB,MAAM8K;gCACnD6b,YAAY;;;;;;YAOhCC,cAAc,SAASC,cAAcC;gBACjC,IAAIC,YACAC,WAAWH,cACXI,0BACAC,iBAAiBJ,kBACjBK,OAAO,SAASC;oBACZ,IAAInrB,GAAGqK,SAAS8gB,OAAO;wBACnB,OAAOnrB,GAAGuG,WAAW4kB;;oBAEzB,OAAOA;mBAEXC,oBAAoB;oBAChB,IAAIprB,GAAGyK,WAAWwgB,iBAAiB;wBAC/B,OAAOA;;oBAEX,OAAOA;mBAEXI,wBAAwB,SAAS7N,IAAI8N;oBACjC,IAAIL,kBAAkBjrB,GAAGqK,SAASihB,WAAW;wBACzCtrB,GAAGuG,OAAO+kB,UAAUF;;oBAGxB,IAAIJ,oBAAoBxN,KAAK;wBACzBxd,GAAGuG,OAAO+kB,UAAUN,oBAAoBxN;;;gBAIpD;oBACI2J,KAAK,SAAS/mB,KAAKod;wBAEf,IAAIA,MAAM,MAAM;4BACZsN;4BACAC,WAAWG,KAAK9qB;+BAEf;4BACD0qB,MAAMtN,MAAM0N,KAAK9qB;;;oBAIzB0kB,KAAK,SAAStH;wBACV,IAAI+N;wBAGJ,IAAI/N,MAAM,QAAQsN,MAAMtN,KAAK;4BACzB+N,SAAST,MAAMtN;+BAEd;4BACD+N,SAASL,KAAKH;;wBAGlBM,sBAAsB7N,IAAI+N;wBAE1B,OAAOL,KAAKK;;oBAGhBC,aAAa,SAAShO,IAAI+N;wBAEtB,IAAIvrB,GAAGqK,SAASygB,QAAQ;4BAEpB,IAAItN,OAAO,MAAM;gCACb,IAAIxd,GAAGyK,WAAW8gB,SAAS;oCACvBN,iBAAiBM;uCAEhB;oCACDN,iBAAiBA;oCACjBjrB,GAAGuG,OAAO0kB,gBAAgBM;;mCAG7B;gCACDP,oBAAoBxN,MAAMwN,oBAAoBxN;gCAC9Cxd,GAAGuG,OAAOykB,oBAAoBxN,KAAK+N;;;;oBAK/CzlB,QAAQ,SAAS4d;wBACb,cAAcoH,MAAMpH;;oBAGxB5G,OAAO;wBACHgO;wBACAE;wBACAD,WAAWH;;;;YAKvBa,0BAA0B;gBACtB,IAAI1nB,OAAO9B;gBAEX,OAAO,IAAIjC,GAAG+c;oBACVmG,SAAS,SAAS1F;wBACd,OAAOzZ,KAAKmf,QAAQ1F;;oBAExBmI,SAAS,SAASnI;wBACd,OAAOzZ,KAAK4hB,QAAQnI;;oBAExB4H,SAAS,SAAS5H;wBACd,OAAOzZ,KAAKqhB,QAAQ5H;;oBAExBkB,gBAAgB,SAASlB,IAAIuB,WAAWD;wBACpC/a,KAAK2nB,sBAAsBlO,IAAIuB,WAAWD;wBAC1C/a,KAAKlD,SAASF,UAAU+d,eAAelB,IAAIuB,WAAWD;wBACtD/a,KAAK4nB,kBAAkBnO,IAAIsB;wBAE3B,IAAI/a,KAAK2iB,gBAAgB;4BACrBkF,WAAW;gCACP7nB,KAAK2iB,eAAehI,eAAelB,IAAIuB,WAAWD;+BACnD;;;;;YAcnB+M,qBAAqB,SAASzN;gBAC1B,IAAIra,OAAO9B,MACPiZ,cAAckD,KAAK0N,UAAU7pB,KAAKpB,SAASkrB,WAAW7Q,aACtD8Q,oBAAoB5N,KAAK4N,qBAAqB/pB,KAAKpB,SAASkrB,WAAWC,mBACvE9F;gBAEJ,SAAS+F;oBACL,IAAIjsB,GAAGgW,kBAAkBqC,eAAe;wBAEpC,IAAItU,KAAKlD,SAASqrB,YAAYC,kBAC1BnsB,GAAG4R,UACF5R,GAAG2R,UACJ5N,KAAKqoB,oBAAoBJ,mBAAmB,SAAS;4BAErD,OAAO;;wBAGX,IAAI5N,KAAKhR,aAAa9M,WAAW;4BAC7B,OAAOyD,KAAKlD,SAASuM;;wBAGzB,OAAOgR,KAAKhR;;oBAGhB,OAAO;;gBAGX8Y,SAAS,IAAIlmB,GAAG+a;oBACZG,aAAaA;oBACbxY,SAAS0b,KAAK1b;oBACdyY,YAAYlZ,KAAKpB,SAASwrB,QAAQC;oBAClClR,SAASgD,KAAKhD;oBACdC,YAAYpZ,KAAKpB,SAASwrB,QAAQE;oBAClCjR,4BAA4BrZ,KAAKpB,SAASqrB,YAAYM;oBACtDpf,UAAU6e;oBACVjrB,MAAMiB,KAAKpB,SAASyoB,QAAQmD;oBAC5BlR,UAAU,SAAStO;wBACflJ,KAAK2oB,eAAezf;;oBAExBuO,OAAO4C,KAAK5C,SAAS,OAAOvZ,KAAKpB,SAASiH,KAAK6kB,iBAAiBvO,KAAK5C;;gBAGzEvZ,KAAK2qB,gBAAgBnX,YAAY;oBAC7ByQ,OAAO5Q;;gBAGXvR,KAAKkiB,SAASnkB,KAAKokB;gBAEnB,OAAOA;;YAGX2G,sBAAsB,SAASC,mBAAmBntB;gBAC9C,IAAIoE,OAAO9B,MACP8qB,qBACA9tB;oBACI2mB,OAAO3jB,KAAKpB,SAAS+kB;oBACrBwD,gBAAgBnnB,KAAKpB,SAASuoB;oBAC9BO,MAAM1nB,KAAKpB,SAAS8oB;oBACpBF,aAAaxnB,KAAKkkB;oBAClBuD,eAAeznB,KAAK4iB;oBACpBrM,UAAUvW,KAAKpB,SAAS2X;oBACxBc,QAAQrX,KAAKpB,SAASyY;oBACtBkI,OAAOvf,KAAKpB,SAAS2gB;oBACrBpf,KAAKpC,GAAG+S,KAAKhP,KAAK3B,KAAK2B;oBACvBipB,mBAAmB/qB,KAAKpB,SAAS8lB,MAAMsG;oBACvCC,YAAY,SAAS1P,IAAIxc,MAAMmsB,QAAQC;wBACnC,IAAID,SAAS,KAAKC,QAAQ,GAAG;4BACzB;;wBAGJ,IAAIL,eAAevP,KAAK;4BACpB,IAAIuP,eAAevP,IAAI2P,WAAWA,UAAUJ,eAAevP,IAAI4P,UAAUA,OAAO;gCAC5ErpB,KAAKspB,YAAY7P,IAAIxc,MAAMmsB,QAAQC;gCACnCrpB,KAAKlD,SAASF,UAAUusB,WAAW1P,IAAIxc,MAAMmsB,QAAQC;;+BAGxD;4BACDrpB,KAAKspB,YAAY7P,IAAIxc,MAAMmsB,QAAQC;4BACnCrpB,KAAKlD,SAASF,UAAUusB,WAAW1P,IAAIxc,MAAMmsB,QAAQC;;wBAGzDL,eAAevP;4BAAO2P,QAAQA;4BAAQC,OAAOA;;;oBAGjDE,YAAY,SAAS9P,IAAIxc,MAAMoG,QAAQoQ;+BAC5BuV,eAAevP;wBAEtB,IAAIK,SAAS9Z,KAAKmhB;4BAAY1H,IAAIA;2BAAKK,QACnCra;wBAMJ,IAAIqa,WAAW7d,GAAG6d,OAAOwC,qBAAqBxC,WAAW7d,GAAG6d,OAAOyC,eAAe;4BAC9E;;wBAGJ9c,SAASO,KAAKwpB,YAAY/P,IAAIxc,MAAMoG,QAAQoQ;wBAI5C,IAAIhU,kBAAmBxD,GAAGmP,SAAS;4BAC/B3L,OAAOkX,KAAK;gCACR3W,KAAKlD,SAASF,UAAU2sB,WAAW9P,IAAIxc,MAAMoG,QAAQoQ;;+BAGxD;4BACDzT,KAAKlD,SAASF,UAAU2sB,WAAW9P,IAAIxc,MAAMoG,QAAQoQ;;;oBAG7DgW,UAAU,SAAShQ,IAAIxc,MAAMysB;wBACzB,IAAIve,UAAU,IAAIlP,GAAGmP;wBAErBpL,KAAKwmB;4BACDvpB,MAAM;4BACN2R,UAAU3S,GAAG+S,KAAKhP,KAAKlD,SAASF,UAAU6sB,UAAUzpB,MAAMyZ,IAAIxc;4BAC9DyZ,WAAWvL,QAAQK;4BACnBiL,WAAW;gCACPiT,yBAAyBxT,KAAK;oCAC1BlW,KAAK2pB,UAAUlQ,IAAIxc;;gCAGvBkO,QAAQG;;4BAEZqb,YAAYlN;;wBAGhB,OAAOtO;;oBAEXye,cAAc3tB,GAAG+S,KAAK9Q,KAAK2rB,eAAe3rB;oBAC1C4rB,UAAU,SAASrQ,IAAIxc;wBACnB+C,KAAK+pB,UAAUtQ,IAAIxc;wBACnB+C,KAAKlD,SAASF,UAAUktB,SAASrQ,IAAIxc;;oBAEzC+sB,eAAe,SAASvQ,IAAIxc,MAAMgtB;wBAC9BjqB,KAAKkqB,eAAezQ,IAAIwQ;wBACxBjqB,KAAKlD,SAASF,UAAUotB,cAAcvQ,IAAIxc,MAAMgtB;;oBAEpDE,sBAAsB,SAAS1Q,IAAIwQ,WAAW5mB,QAAQoQ;wBAClDzT,KAAKlD,SAASF,UAAUutB,qBAAqBlsB,MAAM+B,MAAMvC;;oBAE7D2sB,UAAU,SAAS3Q,IAAIxc,MAAMgtB;wBACzB,OAAOjqB,KAAKlD,SAASF,UAAUwtB,SAAS3Q,IAAIxc,MAAMgtB;;oBAEtDI,aAAa,SAAS5Q,IAAIxc,MAAMqtB,cAAc7W;wBAC1C,OAAOzT,KAAKuqB,aAAatsB,MAAM+B,MAAMvC;;oBAEzC+sB,eAAe,SAAS/Q,IAAI2B;wBACxBpb,KAAK3B,IAAI,wCAAwC2B,KAAK4hB,QAAQnI,MAAM,WAAW2B,UAAU;wBACzFpb,KAAKmkB,QAAQ1K,IAAI2B;;oBAErB+D,SAASljB,GAAG+S,KAAKhP,KAAKmf,SAASnf;oBAC/B4hB,SAAS3lB,GAAG+S,KAAKhP,KAAK4hB,SAAS5hB;oBAC/BqhB,SAASplB,GAAG+S,KAAKhP,KAAKqhB,SAASrhB;oBAC/ByqB,SAASxuB,GAAG+S,KAAKhP,KAAK0qB,UAAU1qB;oBAChC2qB,eAAe,SAAS/Q;wBACpB,OAAO5Z,KAAKmhB;4BAAYvH,MAAMA;;;oBAElCgR,UAAU,SAASnR;wBACf,IAAIK,SAAS9Z,KAAKmhB;4BAAY1H,IAAIA;2BAAKK;wBACvC,OAAOA,WAAW7d,GAAG6d,OAAOmC,UACxBnC,WAAW7d,GAAG6d,OAAOiC,aACrBjC,WAAW7d,GAAG6d,OAAOuC,mBACrBvC,WAAW7d,GAAG6d,OAAOqC;;oBAE7BN,oBAAoB7b,KAAKif,YAAYpD;oBACrCC,eAAe9b,KAAKif,YAAYnD;;gBAGxC7f,GAAGY,KAAKqB,KAAKpB,SAASyoB,SAAS,SAASxoB,MAAMV;oBAC1CnB,QAAQ6B,QAAQV;;gBAGpBnB,QAAQuqB,gBAAgBvnB,KAAKilB;gBAE7B,IAAI4F,mBAAmB;oBACnB9sB,GAAGY,KAAKksB,mBAAmB,SAAS3sB,KAAKC;wBACrCnB,QAAQkB,OAAOC;;;gBAIvB,OAAO,IAAIJ,GAAG4uB,wBAAwB3vB,SAASU;;YAGnDkvB,qBAAqB,SAASrR;gBAC1Bvb,KAAKyjB;gBACLzjB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOkC;;YAG7C+O,aAAa,SAASrgB;gBAClB,IAAIA,UAAU,GAAG;oBACb,OAAOA,QAAQxM,KAAKpB,SAASiH,KAAKinB,YAAY;;gBAElD,IAAInb,KAAK;gBACT,GAAG;oBACCnF,QAAQA,QAAQ;oBAChBmF;yBACKnF,QAAQ;gBAEjB,OAAOpI,KAAK2oB,IAAIvgB,OAAO,IAAKwgB,QAAQ,KAAKhtB,KAAKpB,SAASiH,KAAKinB,YAAYnb;;YAK5Esb,2BAA2B;gBACvB,IAAInrB,OAAO9B;gBAEXA,KAAKktB;gBAELnvB,GAAGY,KAAKqB,KAAKpB,SAASuuB,cAAc,SAASxtB,KAAKytB;oBAC9C,IAAIjiB,WAAWiiB,uBAAuBjiB,UAClC2e,aAAa/rB,GAAGuG,WAAWxC,KAAKlD,SAASkrB,YAAY,OACrDuD,kBAAkBtvB,GAAGuG,WAAW8oB;oBAEpC,IAAIjiB,aAAa9M,WAAW;wBACxB8M,WAAWrJ,KAAKlD,SAASuM;;oBAG7B,IAAIkiB,gBAAgBvD,YAAY;wBAC5B/rB,GAAGuG,OAAOwlB,YAAYsD,uBAAuBtD,YAAY;;oBAG7D/rB,GAAGuG,OAAO+oB;wBACNliB,UAAUA;wBACV2e,YAAYA;uBACb;oBAEHhoB,KAAKwrB,iBAAiBD;;;YAI9B5K,YAAY,SAASjJ;gBACjB,IAAI+T,mBAAmBvtB,KAAKktB,kBAAkB1T;gBAE9C,IAAI+T,kBAAkB;oBAClB,OAAOA,iBAAiB9sB;uBAEvB,IAAI+Y,aAAaxZ,KAAKwtB,kBAAkB;oBACzC,OAAOxtB,KAAKpB,SAASqlB;;;YAW7B4C,cAAc,SAAS4G;gBACnB,IAAIC,QAAQC,WACRC,kBAAkBH;gBAGtB,IAAIG,2BAA2B7vB,GAAG2a,WAAW;oBACzCkV,kBAAkBA,gBAAgBjV;;gBAItC,IAAIiV,oBAAoB7vB,GAAG8M,OAAO+iB,kBAAkB;oBAChD,IAAI7vB,GAAG+L,OAAO8jB,kBAAkB;wBAC5B,OAAOA,gBAAgBhH;2BAEtB,IAAIgH,gBAAgBhjB,QAAQ9M,kBAAkB,WAC/C8vB,gBAAgB1sB,KAAKpD,kBAAkB,QAAQ;wBAE/C,OAAO8vB,gBAAgBxnB,aAAarI,GAAG+a,aAAaY;;oBAGxDgU,SAASE,gBAAgBtoB,qBAAqB;oBAE9CvH,GAAGY,KAAK+uB,QAAQ,SAAS/tB,KAAKqL;wBAC1B,IAAIA,MAAM5E,aAAa,YAAY,QAAQ;4BACvCunB,YAAY3iB;4BACZ,OAAO;;;oBAIf,IAAI2iB,WAAW;wBACX,OAAOA,UAAUvnB,aAAarI,GAAG+a,aAAaY;;;;YAK1DmU,iBAAiB;gBACb,OAAO7tB,KAAK+gB,YAAYrE;oBACpBd,UACI7d,GAAG6d,OAAOsC,WACVngB,GAAG6d,OAAOuC,iBACVpgB,GAAG6d,OAAOmC,QACVhgB,GAAG6d,OAAOQ,YACVre,GAAG6d,OAAOiC,WACV9f,GAAG6d,OAAOqC;mBAEf9b;;YAKP2rB,oBAAoB,SAAStU;gBACzB,IAAI6T,kBAAkBrtB,KAAKktB,kBAAkB1T;gBAE7C,OAAO6T,kBAAkBA,gBAAgBvD,aAAa9pB,KAAKpB,SAASkrB;;YAGxEiE,0BAA0B,SAASC;gBAC/B,IAAIA,YAAY7N,gBAAgBpiB,GAAG2a,WAAW;oBAC1C;wBACI3Z,MAAMhB,GAAGiV,YAAYgb,YAAY7N,KAAKxH;wBACtC2D,MAAM0R,YAAY7N,KAAKxH,cAAc2D;;;gBAI7C;oBACIvd,MAAMiB,KAAKijB;wBAAY1H,IAAIyS,YAAYzS;uBAAKxc;oBAC5Cud,MAAMtc,KAAKijB;wBAAY1H,IAAIyS,YAAYzS;uBAAKe;;;YAIpD2R,2BAA2B,SAASC;gBAChC,IAAIpsB,OAAO9B,MACPmuB;gBAEJpwB,GAAGY,KAAKuvB,cAAc,SAASvuB,KAAKquB;oBAChCG,gBAAgBtuB,KAAKiC,KAAKisB,yBAAyBC;;gBAGvD,OAAOG;;YAIXC,qBAAqB;gBACjB,IAAIpuB,KAAKpB,SAASyvB,OAAO1e,OAAO5R,GAAG4R,OAAO;oBACtC,IAAI2e,kBAAkB,0BAClBrK,SAASjkB,KAAKpB,SAASyvB,OAAOpK,QAC9BzK,WAAWyK,SAASjkB,KAAK6mB,aAAa5C,UAAUjkB,KAAKwtB,kBACrDe,aAAavuB,KAAKpB;oBAGtB,IAAI4a,YAAYA,aAAaxZ,KAAKwtB,kBAAkB;wBAChDe,aAAavuB,KAAKktB,kBAAkB1T;;oBAIxC+U,WAAWpjB,WAAW;oBAGtB,IAAIojB,WAAWzE,WAAW7Q,gBAAgB,MAAM;wBAC5CsV,WAAWzE,WAAW7Q,cAAcqV;2BAEnC;wBACDC,WAAWzE,WAAW7Q,eAAe,MAAMqV;;oBAI/CvwB,GAAGY,KAAKqB,KAAKgkB,UAAU,SAASrkB,KAAKskB;wBACjC,IAAIA,OAAOzJ,kBAAkBhB,UAAU;4BACnCyK,OAAOtK,YAAY4U,WAAWpjB;4BAC9B8Y,OAAOrJ,eAAe2T,WAAWtV;4BAEjC,OAAO;;;;;YAMvBqP,wBAAwB,SAASkG;gBAC7B,IAAI1sB,OAAO9B,MACPyuB,iBAAiBD,QAAQ9d;gBAE7B,IAAI3S,GAAG+Z,iBAAiB2W,iBAAiB;oBACrCzuB,KAAKG,IAAIquB,QAAQzvB,OAAO,oBAAoByvB,QAAQzvB,OAAO,kCAAkCyvB,QAAQ/F;oBACrG,OAAOgG,eAAezW,KAClB,SAAS0W;wBACL5sB,KAAK3B,IAAIquB,QAAQzvB,OAAO,0BAA0ByvB,QAAQ/F;wBAC1D+F,QAAQjW,UAAUmW;uBAEtB;wBACI,IAAIF,QAAQhW,WAAW;4BACnB1W,KAAK3B,IAAIquB,QAAQzvB,OAAO,0BAA0ByvB,QAAQ/F;4BAC1D+F,QAAQhW;+BAEP;4BACD1W,KAAK3B,IAAIquB,QAAQzvB,OAAO,0BAA0ByvB,QAAQ/F;;;;gBAK1E,IAAIgG,mBAAmB,OAAO;oBAC1BD,QAAQjW,UAAUkW;uBAEjB;oBACD,IAAID,QAAQhW,WAAW;wBACnBxY,KAAKG,IAAIquB,QAAQzvB,OAAO,qCAAqCyvB,QAAQ/F,aAAa;wBAClF+F,QAAQhW;2BAEP;wBACDxY,KAAKG,IAAIquB,QAAQzvB,OAAO,qCAAqCyvB,QAAQ/F,aAAa;;;gBAI1F,OAAOgG;;YAIXnP,gBAAgB,SAASa,MAAM5D,SAASoS;gBACpC,IAAI7sB,OAAO9B,MACP0b,OAAO3d,GAAGsQ,eACViO,QAAQ,GACRvd,OAAOhB,GAAGiV,YAAYmN,OACtByO,aAAazO,KAAKvT,QAAQuT,MAC1B0O,UAAU7uB,KAAK8uB,wBACX9uB,KAAK8uB,wBACL/wB,GAAG+S,KAAKhP,KAAKitB,uBAAuBjtB;gBAE5C,KAAK/D,GAAGuM,QAAQskB,eAAeA,WAAWtS,QAAQ,GAAG;oBACjDA,OAAOsS,WAAWtS;;gBAGtBuS,QAAQD,YAAY7vB,MAAM2c,MAAMY,MAAMqS,oBAAoBpS,SAASvc,KAAKpB,SAASyoB,QAAQC;oBACrFxG,YAAYhf,KAAKif;oBACjByG,aAAa1lB,KAAKoiB;oBAClB8K,kBAAkB,SAASzT,IAAI4E;wBAC3Bre,KAAK0e,SAAS/O,IAAI8J,IAAI4E;wBACtBre,KAAK2hB;wBACL3hB,KAAKmtB,aAAa1T;;;;YAK9BwT,uBAAuB,SAAS5O,MAAMphB,MAAM2c,MAAMY,MAAM4S,UAAU3S;gBAC9D,IAAIhB,KAAKvb,KAAK+gB,YAAY7E;oBAASR,MAAMA;oBAAM3c,MAAMA;oBAAMud,MAAMA;oBAAMC,SAASA;;gBAEhFvc,KAAKwgB,SAAS/O,IAAI8J,IAAI4E;gBACtBngB,KAAKivB,aAAa1T;gBAElBvb,KAAKyjB;gBAELyL,SAASrvB;oBAAM0b,IAAIA;oBAAI4E,MAAMA;;;YAGjCqI,qBAAqB,SAAS5b,MAAMuiB;gBAChC,IAAIC,YAAYxiB,KAAK1L,KAAKwG,MAAM,KAAK,IACjC3I,OAAOowB;gBAGX,IAAIpwB,QAAQ,MAAM;oBACdA,OAAOiB,KAAKpB,SAASwpB,MAAM5I;;gBAG/BzgB,QAAQ,MAAMqwB;gBAEdpvB,KAAK6e;oBACD9f,MAAMA;oBACN6N,MAAMA;;;YAKd0gB,kBAAkB,SAASnR;gBACvB,IAAI8H,SAASjkB,KAAK4pB;oBACdC,QAAQ1N,KAAK2N,WAAW7Q;oBACxB8Q,mBAAmB5N,KAAK2N,WAAWC;oBACnCtpB,SAAS0b,KAAK1b;oBACd0Y,SAASgD,KAAKhD;oBACdhO,UAAUgR,KAAKhR;oBACfoO,OAAO4C,KAAKuO;;gBAGhB1qB,KAAKktB,kBAAkBjJ,OAAOzJ,iBAAiB2B;;YAGnDkT,2BAA2B;gBACvBrvB,KAAKsvB,eAAevxB,GAAGwxB,eAAe,IAAIxxB,GAAGwxB,YACzCvvB,KAAKpB,SAASuT,MAAMpU,GAAG+S,KAAK9Q,KAAKkmB,mBAAmBlmB,OAAOjC,GAAG+S,KAAK9Q,KAAKG,KAAKH;gBAGjF,IAAIA,KAAKsvB,gBAAgBtvB,KAAKsvB,aAAaE,gBAAgB;oBACvDxvB,KAAKkkB,eAAelkB,KAAK0oB,aACrB1oB,KAAKpB,SAASyoB,QAAQ9pB,QAASyC,KAAKsvB,aAAaG;oBAGrDzvB,KAAKpB,SAAS8wB,aAAa1vB,KAAKsvB,aAAaK;oBAC7C,IAAI3vB,KAAKsvB,aAAaM,aAAa;wBAC/B5vB,KAAKpB,SAASyoB,QAAQzI,WAAW5e,KAAKsvB,aAAaM;;uBAGtD;oBACD5vB,KAAKkkB,eAAelkB,KAAK0oB,aAAa1oB,KAAKpB,SAASyoB,QAAQ9pB;;;YAIpEsyB,mBAAmB;gBACf,KAAK9xB,GAAGkpB,4BAA4BjnB,KAAKpB,SAASuiB,WAAWH,SAAS;oBAClE,OAAO;;gBAGX,IAAIhhB,KAAKpB,SAAS8oB,KAAKoI,UAAU;oBAC7B,IAAI/xB,GAAGgW,kBAAkB2C,mBAAmB;wBACxC,OAAO;;oBAGX,IAAI3Y,GAAGgW,kBAAkB0C,qBAAqBzW,KAAKpB,SAAS8oB,KAAKqI,UAAU;wBACvE,OAAO;;oBAGX,OAAO;;gBAGX,OAAO;;YAGX5F,qBAAqB,SAAS6F,SAAS9c;gBACnC,IAAI+c,QAAQ;gBAEZ,KAAKD,QAAQ7tB,QAAQ;oBACjB,OAAO;;gBAGXpE,GAAGY,KAAKqxB,SAAS,SAASrwB,KAAKuwB;oBAK3B,IAAInyB,GAAGmL,SAASgnB,aAAa;wBAEzB,IAAIC,WAAW,IAAIzrB,OAAO,QAAQwrB,aAAa,KAAK;wBAEpD,IAAIhd,SAAS/R,MAAMgvB,aAAa,MAAM;4BAClCF,QAAQ;4BACR,OAAO;;;;gBAKnB,OAAOA;;YAWX9J,YAAY,SAASiK,MAAMC,kBAAkBrnB;gBACzC,IAAI5I,UAAUJ,KAAKpB,SAAS0xB,SAASF,OACjCrG,wBACAwG,WAAWrf,OAAOmf,mBAClBtxB,OAAOwxB,MAAM,IACb/W,WAAWxZ,KAAK6mB,aAAa7d,OAC7BwnB,iBAAiBxwB,KAAK8tB,mBAAmBtU,WACzCiX,sBAAsBC;gBAE1B,SAASniB,EAAExP,MAAM4xB;oBAAevwB,UAAUA,QAAQ2E,QAAQhG,MAAM4xB;;gBAEhE5yB,GAAGY,KAAK6xB,eAAezG,mBAAmB,SAASpqB,KAAKixB;oBAKpD,IAAI7yB,GAAGmL,SAAS0nB,mBAAmB;wBAC/B7G,kBAAkBlqB,KAAK+wB;;;gBAI/BH,uBAAuB1G,kBAAkBjY,KAAK,MAAMhU;gBAEpDyQ,EAAE,UAAUvO,KAAKpB,SAASiyB,eAAe9xB;gBACzCwP,EAAE,gBAAgBkiB;gBAClBliB,EAAE,eAAevO,KAAK6sB,YAAY2D,eAAeM;gBACjDviB,EAAE,kBAAkBvO,KAAK6sB,YAAY2D,eAAeO;gBAEpDL,mBAAmBtwB,QAAQe,MAAM;gBACjC,IAAIuvB,qBAAqB,MAAM;oBAC3B3yB,GAAGY,KAAK+xB,kBAAkB,SAAS/wB,KAAKqxB;wBACpCziB,EAAEyiB,aAAaT,MAAM5wB;;;gBAI7BK,KAAKpB,SAASF,UAAUqoB,QAAQ,MAAMhoB,MAAMqB,SAAS/B;gBAErD,OAAO+B;;YAYXukB,cAAc,SAASpJ,IAAI7K;gBACvB,IAAI1Q,KAAKixB,qBAAqB1V,KAAK;oBAC/Bvb,KAAKyjB;oBACLzjB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOuC;oBAEzC,IAAIzN,UAAU;wBACVA,SAAS6K;2BAER;wBACDvb,KAAKwgB,SAASkE,MAAMnJ;;oBAGxB,OAAO;;;YAIfmO,mBAAmB,SAASnO,IAAIK;gBAC5B,IAAI9Z,OAAO9B,MACPkxB,cAAclxB,KAAK6tB;gBAEvB,IAAIjS,WAAW7d,GAAG6d,OAAOwC,mBAAmB;oBACxCpe,KAAKukB,+BAA+B1kB,KAAK0b;uBAExC,IAAIK,WAAW7d,GAAG6d,OAAOyC,eAAe;oBACzCre,KAAKwkB,4BAA4B3kB,KAAK0b;;gBAG1C,IAAI2V,gBAAgB,MACflxB,KAAKukB,+BAA+BpiB,UAAUnC,KAAKwkB,4BAA4BriB,SAAS;oBAEzFwnB,WAAW;wBACP7nB,KAAKqvB,eAAervB,KAAKyiB,gCAAgCziB,KAAK0iB;uBAC/D;;;YAIXtF,kCAAkC;gBAC9B,IAAIpd,OAAO9B;gBAEX,IAAIA,KAAKpB,SAASqrB,YAAYmH,qBAAqBrzB,GAAG+R,YAAY/R,GAAGiS,aAAa;oBAC9E2Z,WAAW;wBACP3iB,OAAOqqB,MAAMvvB,KAAKlD,SAAS0xB,SAASgB;uBACrC;oBACH,MAAM,IAAIvzB,GAAGkG,MAAMjE,KAAKpB,SAAS0xB,SAASgB;;;YAIlDC,+BAA+B,SAAShW,IAAIxc,MAAMyyB,UAAUjc;gBAGxD,KAAKic,SAASpkB,SAAS;oBACnB,IAAImI,OAAOA,IAAIqG,WAAW,QAAQ4V,SAAStxB,OAAO;wBAC9CF,KAAKpB,SAASF,UAAUqoB,QAAQxL,IAAIxc,MAAM,gCAAgCwW,IAAIqG,QAAQrG;2BAErF;wBACD,IAAIkc,cAAcD,SAAStxB,QAAQsxB,SAAStxB,QAAQF,KAAKpB,SAASiH,KAAK6rB;wBACvE1xB,KAAKpB,SAASF,UAAUqoB,QAAQxL,IAAIxc,MAAM0yB,aAAalc;;;;YAKnEoc,8CAA8C,SAASC,WAAWjmB,OAAO1J,OAAO1E,QAAQqhB;gBACpF,IAAI9c,OAAO9B;gBAEX,IAAI2L,MAAMxJ,SAASF,OAAO;oBACtB,IAAI2vB,cAAc5xB,KAAKpB,SAASkrB,WAAW+H,wBAAwB;wBAE/DlI,WAAW;4BACP,IAAImI,uBAAuBhwB,KAAKisB,yBAAyBpiB,MAAM1J,SAC3DuX,WAAW1X,KAAK+kB,aAAalb,MAAM1J,OAAOke,OAC1C8D,SAASniB,KAAK2gB,WAAWjJ;4BAE7B1X,KAAKwmB;gCACDvpB,MAAM;gCACN2R,UAAU3S,GAAG+S,KAAKhP,KAAKlD,SAASF,UAAUqzB,YAAYjwB,MAAMgwB,sBAAsB7N;gCAClF1L,WAAWxa,GAAG+S,KAAKhP,KAAKkwB,4BAA4BlwB,MAAM6J,OAAO1J,OAAO1E,QAAQqhB;gCAChFpG,WAAWza,GAAG+S,KAAKhP,KAAKmwB,4BAA4BnwB,MAAM6J,OAAO1J,OAAO1E,QAAQqhB;gCAChF6J,YAAY,WAAWqJ,qBAAqB/yB,OAAO,cAAc+yB,qBAAqBxV;;2BAE3F;2BAEF,KAAKsV,WAAW;wBACjB,MAAO3vB,QAAQ0J,MAAMxJ,QAAQF,SAAS;4BAClCH,KAAK8qB,oBAAoBjhB,MAAM1J,OAAOsZ;;;;;YAMtD4V,gBAAgB,SAASe,YAAYC;gBACjCnyB,KAAKykB,kBAAkBzkB,KAAKykB,eAAe2N,cAAcF,YAAYC,QAAQnyB,KAAK+jB;gBAElF/jB,KAAKpB,SAASF,UAAU0zB,cAAcr0B,GAAGuG,WAAW4tB,aAAan0B,GAAGuG,WAAW6tB;gBAE/EnyB,KAAKukB;gBACLvkB,KAAKwkB;;YAeT6H,cAAc,SAAS9Q,IAAIxc,MAAMqtB,cAAc7W,KAAK7E;gBAChD,IAAI5O,OAAO9B;gBAEX8B,KAAKiiB,gBAAgBxI,MAAM6Q,aAAatqB,KAAKlD,SAAS8lB,MAAMsG;gBAE5D,IAAIlpB,KAAKuwB,iBAAiB9W,IAAIxc,MAAMqtB,eAAe;oBAC/C,IAAIkG,kBAAkBxwB,KAAKlD,SAAS8lB,MAAM6N,mBAAmB;oBAE7DzwB,KAAKyvB,8BAA8BxxB,MAAM+B,MAAMvC;oBAC/CuC,KAAKlD,SAASF,UAAUytB,YAAY5Q,IAAIxc,MAAM+C,KAAK+hB,aAAatI;oBAChEzZ,KAAK0wB,mBAAmBjX,IAAIxc;oBAE5B+C,KAAKif,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOuC;oBACzCrc,KAAKgiB,eAAevI,MAAMoO,WAAW;wBACjC7nB,KAAK3B,IAAI,wBAAwBpB,OAAO;wBAExC,IAAI2R,UAAU;4BACVA,SAAS6K;+BAER;4BACDzZ,KAAK0e,SAASkE,MAAMnJ;;uBAEzB+W;oBAEH,OAAO;;;YAIfE,oBAAoB,SAASjX,IAAIxc;gBAC7BiB,KAAKG,IAAI,aAAaH,KAAKpB,SAAS8lB,MAAM6N,mBAAmB,8BAA8BxzB,OAAO;;YAItGkyB,sBAAsB,SAAS1V;gBAC3B,IAAIkX,YAAYzyB,KAAKwjB,mBACjBtQ;gBAEJ,IAAIlT,KAAK+jB,gBAAgBxI,KAAK;oBAC1Bvb,KAAKG,IAAI,kCAAkCob,IAAI;oBAC/C,OAAO;uBAEN,IAAIvb,KAAKwgB,SAASe,QAAQhG,KAAK;oBAChCrI,WAAWlT,KAAKihB,QAAQ1F;oBAExB,IAAIvb,KAAKpB,SAASF,UAAUg0B,cAAcnX,IAAIrI,cAAc,OAAO;wBAC/D,OAAO;;oBAGX,IAAIuf,YAAY,KAAKzyB,KAAKyjB,uBAAuB,IAAIgP,WAAW;wBAC5DzyB,KAAKmmB,WAAW;wBAChB,OAAO;;oBAGXnmB,KAAKG,IAAI,0BAA0B+S,WAAW,YAAYqI,KAAK;oBAC/D,OAAO;uBAEN;oBACDvb,KAAKG,IAAI,MAAMob,KAAK,4BAA4B;oBAChD,OAAO;;;YAIfkQ,WAAW,SAASlQ,IAAIxc;gBACpBiB,KAAKyjB;gBAELkP,aAAa3yB,KAAK8jB,eAAevI;gBAEjC,IAAIqX,kBAAkB70B,GAAG4J,QAAQ3H,KAAKmf,YAAY5D;gBAClD,KAAKvb,KAAKpB,SAAS8wB,cAAckD,mBAAmB,GAAG;oBACnD5yB,KAAKmf,WAAWnC,OAAO4V,iBAAiB;;gBAG5C5yB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOoC;;YAG7CsN,aAAa,SAAS/P,IAAIxc,MAAMoG,QAAQoQ;gBACpC,KAAKpQ,OAAOiI,SAAS;oBACjBpN,KAAKyjB;oBACLzjB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOyC;oBAEzC,IAAIlZ,OAAOnF,KAAKpB,SAAS8lB,MAAMsG,kCAAkC,MAAM;wBACnEhrB,KAAK+jB,gBAAgBxI,MAAM;;uBAG9B;oBACD,IAAIpW,OAAOshB,cAAc;wBACrBzmB,KAAKiiB,eAAe1G,MAAMpW,OAAOshB;;oBAGrCzmB,KAAKqjB;oBACLrjB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOwC;;gBAG7Cpe,KAAKuxB,8BAA8BhW,IAAIxc,MAAMoG,QAAQoQ;gBAErD,OAAOpQ,OAAOiI,UAAU,OAAO;;YAGnCwa,WAAW,SAASrM;gBAChBvb,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAO2C;;YAG7CyJ,mBAAmB,SAASzM,IAAIuM,UAAUC;gBACtC,IAAIhpB,OAAOiB,KAAKihB,QAAQ1F;gBAExB,IAAIwM,SAAS;oBACT/nB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAO0C;oBACzCte,KAAKG,IAAI,yBAAyBpB,OAAO,iBAAiB;oBAI1D,IAAI+oB,SAAStS,oBAAoBnX,WAAW;wBACxC2B,KAAKpB,SAASF,UAAUqoB,QAAQxL,IAAIxc,MAAM,yBAAyB+oB;2BAElE;wBACD9nB,KAAKpB,SAASF,UAAUqoB,QAAQxL,IAAIxc,MAAM,8CAA8C+oB,SAASlM,QAAQkM;;uBAG5G;oBACD9nB,KAAKyjB;oBACLzjB,KAAKqjB;oBACLrjB,KAAKwgB,SAASqS,QAAQtX;oBACtBvb,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAO4C;oBACzCxe,KAAKG,IAAI,yBAAyBpB,OAAO;;;YAIjD0rB,gBAAgB,SAASzf;gBACrB,IAAI8nB;gBAEJ,IAAI/0B,GAAGgW,kBAAkBqC,eAAe;oBACpC,KAAK0c,YAAY,GAAGA,YAAY9nB,MAAMkV,MAAM/d,QAAQ2wB,aAAa;wBAC7D9yB,KAAK0mB,sBAAsB1b,MAAMkV,MAAM4S,YAAY9nB;;oBAGvDhL,KAAK6e,SAAS7T,MAAMkV;uBAGnB,IAAIlV,MAAMvC,MAAMtG,SAAS,GAAG;oBAC7BnC,KAAK6e,SAAS7T;;gBAGlBjN,GAAGY,KAAKqB,KAAKgkB,UAAU,SAASrkB,KAAKskB;oBACjCA,OAAOpJ;;;YAIfuQ,aAAa,SAAS7P,IAAIxc,MAAMmsB,QAAQC;gBACpCnrB,KAAKykB,kBAAkBzkB,KAAKykB,eAAesO,qBAAqBxX,IAAI2P,QAAQC;;YAGhF6H,WAAW,SAASzX,IAAIxc;YAIxBk0B,0BAA0B,SAAS1X,IAAIxc;gBACnCiB,KAAKgzB,UAAUjzB,MAAMC,MAAMT;gBAC3BS,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOiC;gBACzC7d,KAAKkzB,aAAanzB,MAAMC,MAAMT;gBAE9B,IAAIS,KAAKpB,SAAS8wB,YAAY;oBAC1B1vB,KAAKpB,SAASF,UAAUy0B,YAAYpzB,MAAMC,MAAMT;oBAChDS,KAAKkhB,YAAY3F;uBAEhB;oBACDvb,KAAKozB,eAAe7X;oBACpBvb,KAAKpB,SAASF,UAAUy0B,YAAYpzB,MAAMC,MAAMT;;;YAIxD6hB,iBAAiB,SAAS7F,IAAI8X,mBAAmBC;gBAC7C,IAAI5X,OAAO1b,KAAK0jB,QAAQnI,KACpBgY;gBAEJ,IAAIF,mBAAmB;oBACnBE,4BAA4Bx1B,GAAG+S,KAAKuiB,mBAAmBrzB,MAAMub,IAAIG,MAAM4X;;gBAG3E,IAAItzB,KAAK6vB,qBAAqB;oBAC1B7vB,KAAKsoB;wBACDvpB,MAAM;wBACN2R,UAAU3S,GAAG+S,KAAK9Q,KAAKpB,SAASF,UAAU80B,gBAAgBxzB,MAAMub;wBAChEhD,WAAWgb,6BACPx1B,GAAG+S,KAAK9Q,KAAKyzB,eAAeC,YAAY1zB,MAAMub,IAAIG,MAAM4X;wBAC5D7K,YAAYlN;;oBAEhB,OAAO;uBAEN;oBACDvb,KAAKG,IAAI,mCAAmCob,KAAK,0DAC7C,oEAAoE;oBACxE,OAAO;;;YAIf2X,cAAc,SAAS3X;YAIvBoY,kBAAkB,SAASzI,QAAQC;gBAC/BnrB,KAAKpB,SAASF,UAAUk1B,gBAAgB1I,QAAQC;;YAGpDQ,eAAe,SAASpQ;YAIxBsQ,WAAW,SAAStQ,IAAIxc;gBACpBiB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOsC;;YAG7C8N,gBAAgB,SAASzQ,IAAIwQ;YAI7BtC,uBAAuB,SAASlO,IAAIuB,WAAWD;gBAE3C,IAAIA,cAAc9e,GAAG6d,OAAOqC,QAAQ;oBAChC0U,aAAa3yB,KAAK8jB,eAAevI;;;YAIzCsY,iCAAiC,SAAS3F;gBACtC,IAAIpsB,OAAO9B;gBAEXjC,GAAGY,KAAKuvB,cAAc,SAASvuB,KAAKquB;oBAChClsB,KAAK8qB,oBAAoBoB,YAAYzS;;;YAI7CuY,iCAAiC,SAASC,uBAAuBpoB,OAAOpO,QAAQqhB,UAAUqF;gBACtF,IAAI+P,cACAvB,YAAYzyB,KAAKwjB,mBACjByQ,mCAAmCj0B,KAAKyjB;gBAE5C,IAAIgP,cAAc,KAAKwB,oCAAoCxB,WAAW;oBAClE,IAAI9mB,MAAMxJ,SAAS,GAAG;wBAClBnC,KAAKsoB;4BACDvpB,MAAM;4BACN2R,UAAU3S,GAAG+S,KAAK9Q,KAAKpB,SAASF,UAAUqzB,YAAY/xB,MAAM+zB,sBAAsB,IAAI9P;4BACtF1L,WAAWxa,GAAG+S,KAAK9Q,KAAKgyB,4BAA4BhyB,MAAM2L,OAAO,GAAGpO,QAAQqhB;4BAC5EpG,WAAWza,GAAG+S,KAAK9Q,KAAKiyB,4BAA4BjyB,MAAM2L,OAAO,GAAGpO,QAAQqhB;4BAC5E6J,YAAY,WAAW9c,MAAM,GAAGwU,KAAKphB,OAAO,cAAc4M,MAAM,GAAGwU,KAAK7D;;2BAG3E;wBACDtc,KAAKmmB,WAAW;;uBAGnB;oBACDnmB,KAAK6zB,gCAAgCloB;oBACrCqoB,eAAeh0B,KAAKpB,SAAS0xB,SAAS4D,kBACjCnvB,QAAQ,iBAAiBkvB,kCACzBlvB,QAAQ,kBAAkB0tB;oBAC/BzyB,KAAK8mB,YAAYkN;;;YAIzB/B,4BAA4B,SAAStmB,OAAO1J,OAAO1E,QAAQqhB;gBACvD,IAAIuV,YAAYlyB,QAAQ;gBAExBjC,KAAK4sB,oBAAoBjhB,MAAM1J,OAAOsZ,IAAI5P,MAAM1J,OAAOke,KAAKphB;gBAE5DiB,KAAK2xB,6CAA6C,OAAOhmB,OAAOwoB,WAAW52B,QAAQqhB;;YAGvFoT,4BAA4B,SAASrmB,OAAO1J,OAAO1E,QAAQqhB;gBACvD,IAAI9c,OAAO9B,MACPm0B,YAAYlyB,QAAQ,GACpB6vB,uBAAuB9xB,KAAK+tB,yBAAyBpiB,MAAM1J;gBAE/DjC,KAAKo0B,wBAAwBzoB,MAAM1J,QAAQ6vB,sBACtC9Z,KACD;oBACIlW,KAAKuyB,QAAQ1oB,MAAM1J,OAAOsZ,IAAIhe,QAAQqhB;oBACtC9c,KAAK6vB,6CAA6C,MAAMhmB,OAAOwoB,WAAW52B,QAAQqhB;mBAEtF;oBACI9c,KAAK6vB,6CAA6C,OAAOhmB,OAAOwoB,WAAW52B,QAAQqhB;;;YAK/F0B,wBAAwB,SAAS3U,OAAOpO,QAAQqhB;gBAC5C,IAAIjT,MAAMxJ,WAAW,GAAG;oBACpBnC,KAAKmmB,WAAW;oBAChB;;gBAGJ,IAAI4N,wBAAwB/zB,KAAKiuB,0BAA0BtiB,QACvD6N,WAAWxZ,KAAK6mB,aAAalb,MAAM,GAAGwU,OACtC8D,SAASjkB,KAAKyiB,WAAWjJ;gBAE7BxZ,KAAKsoB;oBACDvpB,MAAM;oBACN2R,UAAU3S,GAAG+S,KAAK9Q,KAAKpB,SAASF,UAAU41B,iBAAiBt0B,MAAM+zB,uBAAuB9P;oBACxF1L,WAAWxa,GAAG+S,KAAK9Q,KAAK8zB,iCAAiC9zB,MAAM+zB,uBAAuBpoB,OAAOpO,QAAQqhB,UAAUqF;oBAC/GzL,WAAWza,GAAG+S,KAAK9Q,KAAK6zB,iCAAiC7zB,MAAM2L;oBAC/D8c,YAAY;;;YAIpB8L,yBAAyB;gBACrB,IAAIzyB,OAAO9B;gBAEXA,KAAK2qB,gBAAgB1nB,OAAO+D,QAAQ,gBAAgB,SAASmJ;oBACzD,IAAIrO,KAAKghB,iBAAiB;wBACtB3S,IAAIA,KAAKnJ,OAAOwtB;wBAEhBrkB,EAAEC,cAActO,KAAKlD,SAAS0xB,SAASmE;wBAEvC,OAAO3yB,KAAKlD,SAAS0xB,SAASmE;;;;YAQ1CnQ,qBAAqB;gBACjB,IAAIxiB,OAAO9B,MACPhD,UAAUgD,KAAKpB,SAASwlB;gBAG5B,IAAIrmB,GAAG22B,WAAW10B,KAAKpB,SAASwlB,QAAQxF,YAAY,MAAM;oBACtD,KAAK5e,KAAK20B,UAAU;wBAChB52B,GAAGuG,OAAOtH;4BAAU0qB,MAAM1nB,KAAKpB,SAAS8oB;;wBAExC1qB,QAAQmD,MAAMpC,GAAG+S,KAAK9Q,KAAKG,KAAKH;wBAChChD,QAAQ43B,gBAAgB72B,GAAG+S,KAAK9Q,KAAKif,gBAAgBjf;wBAErDA,KAAK20B,WAAW,IAAI52B,GAAG22B,QAAQ13B;;oBAGnC2sB,WAAW;wBACP7nB,KAAK6yB,SAASE,UAAU7c,KAAK,SAASwZ,UAAU1J;4BAC5ChmB,KAAKgzB;4BACLhzB,KAAKlD,SAASF,UAAUq2B,yBAAyBvD,UAAU,MAAM1J;2BAElE,SAAS0J,UAAU1J;4BAElBhmB,KAAKlD,SAASF,UAAUq2B,yBAAyBvD,UAAU,OAAO1J;;uBAEvE;;;YAIXgN,yBAAyB;YAEzBtI,UAAU,SAASjR,IAAIgC;gBACnBvd,KAAK+gB,YAAYzD,WAAW/B,IAAIgC;gBAChCvd,KAAKykB,kBAAkBzkB,KAAKykB,eAAeuQ,UAAUzZ;;YAGzD8W,kBAAkB,SAAS9W,IAAIxc,MAAMqtB;gBACjC,IAAItL,aAAa9gB,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;;gBAGhD,KAAKvb,KAAK+jB,gBAAgBxI,OACnBvb,KAAKpB,SAAS8lB,MAAMuQ,cACpBnU,WAAWlF,WAAW7d,GAAG6d,OAAOqC,QAAQ;oBAE3C,IAAIje,KAAK6jB,aAAatI,QAAQld,WAAW;wBACrC2B,KAAK6jB,aAAatI,MAAM;;oBAG5B,IAAIvb,KAAK6jB,aAAatI,MAAMvb,KAAKpB,SAAS8lB,MAAMwQ,iBAAiB;wBAC7Dl1B,KAAK6jB,aAAatI,OAAO;wBACzB,OAAO;;;gBAIf,OAAO;;YAGX6X,gBAAgB,SAAS7X;gBACrBvb,KAAKmf,WAAWtf,KAAK0b;;YAIzB0T,cAAc,SAAS1T;gBACnB,IAAI/B;gBAEJ,IAAIzb,GAAGgW,kBAAkBqC,eAAe;oBACpCoD,WAAWxZ,KAAKwgB,SAAS2B,QAAQ5G,IAAIqL;uBAEpC;oBACDpN,WAAWxZ,KAAK6mB,aAAa7mB,KAAKwgB,SAASjG,SAASgB;;gBAGxD,IAAI/B,UAAU;oBACVxZ,KAAK0iB,qBAAqBnH,MAAM/B;;;YAIxCoM,6BAA6B,SAASuP;gBAClCn1B,KAAKpB,SAASuT,KAAK1R,UAAU00B;gBAE7Bn1B,KAAKsvB,eAAevxB,GAAGwxB,eAAe,IAAIxxB,GAAGwxB,YACrCvvB,KAAKpB,SAASuT,MAAMpU,GAAG+S,KAAK9Q,KAAKkmB,mBAAmBlmB,OAAOjC,GAAG+S,KAAK9Q,KAAKG,KAAKH;gBAGrF,IAAIA,KAAKsvB,gBAAgBtvB,KAAKsvB,aAAaE,gBAAgB;oBACvDxvB,KAAKkkB,aAAaqF,YAAY,MAAMvpB,KAAKsvB,aAAaG;oBAEtDzvB,KAAKpB,SAAS8wB,aAAa1vB,KAAKsvB,aAAaK;oBAC7C,IAAI3vB,KAAKsvB,aAAaM,aAAa;wBAC/B5vB,KAAKylB,YAAYzlB,KAAKsvB,aAAaM;;;;YAK/CyE,SAAS,SAAS9Y,IAAIhe,QAAQqhB;gBAC1B,IAAI7f,OAAOiB,KAAKihB,QAAQ1F;gBAExB,IAAIhe,QAAQ;oBACRyC,KAAKgmB,UAAUzoB,QAAQge;;gBAG3B,IAAIqD,UAAU;oBACV5e,KAAKylB,YAAY7G,UAAUrD;;gBAG/Bvb,KAAKsoB;oBACDvpB,MAAM;oBACN2R,UAAU3S,GAAG+S,KAAK9Q,KAAKpB,SAASF,UAAU02B,UAAUp1B,MAAMub,IAAIxc;oBAC9DwZ,WAAWxa,GAAG+S,KAAK9Q,KAAKizB,0BAA0BjzB,MAAMub,IAAIxc;oBAC5DyZ,WAAWza,GAAG+S,KAAK9Q,KAAK4sB,qBAAqB5sB,MAAMub,IAAIxc;oBACvD0pB,YAAYlN;;;YAIpB2F,aAAa,SAAS3F;gBAClB,KAAKvb,KAAKwgB,SAASlV,OAAOiQ,KAAK;oBAC3Bvb,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOmC;;;YAIjDqI,oBAAoB;gBAChB,IAAIiP,YAAYC,iBACZxzB,OAAO9B;gBAEX,OAAOA,KAAKmf,WAAWhd,QAAQ;oBAC3BkzB,aAAar1B,KAAKmf,WAAW5L;oBAC7BvT,KAAKkhB,YAAYmU;;gBAIrBC,kBAAkBt1B,KAAKijB;oBAAYrH,QAAQ7d,GAAG6d,OAAOQ;mBAAaja;gBAClE,IAAImzB,iBAAiB;oBACjBv3B,GAAGoC,IAAI,uBAAuBm1B,kBAAkB;oBAChD3L,WAAW;wBACP7nB,KAAKskB;uBACN;;;YAYXgO,yBAAyB,SAASpG,aAAa8D;gBAC3C,IAAIhwB,OAAO9B,MACPmgB,OAAQ;oBACJ,IAAI6N,YAAY7N,gBAAgBpiB,GAAG2a,WAAW;wBAC1C,OAAOsV,YAAY7N,KAAKxH;;oBAE5B,OAAOqV,YAAY7N;qBAEvBphB,OAAO+yB,qBAAqB/yB,MAC5Bud,OAAOwV,qBAAqBxV,MAC5B9C,WAAWxZ,KAAK6mB,aAAamH,YAAY7N,OACzCqQ,iBAAiBxwB,KAAK8tB,mBAAmBtU,WACzC+b,kBAAkB,IAAIx3B,GAAGmP;gBAE7BqoB,gBAAgBvd,KACZ,eACA;oBACIlW,KAAK8qB,oBAAoBoB,YAAYzS,IAAIxc;;gBAGjD,IAAIhB,GAAGqM,cAAc+V,UAAUngB,KAAKmqB,oBAAoBqG,eAAezG,mBAAmBhrB,OAAO;oBAC7FiB,KAAKmmB,WAAW,aAAapnB,MAAMohB;oBACnC,OAAOoV,gBAAgBjoB;;gBAG3B,KAAKtN,KAAKpB,SAASkrB,WAAW0L,cAAclZ,SAAS,GAAG;oBACpDtc,KAAKmmB,WAAW,cAAcpnB,MAAMohB;oBACpC,OAAOoV,gBAAgBjoB;;gBAG3B,IAAIgP,OAAO,KAAKkU,eAAeM,aAAaxU,OAAOkU,eAAeM,WAAW;oBACzE9wB,KAAKmmB,WAAW,aAAapnB,MAAMohB;oBACnC,OAAOoV,gBAAgBjoB;;gBAG3B,IAAIgP,OAAO,KAAKA,OAAOkU,eAAeO,cAAc;oBAChD/wB,KAAKmmB,WAAW,gBAAgBpnB,MAAMohB;oBACtC,OAAOoV,gBAAgBjoB;;gBAG3B,IAAIvP,GAAG03B,mBAAmB13B,GAAGgW,kBAAkBiD,iBAAiBjZ,GAAG+L,OAAOqW,OAAO;oBAC7E,IAAIpiB,GAAG03B,gBAAgBtV,MAAMpiB,GAAG+S,KAAKhP,KAAK3B,KAAK2B,OAAO4zB,SAASlF,eAAemF,OAAO3d,KACjFud,gBAAgBnoB,SAChB,SAASwoB;wBACL9zB,KAAKqkB,WAAWyP,YAAY,cAAc72B,MAAMohB;wBAChDoV,gBAAgBjoB;;uBAIvB;oBACDioB,gBAAgBnoB;;gBAGpB,OAAOmoB;;YAGXM,gBAAgB;gBACZ,IAAI/zB,MAAMg0B,cAAcj3B;gBAExBiD,OAAO9B;gBAEP81B,eAAe,SAAS/2B,MAAM2R,UAAU/N;oBACpC,IAAIozB;oBAEJ;wBACI,OAAOrlB,SAAS3Q,MAAM+B,MAAMa;sBAEhC,OAAOqzB;wBACHD,WAAWC,UAAU51B,WAAW41B,UAAUztB;wBAC1CzG,KAAK3B,IAAI,0BAA0BpB,OAAO,kBAAkBg3B,UAAU;;;gBAK9E,KAAKl3B,QAAQmB,KAAKpB,SAASF,WAAW;qBACjC;wBACG,IAAIu3B,cAAcC;wBAClBD,eAAep3B;wBACfq3B,eAAep0B,KAAKlD,SAASF,UAAUu3B;wBACvCn0B,KAAKlD,SAASF,UAAUu3B,gBAAgB;4BACpC,OAAOH,aAAaG,cAAcC,cAAc32B;;;;;;;KCh0DvE;QACG;QAEAxB,GAAGo4B,oBAAoB,SAASpd;YAC5B,IAAIjX,OAAO9B;YAGXA,KAAKpB;gBACD+kB,OAAO;gBACPM,QAAQ;gBACR9Y,UAAU;gBACVgc,gBAAgB;gBAChBiP,6BAA6B;gBAC7B1G,YAAY;gBAEZrI;oBACIE;oBACA3I,UAAU;oBACVyX,eAAe;oBACfC,gBAAgB;oBAChB9L,WAAW;oBACXtD,QAAQ;oBACR3pB;oBACAg5B,cAAc;oBACdC,mBAAmB;oBACnBlP,UAAU;;gBAGdwC;oBACIC;oBACA+G,WAAW;oBACXC,cAAc;oBACd0B,WAAW;oBACXZ,wBAAwB;oBACxB5Y,aAAa;oBACb0c;wBACIc,WAAW;wBACXC,UAAU;wBACVC,WAAW;wBACXC,UAAU;;oBAEdpB,YAAY;;gBAGhB92B;oBACI02B,UAAU,SAAS7Z,IAAIxc;oBACvBo0B,aAAa,SAAS5X,IAAIxc;oBAC1BssB,YAAY,SAAS9P,IAAIxc,MAAMqtB,cAAcyK;oBAC7CzE,eAAe,SAASF,YAAYC;oBACpC5G,UAAU,SAAShQ,IAAIxc;oBACvB6sB,UAAU,SAASrQ,IAAIxc;oBACvB+sB,eAAe,SAASvQ,IAAIxc,MAAMgtB;oBAClCE,sBAAsB,SAAS1Q,IAAIwQ,WAAWK,cAAc7W;oBAC5D2W,UAAU,SAAS3Q,IAAIrI,UAAU6Y;oBACjCd,YAAY,SAAS1P,IAAIxc,MAAMmsB,QAAQC;oBACvCyI,iBAAiB,SAAS1I,QAAQC;oBAClCpE,SAAS,SAASxL,IAAIxc,MAAMwjB,QAAQuU;oBACpC3K,aAAa,SAAS5Q,IAAIxc,MAAMg4B;oBAChCrE,eAAe,SAASnX,IAAIxc;oBAC5Bu1B,iBAAiB,SAAS0C;oBAC1BjF,YAAY,SAASiF;oBACrBxD,gBAAgB,SAASjY;oBACzBoM,UAAU,SAASpM;oBACnBsM,kBAAkB,SAAStM,IAAIuM,UAAUC;oBACzCQ,iBAAiB,SAAS3b;oBAC1B6P,gBAAgB,SAASlB,IAAIuB,WAAWD;oBACxCkY,0BAA0B,SAASvD,UAAUpkB,SAAS0a;;gBAG1DwI;oBACI2G,WAAW;oBACXC,WAAW;oBACXC,cAAc;oBACdC,YAAY;oBACZC,cAAc;oBACdnD,mBAAmB;oBACnBoD,qBAAqB;oBACrBC,oBAAoB;oBACpBC,qBAAqB;oBACrBC,oBAAoB;oBACpBC,uBAAuB;oBACvBjD,SAAS;oBACTnD,8BAA8B;;gBAGlC5M;oBACIuQ,YAAY;oBACZC,iBAAiB;oBACjB3C,kBAAkB;oBAClBvH,8BAA8B;;gBAGlCZ;oBACIE,aAAa;oBACbD,aAAa;;gBAGjB9T;oBACIyK,SAAS;oBACT2W;wBACI3W,SAAS;;oBAEb4W,WAAW;oBACXC;wBACIC,WAAW;wBACXC,gBAAgB;wBAChBC,WAAW;wBACXC,eAAe;wBACfC,YAAY;;oBAEhBC,UAAU;oBAEV/qB;wBACIwR,UAAU;;;gBAIlBvH;oBACI2J,SAAS;oBACToX,iBAAiB;oBACjBP;wBACIQ,UAAU;;;gBAIlBxH,gBAAgB,SAASyH;oBACrB,OAAOA;;gBAGXzyB;oBACI6rB,sBAAsB;oBACtBhH,gBAAgB;oBAChBoC,eAAc,MAAM,MAAM,MAAM,MAAM,MAAM;;gBAGhD3L;oBACIH,SAAS;oBACTkG,QAAQ;oBACRtI,UAAU;oBACV2I;oBACAhqB;;gBAGJmqB;oBACIoI,UAAU;oBACVyI,iBAAiB;oBACjBxI,UAAU;;gBAGdxQ;oBACIC,aAAa;;gBAGjB4I;oBACID,eAAe;oBACf3I,aAAa;;gBAGjB6O;oBACI1e,KAAK;oBAGLsU,QAAQ;;gBASZkJ;gBAIA/I;oBACIxF,UAAU;oBACVrhB;oBACAgqB;oBACAlD,gBAAgB;;gBAIpBlS;oBAEI1R,SAAS;oBAGTivB,YAAY;oBAGZ8I,iBAAiB;;gBAIrBlhB;oBACImhB,eAAe;oBAGfC,cAAc;oBAGdC,QAAQ;oBAIRC,aAAa;oBAEbC,gBAAgB;oBAEhBC,aAAa;oBAEbC,aAAa;oBAGbC;;gBAGJ/O;oBACIC,gBAAgB;oBAChBkH,mBAAmB;oBACnB7G,kBAAkB;;;YAK1BxsB,GAAGuG,OAAOtE,KAAKpB,UAAUma,GAAG;YAE5B/Y,KAAKgkB;YACLhkB,KAAKktB;YACLltB,KAAK0iB;YAEL1iB,KAAK61B;YACL71B,KAAK2qB,kBAAmB,IAAI5sB,GAAGoV;YAE/BnT,KAAKmf;YACLnf,KAAK6jB;YACL7jB,KAAK8jB;YACL9jB,KAAK+jB;YACL/jB,KAAKiiB;YAELjiB,KAAKyjB,uBAAuB;YAC5BzjB,KAAKqjB,eAAe;YACpBrjB,KAAK+gB,cAAc/gB,KAAKwpB;YAExBxpB,KAAKqvB;YAELrvB,KAAKilB,sBAAsBjlB,KAAK0oB,aAAa1oB,KAAKpB,SAASyoB,QAAQE;YACnEvnB,KAAKolB,gCAAgCplB,KAAK0oB,aAAa1oB,KAAKpB,SAASuiB,WAAWoG;YAEhFvnB,KAAKwlB,yBAAyBxlB,KAAK0oB,aAAa1oB,KAAKpB,SAASuiB,WAAW5jB;YAEzEyC,KAAK4iB,iBAAiB5iB,KAAK0oB,aAAa1oB,KAAKpB,SAASyoB,QAAQzI;YAC9D5e,KAAKslB,2BAA2BtlB,KAAK0oB,aAAa1oB,KAAKpB,SAASuiB,WAAWvC;YAE3E5e,KAAKwgB,WAAWxgB,KAAK4qB;YAErB5qB,KAAKyzB,iBAAiB11B,GAAGkpB,2BAA2BjnB,KAAKgnB;YAEzD,IAAIhnB,KAAKpB,SAASqlB,QAAQ;gBACtBjkB,KAAKwtB,mBAAmBxtB,KAAK4pB;oBACzBnpB,SAAST,KAAKpB,SAASqlB;oBACvB1K,OAAOvZ,KAAKpB,SAASiH,KAAK6kB;mBAC3BlQ;;YAGPxa,KAAKitB;YAELjtB,KAAKouB;YAEL,IAAIpuB,KAAKpB,SAASwpB,MAAMD,eAAe;gBACnC,IAAIpqB,GAAGmqB,cAAc;oBACjBloB,KAAKmkB,gBAAgBnkB,KAAKioB;uBAEzB;oBACDjoB,KAAKG,IAAI,kCAAkC;;;YAInDH,KAAKu0B;YAELv0B,KAAKgiB,kBAAkBjkB,GAAGk7B,kBAAkB,IAAIl7B,GAAGk7B,eAAel7B,GAAG+S,KAAK9Q,KAAKG,KAAKH;YACpFA,KAAKskB;YAELtkB,KAAKukB;YACLvkB,KAAKwkB;YAELxkB,KAAKk5B,UAAWn7B,GAAG+mB,UAAU,IAAI/mB,GAAG+mB,OAAO9kB,KAAKpB,SAAS0Y,SAASvZ,GAAG+S,KAAK9Q,KAAKG,KAAKH;YACpF,IAAIA,KAAKk5B,QAAQlY,SAAS;gBACtBhhB,KAAK8uB,wBAAwB/wB,GAAG+S,KAAK9Q,KAAKk5B,QAAQC,eAAen5B,KAAKk5B;;YAG1E,IAAIn7B,GAAGq7B,iBAAiBr7B,GAAGgW,kBAAkBqD,aAAa;gBACtDpX,KAAKykB,iBAAiB,IAAI1mB,GAAGq7B,cACzBr7B,GAAG+S,KAAK9Q,KAAK2zB,kBAAkB3zB,OAE/B,SAASub;oBACL,IAAI8d,QAAQv3B,KAAKif,YAAYrE;wBAAUnB,IAAIA;;oBAC3C,OAAQ8d,SAASA,MAAM/c,QAAS;;;YAK5Ctc,KAAKwjB,oBAAoBxjB,KAAKpB,SAASkrB,WAAW2I;;QAItD10B,GAAGo4B,kBAAkB92B,YAAYtB,GAAG0gB;QACpC1gB,GAAGuG,OAAOvG,GAAGo4B,kBAAkB92B,WAAWtB,GAAGsoB;;ICnTjDtoB,GAAGu7B,gBAAgB,SAASvgB;QACxB;QAEA,IAAI5Y,KAAKo5B,6BACLC,YACAC,kBACAz8B;YACI08B,cAAc;YACdC,gBAAe,SAAS,QAAQ;YAChCzS,QAAQ;YACR0S,aAAa;YACbzS,gBAAgB;YAChBI;YACAE;YACAD;YACAqS;YACAC,oCAAoC;YACpCC;gBACIC,UAAS,KAAK,KAAK;gBACnBC,SAAQ,KAAK,KAAK,KAAK,KAAK;gBAC5BC,QAAO,KAAK,KAAK,KAAK,KAAK;gBAC3BC,OAAM,KAAK,KAAK,KAAK,KAAK;gBAC1BC,OAAM;;YAEV1S;gBACIoI,UAAU;gBACVyI,iBAAiB;;YAErBp4B,KAAK,SAASsJ,KAAKvB;YACnBmyB,QAAQ,SAAS9e;YACjB8P,YAAY,SAAS9P,IAAIuM,UAAUC;YACnCkD,YAAY;;QAGpBltB,GAAGuG,OAAOtH,SAAS+b;QACnB5Y,MAAMnD,QAAQmD;QAEd,IAAIpC,GAAG4J,QAAQ3K,QAAQ28B,cAAc38B,QAAQkqB,UAAU,GAAG;YACtD,MAAM,IAAIjjB,MAAM,MAAMjH,QAAQkqB,SAAS;;QAM3C,SAASoT;YACL,OAAOv8B,GAAG4J,UAAS,OAAO,QAAQ,UAAS3K,QAAQkqB,WAAW;;QAMlE,SAASqT,yBAAyBvV;YAC9B,IAAIwV,oBAAoB;YAExBz8B,GAAGY,KAAK67B,mBAAmB,SAAS76B,KAAK86B;gBACrC,IAAI18B,GAAG4J,UAAS,UAAU,mBAAmB,oBAAoB,kBAAiB8yB,UAAU,GAAG;oBAC3FD,oBAAoB;oBACpB,OAAO;;;YAIf,OAAOA;;QAGX,SAASE,MAAMnlB;YAEX,OAAOvY,QAAQ0qB,KAAKoI,YAAYva,IAAIC,oBAAoBnX;;QAI5D,SAASs8B;YACL,IAAI7S;YAEJ,IAAI9gB,OAAOuE,kBAAkBvE,OAAOwE,eAAe;gBAC/Csc,WAAW/pB,GAAGsN;gBAEd,IAAIyc,SAAStS,oBAAoBnX,WAAW;oBACxCypB,WAAW,IAAIpS;oBAEfoS,SAAS3a,SAAS;oBAClB2a,SAASza,UAAU;oBACnBya,SAAS8S,YAAY;oBACrB9S,SAAS+S,aAAa;;;YAI9B,OAAO/S;;QAIX,SAASgT,YAAYvf,IAAIwf;YACrB,IAAIjT,WAAW2R,YAAYle,IAAIhG;YAE/B,KAAKuS,UAAU;gBACX,IAAIiT,aAAa;oBACbjT,WAAWiT;uBAEV;oBACD,IAAI/9B,QAAQ0qB,KAAKoI,UAAU;wBACvBhI,WAAW6S;2BAEV;wBACD7S,WAAW/pB,GAAGsN;;;gBAItBouB,YAAYle,IAAIhG,MAAMuS;;YAG1B,OAAOA;;QAIX,SAASkT,QAAQzf;YACb,IAAI5J,IAAI5T,GAAG4J,QAAQ6xB,OAAOje,KACtBwR,MAAM/vB,QAAQmqB,gBACd8T;mBAEGxB,YAAYle;YACnBie,MAAMxc,OAAOrL,GAAG;YAEhB,IAAI6nB,MAAMr3B,UAAU4qB,OAAOpb,IAAIob,KAAK;gBAChCkO,SAASzB,MAAMzM,MAAM;gBACrBmO,YAAYD;;;QAIpB,SAAS5P,WAAW9P,IAAI4f;YACpB,IAAI5lB,MAAMulB,YAAYvf,KAClB2L,SAASlqB,QAAQkqB,QACjBa,UAAUoT,aAAa;YAE3BH,QAAQzf;YAER,IAAIwM,SAAS;gBACT5nB,IAAI+mB,SAAS,kBAAkB3L,KAAK,eAAe;mBAElD,KAAKmf,MAAMnlB,SAAS6lB,qBAAqB7lB,IAAIqG,SAAS;gBACvDmM,UAAU;gBACV5nB,IAAI+mB,SAAS,kBAAkB3L,KAAK,iCAAiChG,IAAIqG,QAAQ;;YAGrF5e,QAAQquB,WAAW9P,IAAIhG,KAAKwS;;QAGhC,SAASsT,UAAU9f;YACf,IAAI+f,iBAAiB7B,YAAYle,IAAIggB,kBACjC1B,iBAAiB78B,QAAQ68B,gBACzBt8B;YAEJ,IAAIP,QAAQwqB,YAAY3E,KAAK;gBACzBtlB,SAASP,QAAQwqB,YAAY3E,IAAItH;;YAGrC,IAAI+f,gBAAgB;gBAChBv9B,GAAGY,KAAK28B,gBAAgB,SAASv8B,MAAMZ;oBACnCZ,SAASA;oBACTA,OAAOwB,QAAQZ;;;YAIvB,IAAI07B,gBAAgB;gBAChB97B,GAAGY,KAAKk7B,gBAAgB,SAAS96B,MAAMZ;oBACnCZ,SAASA;oBACTA,OAAOwB,QAAQZ;;;YAIvB,OAAOZ;;QAGX,SAAS29B,YAAY3f,IAAIigB;YACrB,IAAIjmB,MAAMulB,YAAYvf,IAAIigB,SACtBtU,SAASlqB,QAAQkqB,QACjB3pB,SAAS89B,UAAU9f,KACnBkgB,UAAUhC,YAAYle,IAAIkgB,SAC1BC;YAEJ1+B,QAAQq9B,OAAO9e;YAEfmgB,MAAMC,UAAUpgB,IAAIhe,QAAQk8B,YAAYle,IAAIqgB;YAG5C,IAAIlB,MAAMnlB,MAAM;gBACZA,IAAIpI,SAAS0uB,kBAAkBtgB;gBAC/BhG,IAAIlI,UAAUyuB,mBAAmBvgB;mBAEhC;gBACDhG,IAAIwmB,qBAAqBC,8BAA8BzgB;;YAG3D0gB,0BAA0B1gB;YAG1BhG,IAAI2mB,KAAKhV,QAAQwU,KAAK;YAItB,IAAI1+B,QAAQ0qB,KAAKoI,YAAY9yB,QAAQ0qB,KAAK6Q,oBAAoBmC,MAAMnlB,MAAM;gBACtEA,IAAIC,kBAAkB;;YAG1B2mB,WAAW5gB;YAEXpb,IAAI,aAAa+mB,SAAS,kBAAkB3L;YAE5C,IAAIkgB,SAAS;gBACTlmB,IAAI6mB,KAAKX;mBAER,IAAIlC,gCAAgCh8B,QAAQ;gBAC7CgY,IAAI6mB;mBAEH,IAAI7+B,UAAUP,QAAQ48B,eAAe58B,QAAQ48B,YAAY97B,cAAc6J,QAAQ,wCAAwC,GAAG;gBAC3H4N,IAAI6mB,KAAKr+B,GAAGoT,QAAQ5T,QAAQ;mBAE3B,IAAIA,UAAUP,QAAQ48B,eAAe58B,QAAQ48B,YAAY97B,cAAc6J,QAAQ,uBAAuB,GAAG;gBAC1G4N,IAAI6mB,KAAK5pB,KAAK6pB,UAAU9+B;mBAEvB;gBACDgY,IAAI6mB,KAAK7+B;;YAGb,OAAOgY;;QAGX,SAASomB,UAAUpgB,IAAIhe,QAAQq+B;YAC3B,IAAIhd,WAAW5hB,QAAQyqB,cAAc5E,IAAItH,KACrC+gB,YAAY7C,YAAYle,IAAI+gB;YAGhC,IAAIA,aAAaj+B,WAAW;gBACxBugB,YAAY,MAAM0d;;YAGtB,IAAI/C,+BAA+Bh8B,QAAQ;gBACvCqhB,WAAW7gB,GAAGoT,QAAQ5T,QAAQqhB;;YAGlC,IAAIgd,uBAAuB;gBACvBhd,WAAW7gB,GAAGoT,QAAQyqB,uBAAuBhd;;YAGjD,OAAOA;;QAKX,SAASod,8BAA8BzgB;YACnC,OAAO;gBACH,IAAIuf,YAAYvf,IAAIghB,eAAe,GAAG;oBAClClR,WAAW9P;;;;QAKvB,SAAS0gB,0BAA0B1gB;YAC/B,IAAI0P,aAAajuB,QAAQiuB;YAEzB,IAAIA,YAAY;gBACZ6P,YAAYvf,IAAIjQ,OAAOuvB,aAAa,SAAS1qB;oBACzC,IAAIA,EAAEqsB,kBAAkB;wBACpBvR,WAAW1P,IAAIpL,EAAE+a,QAAQ/a,EAAEgb;;;;;QAQ3C,SAAS0Q,kBAAkBtgB;YACvB,OAAO;gBACH8P,WAAW9P;;;QAMnB,SAASugB,mBAAmBvgB;YACxB,OAAO;gBACH8P,WAAW9P,IAAI;;;QAIvB,SAAS4gB,WAAW5gB;YAChB,IAAIhG,MAAMulB,YAAYvf,KAClBgM,gBAAgBvqB,QAAQuqB,eACxBkV,kBAAkBhD,YAAYle,IAAImhB,yBAClCxV,SAASlqB,QAAQkqB,QACjByV;YAGJ,KAAKjC,MAAMnlB,MAAM;gBACbvY,QAAQ08B,gBAAgBnkB,IAAIqnB,iBAAiB,UAAU5/B,QAAQ08B;gBAG/D,IAAI18B,QAAQ88B,oCAAoC;oBAK5C,KAAK98B,QAAQ0qB,KAAKoI,cAAcwK,oBAAoBC,yBAAyBhT,iBAAiB;wBAC1FhS,IAAIqnB,iBAAiB,oBAAoB;wBACzCrnB,IAAIqnB,iBAAiB,iBAAiB;;;gBAI9C,IAAI5/B,QAAQ48B,gBAAgB1S,WAAW,UAAUA,WAAW,QAAQ;oBAChE3R,IAAIqnB,iBAAiB,gBAAgB5/B,QAAQ48B;;gBAGjD77B,GAAGuG,OAAOq4B,YAAY5+B,GAAGyK,WAAW+e,iBAAiBA,cAAchM,MAAMgM;gBACzExpB,GAAGuG,OAAOq4B,YAAYF;gBAEtB1+B,GAAGY,KAAKg+B,YAAY,SAAS59B,MAAMZ;oBAC/BoX,IAAIqnB,iBAAiB79B,MAAMZ;;;;QAKvC,SAASi9B,qBAAqByB;YAC1B,OAAO9+B,GAAG4J,QAAQ3K,QAAQ+8B,wBAAwB/8B,QAAQkqB,SAAS2V,iBAAiB;;QAGxF,SAASC,cAAcvhB,IAAIigB,QAAQc,WAAWf,kBAAkBK,uBAAuBc,mBAAmBjB;YACtGhC,YAAYle;gBACR+gB,WAAWA;gBACXf,kBAAkBA;gBAClBK,uBAAuBA;gBACvBc,mBAAmBA;gBACnBjB,SAASA;;YAGb,IAAIttB,MAAMqrB,MAAM35B,KAAK0b;YAGrB,IAAIpN,OAAOnR,QAAQmqB,gBAAgB;gBAC/B,OAAO+T,YAAY3f,IAAIigB;;;QAI/BjC,8BAA8Bv8B,QAAQkqB,WAAW,SAASlqB,QAAQkqB,WAAW;QAE7EnpB,GAAGuG,OAAOtE;YAEN+8B,eAAe,SAASxhB;gBACpB,IAAIyhB,MAAMz/B,QAAQynB,SAASyW,SAASwB,aAAarB;gBAEjD;oBAEIsB,UAAU,SAASC;wBACfH,OAAOG;wBACP,OAAOn9B;;oBAOXo9B,YAAY,SAAS7B;wBACjBh+B,SAASg+B;wBACT,OAAOv7B;;oBAGXq9B,iBAAiB,SAASC;wBACtB1B,wBAAwB0B;wBACxB,OAAOt9B;;oBAIXu9B,aAAa,SAASb;wBAClB1X,UAAU0X;wBACV,OAAO18B;;oBAIXw9B,aAAa,SAASC;wBAClBhC,UAAUgC;wBACV,OAAOz9B;;oBAIX09B,iBAAiB;wBACbT,cAAc;wBACd,OAAOj9B;;oBAIXo8B,MAAM,SAASZ;wBACX,IAAIyB,eAAel/B,GAAG4J,UAAS,OAAO,YAAW3K,QAAQkqB,WAAW,GAAG;4BACnE3pB,OAAOogC,cAAc,IAAIC,OAAOC;;wBAGpC,OAAOf,cAAcvhB,IAAIigB,QAAQwB,MAAMz/B,QAAQq+B,uBAAuB5W,SAASyW;;;;YAK3FqC,UAAU,SAASviB;gBACfyf,QAAQzf;;;;IC1YpBxd,GAAGggC,gBAAgB,SAAS5hB;QACxB;QAEA,IAAI6hB,QAAQ7hB,KAAK6hB,OACbC,gBACA1S,WAAWyS,MAAMzS,UACjBtK,UAAU+c,MAAM/c;QAEpBljB,GAAGuG,OAAOtE;YACNyR,KAAK,SAAS8J,IAAI2iB;gBACdD,UAAU1iB,MAAM2iB;gBAChBD,UAAU1iB,IAAIlK;;YAGlBkP,QAAQ,SAAShF;gBACb,IAAIzZ,OAAO9B,MACPwrB,2BAA2B,IAAIztB,GAAGmP,WAClCixB,iBAAiB5S,SAAShQ,IAAI0F,QAAQ1F,KAAKiQ;gBAE/C2S,eAAenmB,KAAK;oBAChB,IAAIlW,KAAKyf,QAAQhG,KAAK;wBAClB0iB,UAAU1iB,IAAIuiB,WAAW;wBACzBh8B,KAAK+wB,QAAQtX;;oBAEjBiQ,yBAAyBpe;;;YAIjCylB,SAAS,SAAStX;uBACP0iB,UAAU1iB;;YAGrB6iB,qBAAqB,SAAS7iB;gBAC1B,OAAO0iB,UAAU1iB,IAAIrd;;YAGzBqjB,SAAS,SAAShG;gBACd,OAAO0iB,UAAU1iB,QAAQld;;YAG7Bwc,OAAO;gBACHojB;;YAGJI,eAAe,SAAS9iB;gBACpB,OAAO0iB,UAAU1iB;;YAGrB+iB,sBAAsB,SAAS/iB,IAAIgjB;gBAC/BN,UAAU1iB,IAAIrd,MAAMqgC;;YAGxBC,cAAc,SAASjjB;gBACnB,SAAS0iB,UAAU1iB,IAAIuiB;;;;ICpDnC//B,GAAG4uB,0BAA0B,SAAS5T,GAAGrb;QACrC;QAEA,IAAI+gC,aAAaz+B,MACb0+B,mBAAmB,OACnBC,6BAA6B,OAC7BpoB,UAAUqoB,sBAAsBz+B,KAAK0uB,SAEzC7xB;YACIwqB;YACAL,gBAAgB;YAChB5Q;gBACIyK,SAAS;gBACT7V;oBACI6V,SAAS;;;YAGjB7gB,KAAK,SAASsJ,KAAKvB;YACnB+iB,YAAY,SAAS1P,IAAIrI,UAAUgY,QAAQC;YAC3CE,YAAY,SAAS9P,IAAIrI,UAAUse,UAAUjc;YAC7CgW,UAAU,SAAShQ,IAAIrI;YACvBwY,cAAc,SAASnQ;YACvBqQ,UAAU,SAASrQ,IAAIrI;YACvB4Y,eAAe,SAASvQ,IAAIrI,UAAU6Y;YACtCE,sBAAsB,SAAS1Q,IAAIwQ,WAAWyF,UAAUjc;YACxD4W,aAAa,SAAS5Q,IAAIrI,UAAUse,UAAUjc;YAC9C2W,UAAU,SAAS3Q,IAAIrI,UAAU6Y;YACjCO,eAAe,SAAS/Q,IAAI2B;YAC5B+D,SAAS,SAAS1F;YAClBgR,SAAS,SAAShR,IAAIgC;YACtBmP,UAAU,SAASnR;YACnBoC,oBAAoB,SAASpC;YAC7BqC,eAAe,SAASrC;WAG5BsjB;YAEIpmB,MAAM,SAAS8C,IAAIujB,UAAUtN,UAAUjc;gBACnC,IAAIwW,YAAY8C,QAAQkQ,cAAcxjB,IAAIujB;gBAE1CjQ,QAAQwP,cAAc9iB,IAAIyjB,mBAAmB;uBAEtCnQ,QAAQwP,cAAc9iB,IAAIlK,KAAK4tB,cAAcH;gBACpDjQ,QAAQwP,cAAc9iB,IAAI2P,UAAUa,UAAUzP;gBAE9Ctf,QAAQivB,qBAAqB1Q,IAAIsT,QAAQqQ,yBAAyBnT,YAAYyF,UAAUjc;;YAK5F4pB,UAAU,SAAS5jB;gBACf,IAAIe,OAAOtf,QAAQmmB,QAAQ5H,KACvBxc,OAAO/B,QAAQikB,QAAQ1F;gBAE3Bpb,IAAI,uCAAuCob,KAAK;gBAChDsT,QAAQuQ,eAAe7jB,IAAIvD,KACvB,SAASwZ,UAAUjc;oBACfpV,IAAI,6BAA6Bob;oBAEjC,IAAI8jB,oBAAoB/zB,OAAOg0B,kBAAkB9N,UAAU;oBAE3Dx0B,QAAQiuB,WAAW1P,IAAIxc,MAAMud,MAAMA;oBACnCuS,QAAQ0Q,+BAA+BhkB;oBACvCjQ,OAAOk0B,QAAQjkB,IAAI8jB,mBAAmB9pB;mBAE1C,SAASic,UAAUjc;oBACf,IAAI8pB,oBAAoB/zB,OAAOg0B,kBAAkB9N,UAAU;oBAE3DrxB,IAAI,2CAA2Cob,KAAK,QAAQ8jB,kBAAkBn/B,OAAO;oBAErF,IAAIm/B,kBAAkBxkB,OAAO;wBACzBgkB,QAAQhkB,MAAMU;;oBAGlB,KAAKve,QAAQmvB,YAAY5Q,IAAIxc,MAAMsgC,mBAAmB9pB,MAAM;wBACxDjK,OAAOk0B,QAAQjkB,IAAI8jB,mBAAmB9pB;;;;YAMtDkqB,eAAe,SAASX,UAAUvjB,IAAIiW,UAAUjc;gBAC5C,IAAIxW,OAAO/B,QAAQikB,QAAQ1F;gBAE3Bpb,IAAI,uCAAuCob,KAAK,aAAaujB;gBAE7DjQ,QAAQ6Q,iBAAiBnkB,IAAIujB;gBAE7B,IAAIa,mBAAmBr0B,OAAOg0B,kBAAkB9N,UAAU,QACtDoO;gBAEJ,IAAID,iBAAiB9kB,OAAO;oBACxBgkB,QAAQhkB,MAAMU;uBAEb;oBACDqkB,gBAAgB7hC,GAAG4J,QAAQknB,QAAQwP,cAAc9iB,IAAIhF,SAASspB,YAAYf;oBAC1E,IAAIc,iBAAiB,GAAG;wBACpB/Q,QAAQwP,cAAc9iB,IAAIhF,SAASspB,WAAW7iB,OAAO4iB,eAAe;wBACpE/Q,QAAQwP,cAAc9iB,IAAIhF,SAASupB,UAAUC,QAAQjB;;;gBAM7D,KAAKjQ,QAAQwP,cAAc9iB,IAAIlK,KAAK2uB,eAAe;oBAG/C,IAAIrB,4BAA4B;wBAC5B9P,QAAQwP,cAAc9iB,IAAIlK,KAAK2uB,gBAAgB;wBAE/C7/B,IAAIpC,GAAGyL,OAAO,oFAAoFgJ,KAAK6pB,UAAU/zB,OAAO23B,KAAKpR,QAAQqR,SAAS3kB,OAAO/I,KAAK6pB,UAAUxN,QAAQwP,cAAc9iB,IAAIhF,SAASspB;wBACvM9hC,GAAGY,KAAKkwB,QAAQqR,SAAS3kB,KAAK,SAAS4kB,MAAMC;4BACzCjgC,IAAIpC,GAAGyL,OAAO,uDAAuD+R,IAAI4kB,MAAMC,MAAM7D;4BACrF6D,MAAMC;4BAGND,MAAME,aAAa;;wBAIvBzR,QAAQ0R,0BAA0BhlB;wBAIlCilB,kBAAkBC,KAAKllB,IAAI;;oBAG/B,KAAKve,QAAQmvB,YAAY5Q,IAAIxc,MAAM4gC,kBAAkBpqB,MAAM;wBAIvDjK,OAAOk0B,QAAQjkB,IAAIokB,kBAAkBpqB;;;;YAKjDmrB,cAAc,SAASnlB;gBACnB,SAASsT,QAAQwP,cAAc9iB,IAAIhF,SAASupB,UAAU39B;;YAG1Dw+B,UAAU,SAASplB;gBACf,IAAIqlB,UAAU/R,QAAQwP,cAAc9iB,IAAIhF,SAASupB,UAAUvsB;gBAE3D,IAAIqtB,WAAW/R,QAAQgS,gBAAgBtlB,KAAK;oBACxCqlB,UAAU;;gBAGd,OAAOA;;YAGX/lB,OAAO,SAASU;gBACZpb,IAAI,gGAAgGob,IAAI;gBAExGsT,QAAQ0Q,+BAA+BhkB;gBACvCsT,QAAQiS,mBAAmBvlB;gBAC3BsT,QAAQwP,cAAc9iB,IAAI2P,SAAS;;YAGvC6V,UAAU,SAASxlB;gBACf,IAAIe,OAAOtf,QAAQmmB,QAAQ5H,KACvBxc,OAAO/B,QAAQikB,QAAQ1F,KACvBujB,WAAWD,QAAQ8B,SAASplB,KAC5BwQ,YAAY8C,QAAQkQ,cAAcxjB,IAAIujB,WACtCzG,WAAWxJ,QAAQwP,cAAc9iB,IAAIyjB,kBACrCgC,mBAAmBnS,QAAQwP,cAAc9iB,IAAIhF,SAASspB;gBAE1D,IAAIhR,QAAQwP,cAAc9iB,IAAI2P,UAAU,MAAM;oBAC1C2D,QAAQwP,cAAc9iB,IAAI2P,SAAS;;gBAIvC,IAAImN,YAAYr7B,QAAQkvB,SAAS3Q,IAAIxc,MAAMgtB,eAAe,OAAO;oBAC7D8S,QAAQhkB,MAAMU;oBACdujB,WAAWD,QAAQ8B,SAASplB;oBAC5BwQ,YAAY8C,QAAQkQ,cAAcxjB,IAAIujB;oBACtCzG,WAAW;;gBAIf,IAAIyG,YAAY,QAAQkC,iBAAiB7+B,WAAW,GAAG;oBACnD08B,QAAQM,SAAS5jB;uBAIhB;oBACDpb,IAAIpC,GAAGyL,OAAO,qEAAqE+R,IAAIujB,UAAU/S,UAAU5f,QAAQ,GAAG4f,UAAU3f,KAAKkQ;oBACrItf,QAAQ8uB,cAAcvQ,IAAIxc,MAAM8vB,QAAQqQ,yBAAyBnT;oBACjEiV,iBAAiBnhC,KAAKi/B;oBACtBjQ,QAAQwP,cAAc9iB,IAAIhF,SAASspB,aAAamB;oBAEhD,IAAIrC,4BAA4B;wBAC5B6B,kBAAkBtE,KAAK3gB,IAAIujB;;oBAG/B,IAAIH,8BAA8B6B,kBAAkBS,eAAepS,QAAQwP,cAAc9iB,IAAIhF,SAASupB,UAAU39B,QAAQ;wBACpH08B,QAAQkC,SAASxlB;;oBAGrB,IAAIwQ,UAAUnf,KAAK0P,SAAS,GAAG;wBAC3Bnc,IAAIpC,GAAGyL,OAAO,gEAAgEs1B,UAAUvjB,KAAK;wBAC7FsjB,QAAQY,cAAcX,UAAUvjB,IAAI,+BAA+B;2BAElE;wBACDsT,QAAQqS,YAAY3lB,IAAIujB,UAAUzG,UAAUrgB,KAExC,SAAS5K,QAAQokB,UAAUjc;4BACvBpV,IAAI,0CAA0Cob,KAAK,aAAaujB;4BAEhEjQ,QAAQ6Q,iBAAiBnkB,IAAIujB;4BAE7B,IAAIkC,mBAAmBnS,QAAQwP,cAAc9iB,IAAIhF,SAASspB,kBACtDF,mBAAmBr0B,OAAOg0B,kBAAkB9N,UAAU,OACtD2P,qBAAqBpjC,GAAG4J,QAAQq5B,kBAAkBlC;4BAEtD3+B,IAAIpC,GAAGyL,OAAO,+CAA+Cs1B,UAAUvjB;4BAEvEsjB,QAAQpmB,KAAK8C,IAAIujB,UAAUa,kBAAkBpqB;4BAE7C,IAAI4rB,sBAAsB,GAAG;gCACzBH,iBAAiBhkB,OAAOmkB,oBAAoB;;4BAGhDtS,QAAQuS,0BAA0B7lB;4BAElC,KAAKsjB,QAAQ6B,aAAanlB,OAAOylB,iBAAiB7+B,WAAW,GAAG;gCAC5D08B,QAAQM,SAAS5jB;mCAEhB,IAAIsjB,QAAQ6B,aAAanlB,KAAK;gCAC/BsjB,QAAQkC,SAASxlB;mCAEhB;gCACDpb,IAAIpC,GAAGyL,OAAO,qGAAqG+R,IAAI/I,KAAK6pB,UAAU2E;;2BAK9I,SAAS1zB,QAAQkkB,UAAUjc;4BACvBspB,QAAQY,cAAcX,UAAUvjB,IAAIiW,UAAUjc;2BAGjDkD,KAAK;4BACFoW,QAAQwS,SAAS9lB,IAAIujB;;;;;WAO7C0B;YACIc;YACAC;YACAC;YAEAP,WAAW;gBACP,IAAIlU,MAAM/vB,QAAQmqB,gBACdsa,wBAAwB,GACxBC,kBAAkB;gBAEtB3jC,GAAGY,KAAK6hC,kBAAkBe,aAAa,SAAS9f,QAAQkgB;oBACpDF;oBACAC,mBAAmBC,iBAAiBx/B;;gBAGxC,OAAO4qB,OAAOyT,kBAAkBc,MAAMn/B,SAASs/B,wBAAwBC;;YAM3EjB,MAAM,SAASllB,IAAIqmB;gBACf,IAAIC,aAAaD,eACbE,eAAe/jC,GAAG4J,QAAQ64B,kBAAkBgB,UAAUjmB,KACtDwmB,mBAAmBhkC,GAAG4J,QAAQ64B,kBAAkBc,OAAO/lB,KACvD0f;uBAEGuF,kBAAkBe,YAAYhmB;gBAErC,IAAIjQ,OAAO02B,eAAezmB,eAAexd,GAAG2a,WAAW;oBACnDvY,IAAI,yCAAyCob,KAAK;2BAC3CsT,QAAQwP,cAAc9iB,IAAI4E;;gBAIrC,IAAI2hB,gBAAgB,GAAG;oBACnBtB,kBAAkBgB,SAASxkB,OAAO8kB,cAAc;uBAG/C,IAAID,aAAaE,oBAAoB,GAAG;oBACzCvB,kBAAkBc,MAAMtkB,OAAO+kB,kBAAkB;oBAEjD9G,SAASuF,kBAAkBgB,SAASjuB;oBACpC,IAAI0nB,UAAU,GAAG;wBACbuF,kBAAkBc,MAAMzhC,KAAKo7B;wBAC7B3vB,OAAOa,MAAM8uB;;;;YAKzBgH,uBAAuB;gBACnB,IAAIC;gBAIJnkC,GAAGY,KAAK6hC,kBAAkBe,aAAa,SAAS9f,QAAQ0gB;oBACpD,IAAIA,UAAUA,OAAOhgC,QAAQ;wBACzB+/B,mBAAmBriC,KAAKuiC,SAAS3gB;;;gBAMzC1jB,GAAGY,KAAK6hC,kBAAkBc,OAAO,SAAS3hC,KAAK8hB;oBAC3C,KAAK+e,kBAAkBe,YAAY9f,SAAS;wBACxCygB,mBAAmBriC,KAAKuiC,SAAS3gB;;;gBAKzCygB,qBAAqBA,mBAAmBhxB,OAAOsvB,kBAAkBgB;gBAEjE,OAAOU;;YAGXG,mBAAmB,SAAS9mB;gBACxB,OAAOxd,GAAG4J,QAAQ64B,kBAAkBc,OAAO/lB,OAAO;;YAGtD2gB,MAAM,SAAS3gB,IAAIujB;gBACf,IAAIA,YAAY,MAAM;oBAClB0B,kBAAkBgB,SAAS3hC,KAAK0b;;gBAGpC,IAAIilB,kBAAkBS,aAAa;oBAC/B,IAAInC,YAAY,MAAM;wBAClB0B,kBAAkBgB,SAASc;wBAC3B9B,kBAAkBc,MAAMzhC,KAAK0b;2BAE5B;yBACA;4BACG,IAAIgnB,kBAAkB/B,kBAAkBe,YAAYhmB;4BACpDgnB,gBAAgB1iC,KAAKi/B;4BACrB0B,kBAAkBe,YAAYhmB,MAAMgnB;;;oBAI5C,OAAO;;gBAGX,OAAO;;YAGX1nB,OAAO;gBACH2lB,kBAAkBgB;gBAClBhB,kBAAkBc;;WAI1BkB;YACIpG,MAAM,SAAS7gB,IAAIxc;gBACf8vB,QAAQwP,cAAc9iB,IAAI2P,SAAS;gBAEnC/qB,IAAI,uCAAuCob;gBAC3CsT,QAAQ4T,WAAWlnB,IAAIvD,KACnB,SAASwZ,UAAUgK;oBACfr7B,IAAI,yCAAyCob;oBAE7C,IAAIokB,mBAAmBr0B,OAAOg0B,kBAAkB9N,UAAU,OACtDlV,OAAOtf,QAAQmmB,QAAQ5H;oBAE3Bve,QAAQiuB,WAAW1P,IAAIxc,MAAMud,MAAMA;oBACnChR,OAAOo3B,aAAannB,IAAIokB;oBACxBr0B,OAAOk0B,QAAQjkB,IAAIokB,kBAAkBnE;mBAGzC,SAAShK,UAAUgK;oBACfr7B,IAAI,sCAAsCob;oBAE1C,IAAIokB,mBAAmBr0B,OAAOg0B,kBAAkB9N,UAAU;oBAE1D,KAAKx0B,QAAQmvB,YAAY5Q,IAAIxc,MAAM4gC,kBAAkBnE,SAAS;wBAC1DlwB,OAAOk0B,QAAQjkB,IAAIokB,kBAAkBnE;;;;WAOzDlwB;YACIiV,QAAQ,SAAShF;gBACbpb,IAAI,gBAAgBob;gBACpBve,QAAQwqB,YAAY3jB,OAAO0X;gBAC3BilB,kBAAkBC,KAAKllB;;YAG3BikB,SAAS,SAASjkB,IAAIiW,UAAUgK;gBAC5B,IAAIz8B,OAAO/B,QAAQikB,QAAQ1F;gBAE3Bve,QAAQquB,WAAW9P,IAAIxc,MAAMyyB,UAAUgK;gBAEvC,IAAI3M,QAAQwP,cAAc9iB,KAAK;oBAC3BsT,QAAQ8T,cAAc9T,QAAQ8T,WAAWpnB;;gBAG7CilB,kBAAkBC,KAAKllB;;YAK3BymB,gBAAgB,SAASzmB;gBACrB,OAAQsT,QAAQ+T,YAAY/T,QAAQ+T,SAASrnB,OACxCsT,QAAQ1M,WAAW0M,QAAQ1M,QAAQ5G;;YAG5CsnB,aAAa;gBACT,IAAIC,cAAcplC,YAAYK,GAAGL,aAAaK,GAAGglC,aAC7CC,uBAAuBjlC,GAAGgW,kBAAkBqC,gBAAgB,QAAQ;gBAExEyY,UAAU,IAAIiU,YAAYE,uBAAuB,iBAC7ChmC;oBAEIyvB,eAAezvB,QAAQyvB;oBACvBxL,SAASjkB,QAAQikB;oBACjBkC,SAASnmB,QAAQmmB;oBACjBO,SAAS1mB,QAAQ0mB;oBACjBvjB,KAAKA;oBACLorB,UAAUvuB,QAAQuuB;oBAClBN,YAAYjuB,QAAQiuB;oBACpBqB,eAAetvB,QAAQsvB;;gBAI/B,IAAIuC,QAAQoU,+BAA+B;oBACvCpU,QAAQoU;;;YAIhBC,6BAA6B,SAAS3nB;gBAClC,OAAOve,QAAQ0vB,SAASnR;;YAM5B4nB,YAAY,SAAS5nB,IAAI3O;gBAIrB,IAAIA,SAASiiB,QAAQ1M,QAAQ5G,OAAO3O,gBAAgB7O,GAAG2a,WAAW;oBAK9D1b,QAAQ0uB,aAAanQ;oBAErBpb,IAAI,iDAAiDob;oBACrD3O,KAAKiM,SAASb,KAAK,SAASorB;wBACxBjjC,IAAI,qCAAqCob;wBAGzCsT,QAAQwU,WAAW9nB,IAAI6nB;wBAGvBpmC,QAAQuvB,QAAQhR,IAAI6nB,cAAc9mB;wBAGlCuS,QAAQiS,mBAAmBvlB;wBAE3BjQ,OAAOg4B,uBAAuB/nB;uBAIlC,SAASyY;wBACL,IAAIuP;wBAEJ,IAAIvP,cAAc;4BACduP,cAAcrjC,QAAQ8zB;;wBAG1B7zB,IAAIpC,GAAGyL,OAAO,0DAA0D+R,IAAIyY,eAAe;wBAE3Fh3B,QAAQquB,WAAW9P,IAAIve,QAAQikB,QAAQ1F,KAAKxd,GAAGuG,OAAOi/B,eAAe3E,uBAAuB;wBAC5FtzB,OAAOg4B,uBAAuB/nB;wBAC9BilB,kBAAkBC,KAAKllB;;uBAG1B;oBACD,OAAOjQ,OAAOg4B,uBAAuB/nB;;gBAGzC,OAAO;;YAIX+nB,wBAAwB,SAAS/nB;gBAC7B,IAAIioB,aAAaxmC,QAAQ2gB,mBAAmBpC,KACxCkoB,iBAAiB;gBAErB,IAAID,cAAcA,WAAWrhC,QAAQ;oBACjChC,IAAI,4CAA4Cob;oBAEhDxd,GAAGY,KAAK6kC,YAAY,SAAS7jC,KAAK+jC;wBAC9B,IAAIp4B,OAAO43B,4BAA4BQ,gBAAgB7U,QAAQ1M,QAAQuhB,YAAY;4BAC/ED,iBAAiBC,cAAcnoB;4BAC/BjQ,OAAOq4B,IAAID;+BAEV,IAAIp4B,OAAO43B,4BAA4BQ,YAAY;4BACpD,OAAO;;;uBAId;oBACDD,iBAAiB;oBACjBn4B,OAAOq4B,IAAIpoB;;gBAGf,OAAOkoB;;YAGXf,cAAc,SAASnnB,IAAIiW;gBACvB,IAAIA,SAAStU,YAAY7e,WAAW;oBAChCrB,QAAQsvB,cAAc/Q,IAAIiW,SAAStU;;;YAO3CoiB,mBAAmB,SAASsE,kBAAkB1R;gBAC1C,IAAIV,WAAWoS;gBAIf,KAAK7lC,GAAGqK,SAASw7B,mBAAmB;oBAChCpS;oBAEA,IAAIzzB,GAAGmL,SAAS06B,sBAAsB1R,YAAY;wBAC9CV,SAAStxB,QAAQ0jC;;;gBAIzBpS,SAASpkB,UAAU8kB;gBAEnB,OAAOV;;YAGXmS,KAAK,SAASpoB;gBACV,IAAIxc,OAAO/B,QAAQikB,QAAQ1F;gBAE3B,KAAKkjB,WAAWld,QAAQhG,KAAK;oBACzB,MAAM,IAAIxd,GAAGkG,MAAMsX,KAAK;;gBAG5Bve,QAAQ4uB,SAASrQ,IAAIxc;gBAErB,IAAI2/B,oBAAoB7P,QAAQgV,qBAAqBtoB,KAAK;oBACtDsjB,QAAQkC,SAASxlB;uBAEhB;oBACDinB,OAAOpG,KAAK7gB,IAAIxc;;;YAIxBoN,OAAO,SAASoP;gBACZ,IAAIuoB,eAAex4B,OAAO02B,eAAezmB;gBAEzC,IAAIuoB,cAAc;oBACd,OAAOx4B,OAAO63B,WAAW5nB,IAAIuoB;uBAE5B;oBACDx4B,OAAOq4B,IAAIpoB;oBACX,OAAO;;;;QAKnBxd,GAAGuG,OAAOtE;YAINyR,KAAK,SAAS8J,IAAI4E;gBACd0O,QAAQpd,IAAI1R,MAAMC,MAAMT;;YAM5B+L,QAAQ,SAASiQ;gBACb,IAAIilB,kBAAkBtE,KAAK3gB,KAAK;oBAC5B,OAAOjQ,OAAOa,MAAMoP;;gBAExB,OAAO;;YAGXmJ,OAAO,SAASnJ;gBAKZ,IAAIojB,4BAA4B;oBAC5B9P,QAAQwP,cAAc9iB,IAAIlK,KAAK2uB,gBAAgB;;gBAKnD,IAAIQ,kBAAkB6B,kBAAkB9mB,KAAK;oBACzC,OAAOjQ,OAAOa,MAAMoP;uBAMnB;oBACD,OAAOkjB,WAAWnzB,OAAOiQ;;;YAOjCgF,QAAQ,SAAShF;gBACb,IAAIwoB,eAAelV,QAAQtO,OAAOhF;gBAElC,IAAIxd,GAAG+Z,iBAAiBisB,eAAe;oBACnCA,aAAa/rB,KAAK;wBACd1M,OAAOiV,OAAOhF;;uBAGjB,IAAIwoB,iBAAiB,OAAO;oBAC7Bz4B,OAAOiV,OAAOhF;;;YAOtBkF,WAAW;gBACP,IAAIyhB,qBAAqB1B,kBAAkByB,yBACvCtwB;gBAIJ,IAAIuwB,mBAAmB//B,QAAQ;oBAC3B,KAAKwP,IAAIuwB,mBAAmB//B,SAAS,GAAGwP,KAAK,GAAGA,KAAK;wBACjD8sB,WAAWle,OAAO2hB,mBAAmBvwB;;;gBAI7C6uB,kBAAkB3lB;;YAKtBsH,SAAS,SAAS5G;gBACd,IAAIsT,QAAQ+T,YAAY/T,QAAQ+T,SAASrnB,KAAK;oBAC1C,OAAOsT,QAAQ+T,SAASrnB,IAAI5C;;gBAGhC,OAAOkW,QAAQ1M,WAAW0M,QAAQ1M,QAAQ5G;;YAI9CyoB,WAAW,SAASzoB;gBAChB,UAAUsT,QAAQ+T,YAAY/T,QAAQ+T,SAASrnB;;YAGnDhB,UAAU,SAASgB;gBACf,IAAIsT,QAAQtU,UAAU;oBAClB,OAAOsU,QAAQtU,SAASgB;;;YAIhCV,OAAO;gBACH1a,IAAI;gBACJs+B,WAAWhe;gBACX+f,kBAAkB3lB;gBAClBgU,QAAQhU;;YAGZgY,SAAS,SAAStX;gBACd,IAAIkjB,WAAWld,QAAQhG,KAAK;oBACxB,OAAOsT,QAAQgE,QAAQtX;;;YAO/BgG,SAAS,SAAShG;gBACd,OAAOsT,QAAQtN,QAAQhG;;YAG3B2H,uBAAuB;gBACnB,IAAI2L,QAAQ3L,uBAAuB;oBAC/B,OAAO2L,QAAQ3L;;gBAEnB;;YAWJkb,qBAAqB,SAAS7iB;gBAC1B,IAAIkjB,WAAWld,QAAQhG,KAAK;oBACxB,OAAOsT,QAAQuP,oBAAoB7iB;;;YAS3CpE,OAAO,SAASoE;gBACZ,IAAIkjB,WAAWwF,YAAY1oB,OAAOsT,QAAQ1X,SAASsnB,WAAWld,QAAQhG,OAAOsT,QAAQ1X,MAAMoE,KAAK;oBAC5FilB,kBAAkBC,KAAKllB;oBACvBsT,QAAQ0R,0BAA0BhlB;oBAClC,OAAO;;gBAEX,OAAO;;YAIX0oB,aAAa,SAAS1oB;gBAClB,SAASsT,QAAQoV,eAAepV,QAAQoV,YAAY1oB;;;QAI5Dxd,GAAGuG,OAAOtH,SAAS+b;QACnB5Y,MAAMnD,QAAQmD;QACdu+B,mBAAmB1hC,QAAQuZ,SAASyK,WAAWjjB,GAAGgW,kBAAkBwC;QACpEooB,6BAA6BD,oBAAoB1hC,QAAQuZ,SAASohB,WAAW3W;QAE7E4d,uBAAwB;YACpB,IAAIpN;YAEJA,SAASx0B,QAAQ+tB,qBAAqB;YAEtC,OAAOyG;;QAGXlmB,OAAOu3B;;IC9uBX9kC,GAAGmmC,uBAAuB,SAASnrB;QAC/B;QAEA,IAAI/b;YACImD,KAAK,SAASC,SAAS8H;WAE3Bi8B;QAEJpmC,GAAGuG,OAAOtH,SAAS+b;QAEnBhb,GAAGuG,OAAOtE;YACNokC,gBAAgB,SAAS7oB,IAAI7K;gBACzB,IAAI2zB,2BAA2B,SAAS7P;oBAChC9jB,SAAS8jB,MAAMp2B;;gBAGvB,IAAI4I,OAAOmP,aAAa;oBACpBguB,yBAAyB5oB,MAAMxd,GAAGiJ,QAAQ/D,OAAO,WAAWohC;uBAE3D;oBACDlkC,IAAI,yDAAyD;;;YAIrEmkC,uBAAuB,SAAS/oB;gBAC5B,IAAIvU,OAAOmP,aAAa;oBACpB,IAAIouB,WAAWJ,yBAAyB5oB;oBACxC,IAAIgpB,UAAU;wBACVA;;;;;;ICvBpBxmC,GAAGymC,oBAAoB,SAASroB;QAC5B;QAEA,IAAInf,UAAUmf,KAAKnf,SACf6xB,UAAU7uB,MACVg+B,QAAQ7hB,KAAK6hB,OACbyG,wBAAwB1mC,GAAGsQ,eAC3Bq2B,sBACAC,uBACAC,gCACAC,SAAS7nC,QAAQ6nC,QACjBra,YAAYxtB,QAAQwtB,WACpB9G,UAAUsa,MAAMta,SAChBvjB,MAAM69B,MAAM79B,KACZ2kC,sBAAsB,IAAI/mC,GAAGmmC;YAAsB/jC,KAAKA;;QAO5D,SAAS4kC,YAAYxpB;mBACVopB,iBAAiBppB;YAKxB,IAAIspB,QAAQ;gBACRlS,aAAaiS,0BAA0BrpB;uBAChCqpB,0BAA0BrpB;gBACjCupB,oBAAoBR,sBAAsB/oB;;YAG9C,IAAIypB,SAAS/5B,SAASg6B,eAAepW,QAAQqW,eAAe3pB;YAC5D,IAAIypB,QAAQ;gBAIRA,OAAO5yB,aAAa,OAAO;gBAE3BrU,GAAGinC,QAAQnhC;;;QAQnB,SAASshC,uBAAuBC;YAC5B,OAAOA,WAAW19B,MAAM,KAAK;;QAUjC,SAAS29B,oBAAoBtmC;YACzB,IAAIimC,SAASjnC,GAAGsS,UAAU,2CAA2CtR,OAAO;YAE5EimC,OAAO5yB,aAAa,MAAMrT;YAE1BimC,OAAOjiC,MAAMC,UAAU;YACvBiI,SAASq6B,KAAKjzB,YAAY2yB;YAE1B,OAAOA;;QAUX,SAASO,4BAA4BP,QAAQt0B;YACzC,IAAI00B,aAAaJ,OAAOzpB,IACpBkG,SAAS0jB,uBAAuBC,aAChC1pB,OAAOgI,QAAQjC;YAEnBijB,gBAAgBhpB,QAAQhL;YAIxBi0B,iBAAiBljB,UAAU1jB,GAAGinC,QAAQ/hC,OAAO,QAAQ;gBACjD,IAAI4rB,QAAQtU,SAASkH,SAAS;oBAC1BthB,IAAI,qEAAqEilC,aAAa;oBAEtFR,0BAA0BQ,cAAczb,WAAW;wBAC/C,IAAIqK,eAAe,kEAAkEoR;wBACrFjlC,IAAI6zB,cAAc;wBAClBtjB;4BACIxQ,OAAO8zB;;uBAEZ;;;YAMX8Q,oBAAoBV,eAAegB,YAAY,SAAShlC;gBACpDD,IAAI,6CAA6CC,UAAU;gBAC3D,IAAIqhB,SAAS0jB,uBAAuBC,aAChC5T,WAAW3C,QAAQ2W,mBAAmBplC,UACtCsb,OAAO8V,SAAS9V,MAChB+pB;gBAEJ,IAAI/pB,QAAQgpB,gBAAgBhpB,OAAO;oBAC/Bvb,IAAI,uCAAuCilC;oBAC3CzS,aAAaiS,0BAA0BQ;2BAChCR,0BAA0BQ;oBAEjCvW,QAAQ6W,iBAAiBN;oBAEzBK,iBAAiBf,gBAAgBhpB;2BAE1BgpB,gBAAgBhpB;oBACvBopB,oBAAoBR,sBAAsBc;oBAC1CK,eAAejU;uBAEd,KAAK9V,MAAM;oBACZvb,IAAI,MAAMC,UAAU;;;;QAKhCrC,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGggC,cAAc5hB;QAErCpe,GAAG2P,SAAS1N,MAAM,SAAS6N;YACvB;gBAII4D,KAAK,SAAS8J,IAAIoS;oBACd9f,OAAO4D,IAAI8J;wBAAKvQ,OAAO2iB;;oBAEvBA,UAAUvb,aAAa,QAAQoY;oBAG/B,IAAImD,UAAU/pB,YAAY;wBACtB7F,GAAG4vB,WAAW9pB;;;gBAItBgvB,SAAS,SAAStX;oBACdwpB,YAAYxpB;oBACZ1N,OAAOglB,QAAQtX;;gBAGnBgG,SAAS,SAAShG;oBACd,OAAO1N,OAAO0T,QAAQhG,OAClBsT,QAAQwP,cAAc9iB,IAAIvQ,UAAU3M;;;;QAKpDN,GAAGuG,OAAOtE;YACNua,UAAU,SAASgB;gBACf,OAAOsT,QAAQwP,cAAc9iB,IAAIvQ;;YAWrC26B,kBAAkB,SAASX,QAAQt0B;gBAE/B,IAAIk1B;gBAEJ,IAAIf,QAAQ;oBACRU,4BAA4BP,QAAQt0B;uBAEnC;oBACDi0B,iBAAiBK,OAAOzpB,MAAMxd,GAAGinC,QAAQ/hC,OAAO,QAAQ;wBACpD9C,IAAI,2BAA2B6kC,OAAOzpB;wBAKtC,KAAKypB,OAAOphC,YAAY;4BACpB;;wBAGJ;4BAEI,IAAIohC,OAAOa,mBACPb,OAAOa,gBAAgBP,QACvBN,OAAOa,gBAAgBP,KAAK90B,aAAa,SAAS;gCAKlD;;0BAGR,OAAOtQ;4BAEHC,IAAI,gFAAgFD,MAAME,UAAU,KAAK;4BACzGwlC;gCAAsBx4B,SAAS;;;wBAGnCsD,SAASk1B;;;;YAWrBE,eAAe,SAASvqB;gBACpB,IAAI6pB,aAAavW,QAAQqW,eAAe3pB;gBAExC,OAAO8pB,oBAAoBD;;YAQ/BM,kBAAkB,SAASnqB;gBACvB,IAAIopB,iBAAiBppB,QAAQld,WAAW;oBACpCsmC,iBAAiBppB;2BACVopB,iBAAiBppB;;;YAQhC2pB,gBAAgB,SAASzjB;gBACrB,OAAOA,SAAS,MAAMgjB;;YAY1BsB,oBAAoB,SAAS5pB;gBACzB,IAAI+K,SAAS/K,KAAK+K,QACdtI,WAAWzC,KAAKyC,UAChBrhB,SAAS4e,KAAK5e,QACdg5B,eAAepa,KAAKoa,cACpByP,aAAa7pB,KAAK6pB,YAClB7zB,OAAOpU,GAAGsS,UAAU,mBAAmB6W,SAAS,4CAChDwU,MAAM9c;gBAEV,IAAI2X,cAAc;oBACdx4B,GAAGmU,WAAW3U,QAAQ4U;uBAErB;oBACDupB,MAAM39B,GAAGoT,QAAQ5T,QAAQqhB;;gBAG7BzM,KAAKC,aAAa,UAAUspB;gBAC5BvpB,KAAKC,aAAa,UAAU4zB;gBAC5B7zB,KAAKpP,MAAMC,UAAU;gBACrBiI,SAASq6B,KAAKjzB,YAAYF;gBAE1B,OAAOA;;YAOXqzB,oBAAoB,SAASS;gBACzB,IAAIzU;gBAEJ;oBACIA,WAAWzzB,GAAGuU,UAAU2zB;kBAE5B,OAAO/lC;oBACHC,IAAI,4DAA4DD,MAAME,UAAU,KAAK;;gBAGzF,OAAOoxB;;;;ICnSnBzzB,GAAGmoC,mBAAmB,SAAS/pB;QAC3B;QAEA,IAAI0S,UAAU7uB,MACVtC,YAAYye,KAAKnf,QAAQU,WACzBsgC,QAAQ7hB,KAAK6hB,OACbznB,WAAW4F,KAAKnf,QAAQuZ,UACxBc,SAAS8E,KAAKnf,QAAQqa,QACtB8uB,aAAa5vB,YAAY4F,KAAKnf,QAAQuZ,SAASyK,WAAWjjB,GAAGgW,kBAAkBwC,UAC/E6vB,gBAAgB/uB,UAAU8E,KAAKnf,QAAQqa,OAAO2J,WAAWmlB,cAAcpoC,GAAGgW,kBAAkBsD,QAC5F4J,UAAU+c,MAAM/c,SAChBkC,UAAU6a,MAAM7a,SAChBO,UAAUsa,MAAMta,SAChBf,cAAcqb,MAAMrb,aACpB8J,gBAAgBuR,MAAMvR,eACtBH,gBAAgB0R,MAAM1R,eACtBrB,aAAa+S,MAAM/S,YACnB9qB,MAAM69B,MAAM79B;QAEhB,SAASkgC,MAAM9kB;YACXxd,GAAGY,KAAKkwB,QAAQqR,SAAS3kB,KAAK,SAAS8qB,OAAO9wB;gBAC1C,IAAI+wB,gBAAgBzX,QAAQ0X,kBAAkBhrB,IAAI8qB;gBAElD9wB,IAAIwmB,qBAAqB;gBACzBxmB,IAAIjK,OAAOuvB,aAAa;gBACxBtlB,IAAI8qB;gBACJiG,iBAAiBA,cAAcxI,YAAYwI,cAAcxI,SAASviB;;;QAI1Exd,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGggC,cAAc5hB;QAErCpe,GAAG2P,SAAS1N,MAAM,SAAS6N;YACvB;gBAII4D,KAAK,SAAS8J,IAAIirB;oBACd,IAAIzoC,GAAG+L,OAAO08B,gBAAgBzoC,GAAG8M,OAAO27B,cAAc;wBAClD34B,OAAO4D,IAAI8J;4BAAK4E,MAAMqmB;;2BAErB,IAAIA,uBAAuBzoC,GAAG2a,WAAW;wBAC1C7K,OAAO4D,IAAI8J;4BAAKyiB,OAAOwI;;2BAEtB;wBACD,MAAM,IAAIviC,MAAM;;oBAGpB4qB,QAAQ4X,eAAelrB;oBACvB6qB,iBAAiBvX,QAAQ6X,uBAAuBnrB;;gBAGpDsX,SAAS,SAAStX;oBACd8kB,MAAM9kB;oBACNsT,QAAQ0Q,+BAA+BhkB;oBACvCsT,QAAQ8T,WAAWpnB;oBACnB1N,OAAOglB,QAAQtX;;;;QAK3Bxd,GAAGuG,OAAOtE;YAEN0/B,kBAAkB,SAASnkB,IAAIujB;uBACpBjQ,QAAQwP,cAAc9iB,IAAIlK,KAAKs1B,aAAa7H;;YAGvDuC,UAAU,SAAS9lB,IAAIujB;gBACnB,IAAI8H,YAAY/X,QAAQwP,cAAc9iB,IAAIlK;gBAE1C,IAAIu1B,UAAUC,MAAM;2BACTD,UAAUC,KAAK/H;;gBAE1B,IAAI8H,UAAUE,gBAAgB;2BACnBF,UAAUE,eAAehI;;;YAMxCM,gBAAgB,SAAS7jB,IAAIwrB;gBACzB,IAAIC,eAAenY,QAAQgS,gBAAgBtlB,MAAM,GAC7ChG,MAAMsZ,QAAQoY,QAAQ1rB,IAAIyrB;gBAE9B,IAAID,gBAAgB;oBAChB,OAAO,IAAIhpC,GAAGmP,UAAUE,QAAQ25B,eAAexxB,MAAMA;;gBAGzD,OAAO,IAAIxX,GAAGmP,UAAUE,YAAYmI;;YAGxC4M,SAAS,SAAS5G;gBACd,OAAOsT,QAAQtN,QAAQhG,OAAOsT,QAAQwP,cAAc9iB,IAAI4E;;YAG5DyiB,UAAU,SAASrnB;gBACf,OAAOsT,QAAQtN,QAAQhG,OAAOsT,QAAQwP,cAAc9iB,IAAIyiB;;YAO5D9a,uBAAuB;gBACnB,IAAIgkB;gBAEJrY,QAAQsY,sBAAsB,SAASjpC,KAAK4iB;oBACxC+N,QAAQ0R,0BAA0B,MAAMzf,WAAWvK,SAASspB,YAAa/e,WAAWvK,SAASupB;oBAE7F,IAAI1hC;wBACAW,MAAM+hB,WAAW/hB;wBACjB+gC,WAAWhf,WAAWvK,SAASupB;wBAC/BxjB,MAAMwE,WAAWxE;wBACjBZ,MAAMoF,WAAWpF;;oBAGrB,IAAIoF,WAAW5iB,KAAK;wBAChBE,KAAKF,MAAM4iB,WAAW5iB;;oBAG1BgpC,mBAAmBrnC,KAAKzB;;gBAG5B,OAAO8oC;;YAGXjD,aAAa,SAAS1oB;gBAClB,SAAShF,YAAYsY,QAAQtN,QAAQhG,QAAQsT,QAAQwP,cAAc9iB,IAAI6rB;;YAG3E7G,2BAA2B,SAAShlB,IAAI8rB,eAAeC;gBACnD,IAAIzH,aAAawH,iBAAiBxY,QAAQwP,cAAc9iB,IAAIhF,SAASspB,YACjEC,YAAYwH,gBAAgBzY,QAAQwP,cAAc9iB,IAAIhF,SAASupB;gBAEnE,IAAID,YAAY;oBACZ1/B,IAAIpC,GAAGyL,OAAO,0DAA0DgJ,KAAK6pB,UAAUwD;oBACvFA,WAAW0H;oBACXxpC,GAAGY,KAAKkhC,YAAY,SAASlgC,KAAKm/B;wBAC9BgB,UAAUC,QAAQjB;;oBAEtBe,WAAW19B,SAAS;;;YAI5BgV,OAAO,SAASoE;gBACZ,IAAIsT,QAAQtN,QAAQhG,KAAK;oBACrBpb,IAAIpC,GAAGyL,OAAO,6DAA6D+R,IAAI0F,QAAQ1F;oBACvFsT,QAAQwP,cAAc9iB,IAAIisB,SAAS;oBACnCnH,MAAM9kB;oBACN,OAAO;;;YAIfulB,oBAAoB,SAASvlB;gBACzB,IAAIhF,YAAYsY,QAAQtN,QAAQhG,KAAK;oBACjC,IAAIjD,QAAQuW,QAAQwP,cAAc9iB,KAC9BksB,aACA91B;2BAEG2G,MAAM/B;oBAEb+B,MAAM/B;oBACNkxB,cAAc5Y,QAAQgS,gBAAgBtlB;oBACtC,IAAIksB,cAAc,KAAKlxB,SAASqhB,WAAW;wBACvCtf,MAAM/B,SAASyK,UAAU;wBACzB1I,MAAM/B,SAASmxB,QAAQD;wBACvBnvB,MAAM/B,SAASupB;wBAEf,KAAKnuB,IAAI,GAAGA,IAAI81B,aAAa91B,KAAK;4BAC9B2G,MAAM/B,SAASupB,UAAUjgC,KAAK8R;;wBAGlCkd,QAAQ4X,eAAelrB;2BAEtB;wBACDjD,MAAM/B,SAASyK,UAAU;;;;YAKrCqiB,YAAY,SAAS9nB,IAAIosB;gBACrB,IAAI9Y,QAAQtN,QAAQhG,KAAK;oBACrBsT,QAAQwP,cAAc9iB,IAAI4E,OAAOwnB;;;YAIzChF,YAAY,SAASpnB;gBACjB,IAAIqrB,YAAY/X,QAAQwP,cAAc9iB,IAAIlK;gBAE1CtT,GAAGY,KAAKioC,UAAUE,gBAAgB,SAASc;2BAChChB,UAAUE,eAAec;;gBAGpC7pC,GAAGY,KAAKioC,UAAUC,MAAM,SAASe;2BACtBhB,UAAUC,KAAKe;;;YAW9BC,YAAY,SAAStsB,IAAIusB;gBACrB,OAAOjZ,QAAQkZ,aAAaxsB,IAAIusB,aAAa/pC,GAAGsN;;YAGpDk7B,mBAAmB,SAAShrB,IAAIusB;gBAC5B,IAAIhJ,WAAWgJ,eAAe,QAAQ,IAAIA;gBAC1C,OAAOjZ,QAAQwP,cAAc9iB,IAAIlK,KAAKy1B,eAAehI;;YAGzDC,eAAe,SAASxjB,IAAIysB;gBACxB,IAAIhQ,YAAYzhB,SAAS4hB,UACrB8P,WAAW9kB,QAAQ5H,KACnBrP,aAAa2iB,QAAQ1M,QAAQ5G,KAC7B2sB,aAAalQ,YAAYgQ,YACzBG,WAAWD,aAAalQ,aAAaiQ,WAAWA,WAAWC,aAAalQ,WACxEyP,cAAc5Y,QAAQgS,gBAAgBtlB,KACtCorB,eAAe3mC,KAAKq+B,cAAc9iB,IAAIlK,KAAKs1B,cAI3C/5B,OAAO+5B,aAAaqB,eAAejqC,GAAGkO,UAAUC,YAAYg8B,YAAYC;gBAE5ExB,aAAaqB,cAAcp7B;gBAE3B;oBACIw7B,MAAMJ;oBACN77B,OAAO+7B;oBACP97B,KAAK+7B;oBACLE,OAAOZ;oBACP76B,MAAMA;oBACN0P,MAAM6rB,WAAWD;;;YAIzBhJ,0BAA0B,SAASnT;gBAC/B;oBACI+L,WAAW/L,UAAUqc;oBACrBE,WAAWvc,UAAU5f,QAAQ;oBAC7Bo8B,SAASxc,UAAU3f;oBACnB8rB,YAAYnM,UAAUsc;;;YAQ9BG,oBAAoB,SAASjtB;gBACzB,IAAIktB,gBAAgB,OAChB1pC,OAAOkiB,QAAQ1F,KACfe,OAAO6G,QAAQ5H,KACfyc,YAAYzhB,SAAS4hB,UACrBvZ,WAAW+D,YAAYpH;gBAE3B,OAAOxd,GAAGyL,OAAO,4BAA4B9L,WAAW+qC,eAAe1pC,MAAMud,MAAM0b,WAAWpZ;;YAGlG8pB,cAAc,SAASntB;gBACnB,OAAOsT,QAAQ1M,QAAQ5G,IAAIra;;YAG/BynC,qBAAqB,SAASptB;gBAC1B,OAAOsT,QAAQwP,cAAc9iB,IAAIhF;;YAOrCsqB,iBAAiB,SAAStlB;gBACtB,IAAIhF,UAAU;oBACV,IAAI0xB,WAAW9kB,QAAQ5H,KACnByc,YAAYzhB,SAAS4hB;oBAEzB,OAAO/zB,KAAKwkC,KAAKX,WAAWjQ;;;YAIpCiP,SAAS,SAAS1rB,IAAIusB;gBAClB,IAAIhJ,WAAWgJ,eAAe,QAAQ,IAAIA;gBAC1C,OAAOjZ,QAAQwP,cAAc9iB,IAAIlK,KAAKw1B,KAAK/H;;YAG/CoB,UAAU,SAAS3kB;gBACf,OAAOsT,QAAQwP,cAAc9iB,IAAIlK,KAAKw1B;;YAK1CM,uBAAuB,SAASz2B;gBAC5B,IAAI01B,eAAe;oBACfroC,GAAGY,KAAKoX,cAAc,SAAS7X,KAAK8K;wBAChC,IAAI9K,IAAIyJ,QAAQ5J,GAAGyL,OAAO,cAAc9L,gBAAgB,GAAG;4BACvD,IAAIojB,aAAatO,KAAKC,MAAMzJ;4BAC5B0H,SAASxS,KAAK4iB;;;;;YAM9B2lB,gBAAgB,SAASlrB;gBACrBsT,QAAQwP,cAAc9iB,IAAIlK;oBACtBy1B;oBACA7H;oBACA4H;oBACAF;;;YAIRkC,mBAAmB,SAASttB;gBACxBsT,QAAQwP,cAAc9iB,IAAI6rB,eAAe;;YAK7C7H,gCAAgC,SAAShkB;gBACrC,IAAIutB;gBAEJ,IAAI1C,iBAAiBvX,QAAQoV,YAAY1oB,KAAK;oBAC1CutB,iBAAiBja,QAAQ2Z,mBAAmBjtB;oBAE5C,IAAIutB,kBAAkB/yB,aAAalF,QAAQi4B,iBAAiB;wBACxD/yB,aAAagzB,WAAWD;wBACxB,OAAO;;;gBAIf,OAAO;;YAKXpC,wBAAwB,SAASnrB;gBAC7B,IAAIjD,QAAQuW,QAAQwP,cAAc9iB,KAC9ButB,gBAAgBE;gBAIpB,IAAI5C,iBAAiB9tB,MAAMpa,QAAQG,WAAW;oBAC1CyqC,iBAAiBja,QAAQ2Z,mBAAmBjtB;oBAC5CytB,gBAAgBjzB,aAAalF,QAAQi4B;oBAGrC,IAAIE,eAAe;wBACfA,gBAAgBx2B,KAAKC,MAAMu2B;wBAI3B,IAAIvc,cAAcuc,cAActtB,OAAO;4BACnCmT,QAAQga,kBAAkBttB;+BAEzB;4BACDpb,IAAIpC,GAAGyL,OAAO,2DAA2D+R,IAAI0F,QAAQ1F;4BAErF+Q,cAAc/Q,IAAIytB,cAActtB;4BAEhCpD,MAAMpa,MAAM8qC,cAAc9qC;4BAC1Boa,MAAM/B,WAAWyyB,cAAczyB;4BAC/B+B,MAAM4S,SAAS8d,cAAc9d;4BAC7B5S,MAAM0mB,mBAAmB;4BAEzBnQ,QAAQ0R,0BAA0BhlB;;;;;YAOlD6lB,2BAA2B,SAAS7lB;gBAChC,IAAIjD,QAAQuW,QAAQwP,cAAc9iB,KAC9ButB,gBAAgBE;gBAGpB,IAAI5C,iBAAiBvX,QAAQoV,YAAY1oB,KAAK;oBAC1CutB,iBAAiBja,QAAQ2Z,mBAAmBjtB;oBAE5CytB;wBACIjqC,MAAMkiB,QAAQ1F;wBACde,MAAM6G,QAAQ5H;wBACdG,MAAMgI,QAAQnI;wBACdrd,KAAKoa,MAAMpa;wBACXqY,UAAU+B,MAAM/B;wBAChB2U,QAAQ5S,MAAM4S;wBACd+d,aAAarL,KAAK+F;;oBAGtB;wBACI5tB,aAAaC,QAAQ8yB,gBAAgBt2B,KAAK6pB,UAAU2M;sBAExD,OAAO9oC;wBACHC,IAAIpC,GAAGyL,OAAO,2DAA2D+R,IAAIrb,MAAMqI,aAAa;;;;YAK5G2gC,0BAA0B,SAAS3tB,IAAIujB,UAAU9G;gBAC7C,IAAIziB,MAAMsZ,QAAQoY,QAAQ1rB,IAAIujB,WAC1B//B,OAAOkiB,QAAQ1F,KACf4tB;oBACI3G,QAAQ,SAAStX,QAAQC;wBACrB,IAAI8c,WAAW9kB,QAAQ5H;wBAEvB,IAAI2P,WAAWC,OAAO;4BAClBF,WAAW1P,IAAIxc,MAAMkpC,UAAUA;+BAE9B;4BACDhd,WAAW1P,IAAIxc,MAAOmsB,UAAU+c,WAAWA,WAAW,IAAI/c,QAAS+c;;;oBAI3EpJ,SAAS,SAAS3T,QAAQC;wBACtB,IAAI8T,gBAAgBpQ,QAAQwP,cAAc9iB,IAAIlK,KAAK4tB,eAC/CmK,iCAAiCva,QAAQwP,cAAc9iB,IAAI2P,QAC3Dme,mBAAmBne,QACnBoe,kBAAkBne,OAClB8M,gBAAgB9U,QAAQ5H,KACxBguB,uBAAuBF,oBAAoBC,kBAAkBtR,YAC7DwR,qBAAqBJ;wBAEzBnK,cAAcH,YAAYyK;wBAE1BxrC,GAAGY,KAAKsgC,eAAe,SAASH,UAAU2K;4BACtCD,sBAAsBC;;wBAG1Bxe,WAAW1P,IAAIxc,MAAMyqC,oBAAoBvR;;;gBAIrD1iB,IAAIjK,OAAOuvB,aAAa,SAAS1qB;oBAC7B,IAAIA,EAAEqsB,kBAAkB;wBAEpB,IAAIt7B,OAAO82B,aAAa,OAAO,WAAW;wBAC1CmR,mBAAmBjoC,MAAMiP,EAAE+a,QAAQ/a,EAAEgb;;;;YAcjD4c,cAAc,SAASxsB,IAAIusB,aAAavyB,KAAKm0B;gBACzC,IAAIC,SAAS7B,eAAe,QAAQ,IAAIA,aACpClB,YAAY/X,QAAQwP,cAAc9iB,IAAIlK;gBAE1Cu1B,UAAUC,OAAOD,UAAUC;gBAC3BD,UAAUE,iBAAiBF,UAAUE;gBAErCF,UAAUC,KAAK8C,UAAUp0B;gBAEzB,IAAIm0B,kBAAkB;oBAClB9C,UAAUE,eAAe6C,UAAUD;;gBAGvC,OAAOn0B;;YAIX0tB,+BAA+B;gBAC3B,IAAI2G,iBAAiBvyB,OAAO+gB;gBAE5BvJ,QAAQsY,sBAAsB,SAASjpC,KAAK4iB;oBACxC,IAAI+oB,iBAAiB,IAAIjM,KAAK9c,WAAWmoB;oBAGzCY,eAAeC,QAAQD,eAAeE,YAAYH;oBAElD,IAAIC,eAAehM,aAAaD,KAAK+F,OAAO;wBACxCxjC,IAAI,6CAA6CjC;wBACjD6X,aAAagzB,WAAW7qC;;;;YAWpC2lC,sBAAsB,SAAStoB;gBAC3B,IAAIjD,QAAQuW,QAAQwP,cAAc9iB;gBAElC,KAAKjD,MAAM/B,UAAU;oBACjBsY,QAAQiS,mBAAmBvlB;;gBAG/B,OAAOjD,MAAM/B,SAASyK;;;;ICxflCjjB,GAAGkpB,0BAA0B,SAASlO;QAClC;QAEA,IAAIixB,WACAhtC;YACIkqB,QAAQ;YACRE,eAAe;YACfK;YACAN,gBAAgB;YAChBI,eAAe,SAAShM;gBAAK;;YAC7BiM;YACAE;gBACIoI,UAAU;gBACVyI,iBAAiB;;YAErBp4B,KAAK,SAASsJ,KAAKvB;YACnByf,UAAU,SAASpM;YACnBsM,kBAAkB,SAAStM,IAAIuM,UAAUC;;QAGjDhqB,GAAGuG,OAAOtH,SAAS+b;QAEnB,SAASkxB;YACL,IAAIjtC,QAAQkqB,OAAOtpB,kBAAkB,QAAQ;gBACzC;oBACIssC,SAAS;;;YAIjB;;QAGJF,YAAYjsC,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7B;YAC/BI,cAAc;YACdC,gBAAe,QAAQ;YACvBzS,QAAQlqB,QAAQkqB;YAChBO,eAAezqB,QAAQyqB;YACvBD,aAAaxqB,QAAQwqB;YACrBqS,gBAAgBoQ;YAChB9iB,gBAAgBnqB,QAAQmqB;YACxBI,eAAe,SAAShM;gBACpB,OAAOve,QAAQuqB,cAAc1E,IAAItH;;YAErCpb,KAAKnD,QAAQmD;YACbk6B,QAAQr9B,QAAQ2qB;YAChB0D,YAAYruB,QAAQ6qB;YACpBH,MAAM1qB,QAAQ0qB;;QAGlB3pB,GAAGuG,OAAOtE;YACN0zB,YAAY,SAASnY,IAAIG,MAAM4X;gBAC3B,IAAIzI,oBAAoByI;gBAExBt2B,QAAQmD,IAAI,wCAAwCob;gBAEpD,IAAIve,QAAQkqB,WAAW,UAAU;oBAC7B8iB,UAAUjN,cAAcxhB,IACnB2hB,SAASxhB,MACT0hB,WAAWvS,mBACXuR;uBAEJ;oBACDvR,kBAAkB7tB,QAAQoqB,iBAAiB1L;oBAC3CsuB,UAAUjN,cAAcxhB,IACnB6hB,WAAWvS,mBACXuR;;;;;KCpDrB;QAMI,SAAS+N,kBAAkBC;YACvB,IAAIC,KAAKD,IAAIE,cACTC,KAAKH,IAAII,eACTlkC,SAAS2E,SAASC,cAAc,WAChCu/B;YAEJ,IAAIJ,KAAKE,KAAK,OAAO,MAAM;gBACvBjkC,OAAOokC,QAAQpkC,OAAO8T,SAAS;gBAC/BqwB,MAAMnkC,OAAOqkC,WAAW;gBACxBF,IAAIG,UAAUR,MAAMC,KAAK,GAAG;gBAI5B,OAAOI,IAAII,aAAa,GAAG,GAAG,GAAG,GAAGzsC,KAAK,OAAO;mBAC7C;gBACH,OAAO;;;QAQf,SAAS0sC,qBAAqBV,KAAKC,IAAIE;YACnC,IAAIjkC,SAAS2E,SAASC,cAAc,WAChC6/B,KAAK,GACLC,KAAKT,IACLU,KAAKV,IACLE,KAAKrsC,MAAM8sC,OAAOC;YAEtB7kC,OAAOokC,QAAQ;YACfpkC,OAAO8T,SAASmwB;YAChBE,MAAMnkC,OAAOqkC,WAAW;YACxBF,IAAIG,UAAUR,KAAK,GAAG;YACtBhsC,OAAOqsC,IAAII,aAAa,GAAG,GAAG,GAAGN,IAAInsC;YAGrC,OAAO6sC,KAAKF,IAAI;gBACZG,QAAQ9sC,MAAM6sC,KAAK,KAAK,IAAI;gBAC5B,IAAIC,UAAU,GAAG;oBACbF,KAAKC;uBACF;oBACHF,KAAKE;;gBAETA,KAAMD,KAAKD,MAAO;;YAGtBI,QAASF,KAAKV;YACd,OAAQY,UAAU,IAAK,IAAIA;;QAM/B,SAASC,qBAAqBhB,KAAKx9B,MAAM5P,SAASquC;YAC9C,IAAI/kC,SAAS2E,SAASC,cAAc,WAChC3E,OAAOvJ,QAAQuJ,QAAQ,cACvB0G,UAAU,IAAIlP,GAAGmP;YAErBo+B,oBAAoBlB,KAAKx9B,MAAMtG,QAAQtJ,SAASquC,UAC3CrzB,KAAK;gBACF/K,QAAQG,QACJ9G,OAAOI,UAAUH,MAAMvJ,QAAQwJ,WAAW;;YAItD,OAAOyG;;QAGX,SAASs+B,oCAAoCpvB;YACzC,IAAIqvB,YAAY;YAEhB,KAAKztC,GAAG4R,OAAO;gBACX,MAAM,IAAI5R,GAAGkG,MAAM;;YAGvB,IAAIkY,KAAKsvB,aAAatvB,KAAKuvB,YAAYF,WAAW;gBAC9C;oBACIG,WAAWvnC,KAAKC,MAAMD,KAAKwnC,KAAKJ,aAAarvB,KAAKsvB,aAAatvB,KAAKuvB;oBACpEG,UAAUznC,KAAKC,MAAMD,KAAKwnC,KAAKJ,aAAarvB,KAAKuvB,YAAYvvB,KAAKsvB;;;;QAQ9E,SAASH,oBAAoBlB,KAAKx9B,MAAMtG,QAAQtJ,SAASquC;YACrD,IAAIhB,KAAKD,IAAIE,cACTC,KAAKH,IAAII,eACTE,QAAQ1tC,QAAQ0tC,OAChBtwB,SAASpd,QAAQod,QACjBqwB,MAAMnkC,OAAOqkC,WAAW,OACxB19B,UAAU,IAAIlP,GAAGmP,WACjB4+B;YAEJrB,IAAIsB;YAEJ,IAAI/uC,QAAQgvC,QAAQ;gBAChB,OAAOC;oBACHr/B,MAAMA;oBACNtG,QAAQA;oBACRqvB,OAAOyU;oBACP8B,aAAa3B;oBACb4B,YAAY9B;oBACZ+B,aAAapvC,QAAQovC;oBACrBJ,QAAQhvC,QAAQgvC;oBAChBK,cAAcjyB;oBACdkyB,aAAa5B;;;YAIrB,KAAK3sC,GAAGgW,kBAAkByD,0BAA0B;gBAChDs0B,qBAAqBP;oBACjBG,WAAWhB;oBACXe,YAAYrxB;;gBAGhB,IAAI0xB,oBAAoB;oBACpB/tC,GAAGoC,IAAIpC,GAAGyL,OAAO,kFACbkhC,OAAOtwB,QAAQ0xB,mBAAmBD,UAAUC,mBAAmBH,YAC/D;oBAEJjB,QAAQoB,mBAAmBD;oBAC3BzxB,SAAS0xB,mBAAmBH;;;YAIpCY,oBAAoBjmC,QAAQokC,OAAOtwB,QAAQpd,QAAQovC;YAInD,IAAIruC,GAAG4R,OAAO;iBACT;oBACG,IAAIw6B,kBAAkBC,MAAM;wBACxBC,MAAM;wBACNE,MAAM;;oBAGV,IAAIiC,IAAI,MACJC,YAAYxhC,SAASC,cAAc,WACnCwhC,kBAAkBrB,WAAWP,qBAAqBV,KAAKC,IAAIE,MAAM,GACjEoC,KAAKvoC,KAAKwkC,KAAK4D,IAAI9B,QAAQL,KAC3BuC,KAAKxoC,KAAKwkC,KAAK4D,IAAIpyB,SAASmwB,KAAKmC,kBACjC3B,KAAK,GACL8B,KAAK,GACLC,QAAQC,IAAIC;oBAEhBP,UAAU/B,QAAQ+B,UAAUryB,SAASoyB;oBACrCM,SAASL,UAAU9B,WAAW;oBAE9B,OAAOI,KAAKR,IAAI;wBACZwC,KAAK;wBACLC,KAAK;wBACL,OAAOD,KAAK1C,IAAI;4BACZyC,OAAOG,UAAU,GAAG,GAAGT,GAAGA;4BAC1BM,OAAOlC,UAAUR,MAAM2C,KAAKhC;4BAC5BN,IAAIG,UAAU6B,WAAW,GAAG,GAAGD,GAAGA,GAAGQ,IAAIH,IAAIF,IAAIC;4BACjDG,MAAMP;4BACNQ,MAAML;;wBAEV5B,MAAMyB;wBACNK,MAAMD;;oBAEVnC,IAAIyC;oBACJT,YAAYK,SAAS;;mBAGxB;gBACDrC,IAAIG,UAAUR,KAAK,GAAG,GAAGM,OAAOtwB;;YAGpC9T,OAAO6mC,mBAAmB7mC,OAAO6mC;YACjClgC,QAAQG;YAER,OAAOH;;QAGX,SAASg/B,qCAAqCmB;YAC1C,IAAIxgC,OAAOwgC,WAAWxgC,MAClB+oB,QAAQyX,WAAWzX,OACnBuW,cAAckB,WAAWlB,aACzBC,aAAaiB,WAAWjB,YACxBC,cAAcgB,WAAWhB,aACzBn/B,UAAU,IAAIlP,GAAGmP,WACjB8+B,SAASoB,WAAWpB,QACpBqB,eAAepiC,SAASC,cAAc,WACtCoiC,sBAAsBD,aAAa1C,WAAW,OAC9C4C,eAAeH,WAAW9mC,QAC1B+lC,eAAee,WAAWf,cAC1BC,cAAcc,WAAWd;YAE7BC,oBAAoBc,cAAclB,YAAYD,aAAaE;YAE3DmB,aAAanzB,SAASiyB;YACtBkB,aAAa7C,QAAQ4B;YAErBgB,oBAAoB1C,UAAUjV,OAAO,GAAG;YAExCqW;gBACIp/B,MAAMA;gBACNwN,QAAQiyB;gBACR1W,OAAOA;gBACP0X,cAAcA;gBACdE,cAAcA;gBACd7C,OAAO4B;eAENt0B,KACG,SAAS5K;gBACLmgC,aAAaJ,mBAAmBI,aAAaJ;gBAC7ClgC,QAAQG;eAEZH,QAAQK;YAGhB,OAAOL;;QAOX,SAASs/B,oBAAoBjmC,QAAQokC,OAAOtwB,QAAQgyB;YAChD,QAAQA;cACJ,KAAK;cACL,KAAK;cACL,KAAK;cACL,KAAK;gBACD9lC,OAAOokC,QAAQtwB;gBACf9T,OAAO8T,SAASswB;gBAChB;;cACJ;gBACIpkC,OAAOokC,QAAQA;gBACfpkC,OAAO8T,SAASA;;YAExB,IAAIqwB,MAAMnkC,OAAOqkC,WAAW;YAC5B,QAAQyB;cACJ,KAAK;gBAED3B,IAAI+C,UAAU9C,OAAO;gBACrBD,IAAIvoB,OAAO,GAAG;gBACd;;cACJ,KAAK;gBAEDuoB,IAAI+C,UAAU9C,OAAOtwB;gBACrBqwB,IAAIgD,OAAOrpC,KAAKspC;gBAChB;;cACJ,KAAK;gBAEDjD,IAAI+C,UAAU,GAAGpzB;gBACjBqwB,IAAIvoB,MAAM,IAAI;gBACd;;cACJ,KAAK;gBAEDuoB,IAAIgD,OAAO,KAAMrpC,KAAKspC;gBACtBjD,IAAIvoB,MAAM,IAAI;gBACd;;cACJ,KAAK;gBAEDuoB,IAAIgD,OAAO,KAAMrpC,KAAKspC;gBACtBjD,IAAI+C,UAAU,IAAIpzB;gBAClB;;cACJ,KAAK;gBAEDqwB,IAAIgD,OAAO,KAAMrpC,KAAKspC;gBACtBjD,IAAI+C,UAAU9C,QAAQtwB;gBACtBqwB,IAAIvoB,OAAO,GAAG;gBACd;;cACJ,KAAK;gBAEDuoB,IAAIgD,QAAQ,KAAMrpC,KAAKspC;gBACvBjD,IAAI+C,WAAW9C,OAAO;gBACtB;;cACJ;gBACI;;;QAOZ,SAASiD,aAAaC,UAAUC;YAC5B,IAAI/rC,OAAO9B;YAEX,IAAIgH,OAAOO,QAAQqmC,oBAAoBrmC,MAAM;iBACxC;oBACG,IAAI6iC,MAAM,IAAI0D,SACVC,MAAM/mC,OAAO+mC,OAAO/mC,OAAO+mC,IAAIC,kBAAkBhnC,OAAO+mC,MACpD/mC,OAAOinC,aAAajnC,OAAOinC,UAAUD,kBAAkBhnC,OAAOinC,YAAY;oBAClF,KAAKF,KAAK;wBAAE,MAAM9pC,MAAM;;oBACxBmmC,IAAI8D,MAAMH,IAAIC,gBAAgBJ;oBAC9B9rC,KAAK8K,OAAOghC;oBACZA,WAAWxD;;;YAGnB,KAAKwD,SAAStD,iBAAiBsD,SAASpD,eAAe;gBACnDoD,SAASzgC,SAAS;oBACd,IAAIghC,YAAYrsC,KAAKssC;oBACrB,IAAID,WAAW;wBACXrsC,KAAKssC,qBAAqB;wBAG1BzkB,WAAW;4BACP,KAAK,IAAIhY,IAAI,GAAGxD,MAAMggC,UAAUhsC,QAAQwP,IAAIxD,KAAKwD,KAAK;gCAClDw8B,UAAUx8B;;2BAEf;;;gBAGXi8B,SAASvgC,UAAUwgC;gBACnB7tC,KAAKouC;;YAETpuC,KAAK4tC,WAAWA;;QAMpBD,aAAatuC,UAAUgvC,SAAS,SAAS1gC,QAAQ3Q;YAC7CA,UAAUA;YAEV,IAAI8E,OAAO9B,MACPsuC,WAAWtuC,KAAK4tC,SAAStD,cACzBiE,YAAYvuC,KAAK4tC,SAASpD,eAC1BE,QAAQ1tC,QAAQ0tC,OAChBtwB,SAASpd,QAAQod,QACjBsc,WAAW15B,QAAQ05B,UACnBD,YAAYz5B,QAAQy5B,WACpB4U,YAAYrrC,KAAK4M,QAAQ5M,KAAK4M,KAAK1L,SAAS,cAC5C0J,UAAU+C,OAAO/C,QAAQ9M,eACzB0wC;YAEJ,IAAIxuC,KAAKouC,oBAAoB;gBACzBpuC,KAAKouC,mBAAmBvuC,KAAK;oBAAaiC,KAAKusC,OAAO1gC,QAAQ3Q;;gBAC9D;;YAGJ,IAAI0tC,UAAUtwB,QAAQ;gBAClBA,SAAUm0B,YAAY7D,QAAQ4D,YAAa;mBACxC,IAAIl0B,WAAWswB,OAAO;gBACzBA,QAAS4D,WAAWl0B,SAASm0B,aAAc;mBACxC;gBACH7D,QAAQ4D;gBACRl0B,SAASm0B;;YAEb,IAAI7X,YAAYgU,QAAQhU,UAAU;gBAC9BgU,QAAQhU;gBACRtc,SAAUm0B,YAAY7D,QAAQ4D,YAAa;;YAE/C,IAAI7X,aAAarc,SAASqc,WAAW;gBACjCrc,SAASqc;gBACTiU,QAAS4D,WAAWl0B,SAASm0B,aAAc;;YAG/CC;gBAAQ9D,OAAOA;gBAAOtwB,QAAQA;eAC9Brc,GAAGY,KAAK3B,SAAS,SAASyxC,YAAYC;gBAClCF,IAAIC,cAAcC;;YAGtB,IAAI9jC,YAAY,OAAO;iBAClB;oBACG,IAAI+jC,eAAehhC,OAAOugC;oBAC1B9C,qBAAqBtpC,KAAK8rC,UAAU9rC,KAAK8K,MAAM4hC,KAAKnD,UAC/CrzB,KAAK,SAASrR;wBACXgH,OAAOugC,MAAMvnC;wBACbgoC,iBAAiBhhC,OAAOugC,OAAOvgC,OAAOR;;;mBAG/C,IAAIvC,YAAY,UAAU;gBAC7B0gC,oBAAoBtrC,KAAK4tC,UAAU5tC,KAAK4M,MAAMe,QAAQ6gC,KAAKnD;;YAE/D,WAAWrrC,KAAK4uC,aAAa,YAAY;gBACrC5uC,KAAK4uC,SAASjhC;;;QAItB5P,GAAG4vC,eAAeA;;ICtYtB5vC,GAAGk7B,iBAAiB,SAAS94B;QACzB;QAEA,SAAS0uC,MAAM3sC;YACX,OAAOA,GAAG0I,QAAQ9M,kBAAkB;;QAGxC,SAASgxC,SAAS5sC;YACd,OAAOA,GAAG0I,QAAQ9M,kBAAkB;;QAGxC,SAASixC;YACL,OAAO,IAAIjB,QAAQkB,gBAAgB3wC;;QAGvC,SAAS4wC;YACL,IAAI3oC,SAAS2E,SAASC,cAAc;YAEpC,OAAO5E,OAAOqkC,cAAcrkC,OAAOqkC,WAAW;;QAMlD,SAASuE,wBAAwBC;YAE7B,IAAIC,eAAeD,aAAaznC,MAAM,MAClC3I,OAAOqwC,aAAaA,aAAajtC,SAAS,GAAGuF,MAAM,KAAK,IACxD0nB,YAAYrxB,GAAG4U,aAAa5T;YAEhCqwB,YAAYA,aAAaA,UAAUtxB;YAEnC,QAAQsxB;cACJ,KAAK;cACL,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;cACL,KAAK;gBACD,OAAO;;;QASnB,SAASigB,cAAc3T;YACnB,IAAI4T,eAAerkC,SAASC,cAAc,MACtCqkC,gBAAgBC,gBAAgBC;YAEpCH,aAAaI,OAAOhU;YAEpB6T,iBAAiBD,aAAaK;YAC9BF,aAAaH,aAAaM;YAC1BJ,iBAAiBF,aAAaO;YAE9B,IAAIN,eAAezxC,kBAAkBkJ,OAAO8oC,SAASH,SAAS7xC,eAAe;gBACzE,OAAO;;YAGX,IAAI0xC,eAAe1xC,kBAAkBkJ,OAAO8oC,SAASD,SAAS/xC,eAAe;gBACzE,OAAO;;YAIX,IAAI2xC,eAAezoC,OAAO8oC,SAASF,SAAS7xC,GAAG2Q,MAAM;gBACjD,OAAO;;YAGX,OAAO;;QAGX,SAASqhC,yBAAyB3F,KAAKn9B;YACnCm9B,IAAIj9B,SAAS;gBACTi9B,IAAIj9B,SAAS;gBACbi9B,IAAI/8B,UAAU;gBACdJ,QAAQG,QAAQg9B;;YAGpBA,IAAI/8B,UAAU;gBACV+8B,IAAIj9B,SAAS;gBACbi9B,IAAI/8B,UAAU;gBACdlN,IAAI,8BAA8B;gBAClC8M,QAAQK,QAAQ88B,KAAK;;;QAI7B,SAAS4F,gCAAgC1pC,QAAQ2G;YAO7C3G,OAAO6mC,kBAAkB;gBACrBlgC,QAAQG,QAAQ9G;;;QAQxB,SAAS2pC,kCAAkCvuB,aAAazU;YACpD,IAAIijC,aAAarB,MAAMntB,gBAAgBotB,SAASptB;YAEhD,IAAImtB,MAAMntB,cAAc;gBACpBquB,yBAAyBruB,aAAazU;mBAErC,IAAI6hC,SAASptB,cAAc;gBAC5BsuB,gCAAgCtuB,aAAazU;mBAE5C;gBACDA,QAAQK,QAAQoU;gBAChBvhB,IAAIpC,GAAGyL,OAAO,kDAAkDkY,YAAY9W,UAAU;;YAG1F,OAAOslC;;QAKX,SAASC,KAAKjkC,YAAYkW,WAAWplB;YACjC,IAAIozC,cAAc,IAAIryC,GAAGmP,WACrBub,aAAa,IAAI1qB,GAAGsyC,SAASnkC,YAAY/L,MACzCwhB,UAAU3kB,QAAQ2kB,SAElBgX,SAAS37B,QAAQ27B,UAAU,OAAO,OAAO37B,QAAQ27B,QACjD2X,sBAAsB;gBAClBluB,UAAU/U,UAAU;gBACpB+U,UAAUjV,SAAS;gBACnBhN,IAAI,oDAAoD;gBACxDiwC,YAAY9iC,QAAQ8U,WAAW;;YAGvCqG,WAAW8nB,gBAAgBv4B,KACvB,SAASzR;gBAGL,IAAIiqC;oBACI/9B,OAAO;wBACH,OAAO,IAAI1U,GAAGmP,UAAUE;;mBAGhCqjC,OAAO9X,SAAS,IAAI56B,GAAG2yC,KAAKxkC,YAAY/L,OAAOqwC,WAC/CG,QAAQ,IAAI5yC,GAAG4vC,aAAazhC,YAAYokC;gBAE5C,IAAIL,kCAAkC7tB,WAAWguB,cAAc;oBAC3DK,KAAKh+B,QAAQuF,KACT,SAASy4B;wBACL,IAAIrE,cAAcqE,QAAQA,KAAKG;wBAE/BD,MAAMtC,OAAOjsB;4BACTsU,UAAU/U;4BACV8U,WAAW9U;4BACXyqB,aAAaA;4BACb7lC,MAAMA;4BACNylC,QAAQhvC,QAAQ6kB;;uBAIxB,SAASgvB;wBACL1wC,IAAIpC,GAAGyL,OAAO,kEAAkEqnC;wBAEhFF,MAAMtC,OAAOjsB;4BACTsU,UAAU/U;4BACV8U,WAAW9U;4BACXpb,MAAMA;4BACNylC,QAAQhvC,QAAQ6kB;;;;eAOpC;gBACI1hB,IAAI;gBACJiwC,YAAY9iC,QAAQ8U,WAAW;;YAIvC,OAAOguB;;QAGX,SAASU,yBAAyBpV,KAAKqV,aAAaZ,MAAMxuB,SAASE;YAC/D,IAAImvB,UAAU,IAAIlD,SACdmD,gBAAgB,IAAIlzC,GAAGmP;YAE3B+iC,kCAAkCe,SAASC;YAE3C,IAAI5B,cAAc3T,MAAM;gBACpBsV,QAAQhC,cAAc;;YAG1BgC,QAAQ9C,MAAMxS;YAEduV,cAAcj5B,KACV,SAASk5B;gBACLjB,kCAAkCc,aAAaZ;gBAE/C,IAAIQ,QAAQ,IAAI5yC,GAAG4vC,aAAaqD;gBAChCL,MAAMtC,OAAO0C;oBACTra,UAAU/U;oBACV8U,WAAW9U;oBACXpb,MAAM2oC,wBAAwBxT;oBAC9BsQ,QAAQnqB;;eAIhBsuB,KAAK7iC;;QAIb,SAAS6jC,+BAA+BzV,KAAK0O,KAAK+F,MAAMxuB;YACpDsuB,kCAAkC7F,KAAK+F;YAKvCpyC,GAAGqsC,KAAKrmC;gBACJ2yB,UAAU/U,UAAU;gBACpB8U,WAAW9U,UAAU;;YAGzByoB,IAAI8D,MAAMxS;;QAWd,SAAS0V,YAAY1V,KAAKtZ,WAAWplB;YACjC,IAAImzC,OAAO,IAAIpyC,GAAGmP,WACdgV,QAAQllB,QAAQklB,OAChBP,UAAUO,QAAQllB,QAAQ2kB,UAAU;YAGxC,IAAIO,SAAS2sB,MAAMzsB,YAAY;gBAG3B,IAAI6sB,qBAAqB;oBAIrB,IAAII,cAAc3T,SAASqT,sBAAsB;wBAC7CoC,+BAA+BzV,KAAKtZ,WAAW+tB,MAAMxuB;2BAEpD;wBACDmvB,yBAAyBpV,KAAKtZ,WAAW+tB,MAAMxuB;;uBAGlD;oBACDwvB,+BAA+BzV,KAAKtZ,WAAW+tB,MAAMxuB;;mBAIxD,IAAImtB,SAAS1sB,YAAY;gBAC1B0uB,yBAAyBpV,KAAKtZ,WAAW+tB,MAAMxuB;mBAG9C,IAAIsuB,kCAAkC7tB,WAAW+tB,OAAO;gBACzD/tB,UAAU8rB,MAAMxS;;YAGpB,OAAOyU;;QAGXpyC,GAAGuG,OAAOtE;YAWNqiB,UAAU,SAASgvB,eAAejvB,WAAWplB;gBACzC,IAAIe,GAAGmL,SAASmoC,gBAAgB;oBAC5BlxC,IAAI;oBACJ,OAAOixC,YAAYC,eAAejvB,WAAWplB;uBAE5C;oBACDmD,IAAI;oBACJ,OAAOgwC,KAAKkB,eAAejvB,WAAWplB;;;;QAMlDgD,KAAKsxC;QACLtxC,KAAKsxC,SAASzC,QAAQA;QACtB7uC,KAAKsxC,SAASxC,WAAWA;QACzB9uC,KAAKsxC,SAASjC,gBAAgBA;QAC9BrvC,KAAKsxC,SAASpC,0BAA0BA;;IChT5CnxC,GAAG2yC,OAAO,SAASxkC,YAAY/L;QAC3B;QAGA,IAAIoxC,YAAW,OACXC;YACIC;gBACI1yC,MAAM;gBACNyN,OAAO;;;QAKnB,SAASklC,kBAAkBC;YACvB,IAAIxsC,SAAS,GACTysC,MAAM;YAEV,OAAOD,IAAIxvC,SAAS,GAAG;gBACnBgD,UAAUi9B,SAASuP,IAAIzyC,UAAU,GAAG,IAAI,MAAMkF,KAAKwtC,IAAI,GAAGA;gBAC1DD,MAAMA,IAAIzyC,UAAU,GAAGyyC,IAAIxvC;gBAC3ByvC,OAAO;;YAGX,OAAOzsC;;QAKX,SAAS0sC,WAAWC,QAAQ7kC;YACxB,IAAI8kC,YAAYD,QACZE,aAAa/kC;YACjB,IAAI8kC,cAAc1zC,WAAW;gBACzB0zC,YAAY;gBACZC,aAAa,IAAIj0C,GAAGmP;;YAGxBnP,GAAG4O,cAAcT,YAAY6lC,WAAW,GAAG/5B,KAAK,SAAS25B;gBACrD,IAAIxwC,QAAQ,cAAclC,KAAK0yC,MAC3BM;gBAEJ,IAAI9wC,OAAO;oBACP,IAAIA,MAAM,OAAO,KAAK;wBAClB8wC,gBAAgB7P,SAASuP,IAAI9zC,MAAM,GAAG,IAAI;wBAC1Cg0C,WAAWE,YAAYE,gBAAgB,GAAGD;2BAEzC;wBACDA,WAAW5kC,QAAQ2kC;;uBAGtB;oBACDC,WAAW1kC,QAAQ;;;YAI3B,OAAO0kC;;QAIX,SAASE;YACL,IAAIjlC,UAAU,IAAIlP,GAAGmP;YAErBnP,GAAG4O,cAAcT,YAAY,GAAG,GAAG8L,KAAK,SAAS25B;gBAC7C,IAAIA,IAAIhqC,QAAQ,YAAY,GAAG;oBAC3BsF,QAAQK,QAAQ;uBAEf;oBACDukC,aAAa75B,KAAK,SAAS85B;wBACvB7kC,QAAQG,QAAQ0kC;uBAEpB,SAAS5xC;wBACL+M,QAAQK,QAAQpN;;;;YAK5B,OAAO+M;;QAIX,SAASklC,eAAeC;YACpB,IAAInlC,UAAU,IAAIlP,GAAGmP;YAErBnP,GAAG4O,cAAcT,YAAYkmC,YAAY,IAAI,GAAGp6B,KAAK,SAAS25B;gBAC1D1kC,QAAQG,QAAQukC,QAAQ;;YAG5B,OAAO1kC;;QAIX,SAASolC,iBAAiBD,WAAWE;YACjC,IAAIrlC,UAAU,IAAIlP,GAAGmP;YAErBnP,GAAG4O,cAAcT,YAAYkmC,YAAY,IAAI,GAAGp6B,KAAK,SAAS25B;gBAC1D,IAAIW,cAAc;oBACd,OAAOrlC,QAAQG,QAAQskC,kBAAkBC;uBAExC;oBACD1kC,QAAQG,QAAQg1B,SAASuP,KAAK;;;YAItC,OAAO1kC;;QAIX,SAASslC,OAAOH,WAAWI;YACvB,IAAIV,SAASM,YAAY,IACrB5lC,QAAQgmC,aAAa;YAEzB,OAAOz0C,GAAG4O,cAAcT,YAAY4lC,QAAQtlC;;QAIhD,SAASimC,cAAcC;YACnB,IAAIp3B,cACAw2B,SAAS;YAEb,OAAOA,SAAS,MAAMY,OAAOvwC,QAAQ;gBACjCmZ,QAAQzb,KAAK6yC,OAAO70C,MAAMi0C,QAAQA,SAAS;gBAC3CA,UAAU;;YAGd,OAAOx2B;;QAIX,SAASq3B,aAAaL,cAAcE;YAChC,IAAII,iBAAiB,IACjBC,aAAa90C,GAAGuG,WAAWitC,UAC3BuB;YAEJ/0C,GAAGY,KAAK6zC,YAAY,SAAS7yC,KAAK05B;gBAC9B,IAAI0Z,QAAQ1Z,MAAMx7B,MAAM,GAAG,IACvB0d,KAAK+2B,eAAeZ,kBAAkBqB,SAAS3Q,SAAS2Q,OAAO,KAC/DC,gBAAgBH,WAAWlrC,QAAQ4T,KACnC03B,WAAWroC,SAASsoC;gBAExB,IAAIF,iBAAiB,GAAG;oBACpBpoC,UAAU4mC,SAASj2B,IAAIxc;oBACvBm0C,eAAe1B,SAASj2B,IAAI/O;oBAC5BymC,YAAY5Z,MAAMx7B,MAAM+0C,gBAAgBA,iBAAkBM,eAAe;oBACzEJ,KAAKloC,WAAW0nC,eAAeZ,kBAAkBuB,aAAa7Q,SAAS6Q,WAAW;oBAElFJ,WAAW71B,OAAOg2B,eAAe;;gBAGrC,IAAIH,WAAW1wC,WAAW,GAAG;oBACzB,OAAO;;;YAIf,OAAO2wC;;QAGX/0C,GAAGuG,OAAOtE;YAONyS,OAAO;gBACH,IAAI0gC,SAAS,IAAIp1C,GAAGmP,WAChBkmC,iBAAiB,SAAShzC;oBACtBD,IAAIpC,GAAGyL,OAAO,mCAAmCpJ;oBACjD+yC,OAAO7lC,QAAQlN;;gBAGvB8xC,gBAAgBl6B,KAAK,SAASq7B;oBAC1BlzC,IAAIpC,GAAGyL,OAAO,oDAAoD0C,WAAWnN,SAASV,YAAY,SAAS6N,WAAWnN;oBAEtHozC,eAAekB,YAAYr7B,KAAK,SAASs6B;wBAErCnyC,IAAIpC,GAAGyL,OAAO,gCAAgC8oC,eAAe,WAAW;wBAExED,iBAAiBgB,YAAYf,cAAct6B,KAAK,SAASs7B;4BAErDnzC,IAAIpC,GAAGyL,OAAO,mCAAmC8pC;4BAEjDf,OAAOc,YAAYC,eAAet7B,KAAK,SAAS06B;gCAC5C,IAAIF,aAAaC,cAAcC,SAC3Ba,YAAYZ,aAAaL,cAAcE;gCAE3CryC,IAAI;gCAEJgzC,OAAO/lC,QAAQmmC;+BAChBH;2BACJA;uBACJA;mBACJA;gBAEH,OAAOD;;;QAKfnzC,KAAKsxC;QACLtxC,KAAKsxC,SAASI,oBAAoBA;;IC7MtC3zC,GAAGsyC,WAAW,SAASnkC,YAAY/L;QAC/B;QAEA,SAASqzC,eAAeC,YAAYC;YAChC,IAAIC,eAAe,OACfC,uBAAuB1iC,OAAOuiC;YAElC11C,GAAGY,KAAKi1C,mBAAmB,SAASj0C,KAAKk0C;gBACrC,IAAIH,kBAAkB/rC,QAAQksC,0BAA0B,GAAG;oBACvDF,eAAe;oBACf,OAAO;;;YAIf,OAAOA;;QAGX51C,GAAGuG,OAAOtE;YASNuwC,eAAe;gBACX,IAAIzuC,OAAO9B,MACPyoB,aAAa,IAAI1qB,GAAGmP,WACpB4mC,cAAc,OACd/0C,OAAOmN,WAAWnN,SAASV,YAAY,SAAS6N,WAAWnN;gBAE/DoB,IAAIpC,GAAGyL,OAAO,iEAAiEzK;gBAE/EoB,IAAI;gBAEJ,IAAIH,KAAK+zC,qBAAqB;oBAC1B5zC,IAAI;oBAEJpC,GAAG4O,cAAcT,YAAY,GAAG,GAAG8L,KAAK,SAAS25B;wBAC7C5zC,GAAGY,KAAKmD,KAAKkyC,wBAAwB,SAASztC,MAAMiG;4BAChD,IAAIgnC,eAAehnC,OAAOmlC,MAAM;gCAG5B,IAAIprC,SAAS,gBAAgBxI,GAAGgW,kBAAkBwD,cAAc;oCAC5Du8B,cAAc;oCACdrrB,WAAWrb,QAAQ7G;;gCAGvB,OAAO;;;wBAIfpG,IAAIpC,GAAGyL,OAAO,kDAAkDzK,MAAM+0C,cAAc,KAAK;wBAEzF,KAAKA,aAAa;4BACdrrB,WAAWnb;;uBAGnB;wBACInN,IAAI,iCAAiCpB,OAAO;wBAC5C0pB,WAAWnb;;uBAGd;oBACDmb,WAAWnb;;gBAGf,OAAOmb;;YAWXsrB,mBAAmB;gBACf,IAAIE,WAAW/nC,WAAWhL,MAEtBgzC,oBAAoBn2C,GAAG4J,QAAQW,OAAO23B,KAAKjgC,KAAKg0C,yBAAyBC,aAAa,GACtFH,cAAc,OACd/0C,OAAOmN,WAAWnN,SAASV,YAAY,SAAS6N,WAAWnN;gBAE/D,IAAIm1C,mBAAmB;oBACnB,IAAID,aAAa,cAAc;wBAC3BH,cAAc/1C,GAAGgW,kBAAkBwD;2BAElC;wBACDu8B,cAAc;;;iBAIrBA,eAAe3zC,IAAIpB,OAAO;gBAE3B,OAAO+0C;;;;IAKnB/1C,GAAGsyC,SAAShxC,UAAU20C;QAClBG,cAAc;QACdC,aAAa;QACbC,aAAa;QACbC,aAAa;QACbC,gBAAe,YAAY;;ICpG/Bx2C,GAAG03B,kBAAkB,SAAS7oB,MAAMzM;QAChC;QAMA,SAASq0C,iBAAiBC;YACtB,IAAIC,aAAa;YAEjB32C,GAAGY,KAAK81C,QAAQ,SAASE,OAAOlsC;gBAC5B,IAAIA,QAAQ,GAAG;oBACXisC,aAAa;oBACb,OAAO;;;YAIf,OAAOA;;QAQX,SAASE;YACL,IAAIC,oBAAoB,IAAI92C,GAAGmP;YAE/B,IAAInP,GAAGsyC,SAASzjC,MAAMzM,KAAKowC,gBAAgBv4B,KAAK;gBAC5C,IAAI2d,QAAQ,IAAImY,SACZpS,MAAM10B,OAAO+mC,OAAO/mC,OAAO+mC,IAAIC,kBAAkBhnC,OAAO+mC,MAClD/mC,OAAOinC,aAAajnC,OAAOinC,UAAUD,kBAAkBhnC,OAAOinC,YAC9D;gBAEV,IAAIvS,KAAK;oBACL/F,MAAMtoB,UAAU;wBACZlN,IAAI,6DAA6D;wBACjE00C,kBAAkBvnC;;oBAGtBqoB,MAAMxoB,SAAS;wBACX0nC,kBAAkBznC;4BACds9B,OAAO1qC,KAAK0qC;4BACZtwB,QAAQpa,KAAKoa;;;oBAIrBub,MAAMuY,MAAMxS,IAAIsS,gBAAgBphC;uBAE/B;oBACDzM,IAAI,gEAAgE;oBACpE00C,kBAAkBvnC;;eAEvBunC,kBAAkBvnC;YAErB,OAAOunC;;QASX,SAASC,gBAAgBL,QAAQM;YAC7B,IAAIC;YAEJj3C,GAAGY,KAAK81C,QAAQ,SAASQ,WAAWC;gBAChC,IAAIA,aAAa,GAAG;oBAChB,IAAIC,eAAe,0BAA0Bl2C,KAAKg2C,YAC9CG,oBAAoBD,aAAa,GAAGx3C,OAAO,GAAGG,gBAAgBq3C,aAAa,GAAGt3C,MAAM,IACpFw3C,cAAcN,WAAWK;oBAG7B,QAAQD,aAAa;sBACjB,KAAK;wBACD,IAAIE,cAAcH,YAAY;4BAC1BF,eAAeC;4BACf,OAAO;;wBAEX;;sBACJ,KAAK;wBACD,IAAII,cAAcH,YAAY;4BAC1BF,eAAeC;4BACf,OAAO;;wBAEX;;;;YAKhB,OAAOD;;QAWXh1C,KAAK01B,WAAW,SAAS+e;YACrB,IAAIa,mBAAmB,IAAIv3C,GAAGmP;YAE9B/M,IAAI;YAEJ,IAAIq0C,iBAAiBC,SAAS;gBAC1BG,iBAAiB58B,KAAK,SAAS+8B;oBAC3B,IAAIC,eAAeF,gBAAgBL,QAAQM;oBAE3C,IAAIC,cAAc;wBACdM,iBAAiBhoC,QAAQ0nC;2BAExB;wBACDM,iBAAiBloC;;mBAEtBkoC,iBAAiBloC;mBAEnB;gBACDkoC,iBAAiBloC;;YAGrB,OAAOkoC;;;IC7Hfv3C,GAAG22B,UAAU,SAASvY;QAClB;QAEA,IAAInf;YACA4hB,UAAU;YACVrhB;YACAgqB;YACAG;YACAkN,eAAe,SAAStO;YACxBnmB,KAAK,SAASC,SAAS8H;;QAG3BnK,GAAGuG,OAAOtH,SAASmf,MAAM;QAEzB,SAASo5B,oBAAoB/jB;YACzB,IAAIzzB,GAAG6C,QAAQ4wB,WAAW;gBACtB,OAAO;;YAGXx0B,QAAQmD,IAAI,qCAAqC;;QAGrD,SAASq1C,gBAAgBC,WAAWroC,SAAS0a,UAAU7a;YACnD,IAAIyoC,mBAAmB;YAEvBtoC,UAAUA,WAAWmoC,oBAAoBE;YAEzC,IAAIroC,SAAS;gBACTrP,GAAGY,KAAK82C,WAAW,SAAS91C,KAAKu+B;oBAE7B,IAAIA,SAASxiB,QAAQ,MAAM;wBACvBg6B,mBAAmB;wBACnB14C,QAAQmD,IAAIpC,GAAGyL,OAAO,qEAAqE7J,MAAM;2BAEhG,IAAIu+B,SAASn/B,QAAQ,MAAM;wBAC5B22C,mBAAmB;wBACnB14C,QAAQmD,IAAIpC,GAAGyL,OAAO,qEAAqE7J,MAAM;2BAEhG;wBACD;4BACI3C,QAAQ43B,cAAcsJ;4BACtB,OAAO;0BAEX,OAAOyX;4BACHD,mBAAmB;4BACnB14C,QAAQmD,IAAIw1C,IAAIv1C,SAAS;;;oBAIjC,OAAO;;;YAIf6M,QAAQG,YAAYsoC,mBAAmB,YAAY,WAAWD,WAAW3tB;;QAK7E9nB,KAAK60B,UAAU;YAEX,IAAI+gB,gBAAgB,IAAI73C,GAAGmP,WACvB2oC,0BAA0B,SAASrkB,UAAUpkB,SAAS0a;gBAClD0tB,gBAAgBhkB,UAAUpkB,SAAS0a,UAAU8tB;eAEjDE,mBAAmB/3C,GAAGuG,WAAWtH,UACjCgtC,YAAY,IAAIjsC,GAAGg4C,qBACfh4C,GAAGuG,OAAOwxC;gBAAmBzqB,YAAYwqB;;YAGjD7L,UAAUgM;YAEV,OAAOJ;;;ICrEf73C,GAAGg4C,uBAAuB,SAAS55B;QAC/B;QAEA,IAAI6tB,WACAhtC;YACI4hB,UAAU;YACV2I;YACAhqB;YACAmqB;gBACIoI,UAAU;gBACVyI,iBAAiB;;YAErBlN,YAAY,SAASmG,UAAUpkB,SAAS0a;YACxC3nB,KAAK,SAASsJ,KAAKvB;;QAG3BnK,GAAGuG,OAAOtH,SAASmf;QAEnB,SAASkP,WAAW9P,IAAIuM,UAAUC;YAC9B,IAAIyJ,WAAW;YAGf,IAAI1J,SAASmuB,gBAAgB,MAAM;gBAC/B;oBACIzkB,WAAWzzB,GAAGuU,UAAUwV,SAASmuB;kBAErC,OAAON;oBACH34C,QAAQmD,IAAI,uCAAuCw1C,IAAIv1C,SAAS;oBAChE2nB,UAAU;;;YAIlB/qB,QAAQquB,WAAWmG,WAAWzJ,SAASD;;QAG3CkiB,YAAYjsC,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7B;YAC/BI,cAAc;YACdC,gBAAe;YACfzS,QAAQ;YACRO;gBACI5E,KAAK;oBACD,OAAO7lB,QAAQ4hB;;;YAGvB2I,eAAevqB,QAAQuqB;YACvBpnB,KAAKnD,QAAQmD;YACbkrB,YAAYA;YACZ3D,MAAM1qB,QAAQ0qB;;QAGlB3pB,GAAGuG,OAAOtE;YACNg2C,aAAa;gBACT,IAAIz4C,SAASQ,GAAGuG,WAAWtH,QAAQO;gBAEnCP,QAAQmD,IAAI;gBAEZ6pC,UAAUjN,cAAc,kBACnBK,WAAW7/B,QACXmgC,kBACAtB;;;;ICzDjBr+B,GAAG+mB,SAAS,SAAS3I,MAAMhc;QACvB;QAEA,IAAI2B,OAAO9B,MACP6hB,uBAAuB1F,KAAKsc,eAC5Byd,kBAAkB/5B,KAAKuc,cACvBC,SAASxc,KAAKwc,QACdC,cAAczc,KAAKyc,aACnBC,iBAAiB1c,KAAK0c,iBAAiB,KACvCsd,oBAAoBh6B,KAAK2c,aACzBC,cAAc5c,KAAK4c,aACnBC,QAAQh5B,KAAKo2C,gBAAgBj6B,KAAK6c;QAGtCj7B,GAAGuG,OAAOtE;YAGNghB,SAASjjB,GAAGgW,kBAAkBuD,WAAW0hB,MAAM72B,SAAS;YAExDk0C,gBAAgB,SAASC,kBAAkBC,kBAAkBC;gBACzD,IAAI10C,OAAO9B,MACPy2C,cACAC,eAAeF,uBAAuB5pC,OAAO4pC,uBAAuB5pC,OAAO4pC,wBAC3E/tB,aAAa,IAAI1qB,GAAGsyC,SAASqG,cAAcv2C;gBAG/C,IAAIsoB,WAAWsrB,qBAAqB;oBAEhCh2C,GAAGY,KAAKq6B,OAAO,SAASr5B,KAAKg3C;wBACzB,IAAIC,aAAa90C,KAAK+0C;4BAClBje,aAAaA;4BACbke,eAAeH,WAAWz1C;4BAC1B61C,SAASL,aAAax1C;;wBAG1Bu1C,QAAQ52C;4BACJ6b,MAAM3d,GAAGsQ;4BACTtP,MAAM+C,KAAKk1C,SAAST;gCAChBx3C,MAAM43C,WAAW53C;gCACjBmC,MAAM01C;gCACNG,SAASL,aAAax1C;;4BAE1B0L,MAAM,IAAI7O,GAAG2a,UAAUg+B,cACvB34C,GAAG+S,KAAKhP,KAAKm1C,sBAAsBn1C;gCAC/B+f,sBAAsBA;gCACtBF,SAASg1B,WAAWh1B;gCACpBgX,QAAQA;gCACRz3B,MAAM01C;gCACNpwC,SAASqyB;gCACTqe,YAAYf;gCACZpd,aAAaA;gCACb54B,KAAKA;;;;oBAKjBs2C,QAAQ52C;wBACJ6b,MAAM46B;wBACNv3C,MAAMw3C;wBACNj6B,MAAMo6B,aAAap6B;wBACnB1P,MAAMspC,kBAAkBQ,eAAe;;uBAG1C;oBACDD,QAAQ52C;wBACJ6b,MAAM46B;wBACNv3C,MAAMw3C;wBACNj6B,MAAMo6B,aAAap6B;wBACnB1P,MAAM8pC;;;gBAId,OAAOD;;YAGXtd,eAAe,SAAShZ,MAAMphB,MAAM2c,MAAMY,MAAM4S,UAAU3S,SAAS6K,eAAe+vB;gBAC9E,IAAIr1C,OAAO9B,MACPwZ,WAAW2G,KAAKyG,cAAezG,KAAKvT,QAAQuT,KAAKvT,KAAKga,YACtDwwB,gBACAC,aAAa,MACbroB,mBAAmBmoB,IAAInoB,kBACvBlO,aAAaq2B,IAAIr2B,YACjB0G,cAAc2vB,IAAI3vB,aAClBhL,eAAeze,GAAGsQ;gBAEtBtQ,GAAGY,KAAKmD,KAAKu0C,eAAe36B,MAAM3c,MAAMohB,OAAO,SAASxgB,KAAK23C;oBACzD,IAAIC,WAAWD,OAAOh7B,MAClBf;oBAEJ,IAAI+7B,OAAO1qC,gBAAgB7O,GAAG2a,WAAW;wBACrC6+B,YAAY;;oBAGhBh8B,KAAKuF,WAAW5E;wBACZR,MAAM47B,OAAO57B;wBACb3c,MAAMu4C,OAAOv4C;wBACbud,MAAMi7B;wBACNh7B,SAASA;wBACTC,cAAcA;;oBAGlB,IAAI86B,OAAO1qC,gBAAgB7O,GAAG2a,WAAW;wBACrC0+B,UAAUv3C,KAAK0b;2BAEd;wBACD87B,aAAa97B;;oBAGjB,IAAI+7B,OAAO1qC,MAAM;wBACboiB,iBAAiBzT,IAAI+7B,OAAO1qC;wBAC5BsiB,SAASrvB;4BAAM0b,IAAIA;4BAAI4E,MAAMm3B,OAAO1qC;;2BAEnC;wBACDkU,WAAWlE,UAAUrB,IAAIxd,GAAG6d,OAAOkC;;;gBAO3C,IAAIu5B,eAAe,MAAM;oBACrBt5C,GAAGY,KAAKy4C,WAAW,SAASz3C,KAAK63C;wBAC7B,IAAIj6C;4BACAk6C,cAAc32B,WAAWpE;gCAAUnB,IAAI87B;+BAAa37B;4BACpDg8B,cAAc52B,WAAWpE;gCAAUnB,IAAI87B;+BAAa/6B;;wBAKxD/e,OAAO6pB,iBAAiBtG,WAAWpE;4BAAUnB,IAAIi8B;2BAAW97B;wBAE5DoF,WAAWtD,YAAYg6B,UAAUH;wBACjC7vB,YAAY+B,YAAYiuB,UAAUj6C;;oBAKtC,IAAI65C,UAAUj1C,QAAQ;yBACjB;4BACG,IAAIw1C;4BACJA,MAAMvwB,iBAAiBtG,WAAWpE;gCAAUnB,IAAI87B;+BAAa37B;4BAC7D8L,YAAY+B,YAAY8tB,YAAYM;;;;;;;IAQ5D55C,GAAGuG,OAAOvG,GAAG+mB,OAAOzlB;QAChBulB,YAAY,SAASrJ,IAAIsJ,OAAOsyB;YAC5B;YAEA,KAAKp5C,GAAGgW,kBAAkBuD,SAAS;gBAC/B,MAAM,IAAIvZ,GAAGkG,MAAM;;YAGvB,IAAI2zC,gBAAgB,IAAI75C,GAAGmP,WACvB/M,MAAMg3C,IAAIh3C,KACVggB,OAAOg3B,IAAIh1B,QAAQ5G,KACnBuF,aAAaq2B,IAAIr2B,WAAWpE;gBAAUnB,IAAIA;gBAC1Cxc,OAAO+hB,cAAcA,WAAW/hB,MAChC2c,OAAOoF,cAAcA,WAAWpF,MAChCm8B;gBACIpf,eAAe5T,MAAM4T;gBACrBC,cAAc;gBACdC,QAAQ9T,MAAM8T;gBACdC,aAAa/T,MAAM3jB,QAAQ;gBAC3B23B,gBAAgBhU,MAAMre;gBACtB2vC,mBAAmB;gBACnBnd;oBAASj6B,MAAM;oBAAI4iB,SAASkD,MAAMlD;;eAEtCm2B,SAAS,IAAI/5C,GAAG+mB,OAAO+yB,gBAAgB13C;YAE3C,KAAKpC,GAAG+mB,WAAW/mB,GAAGgW,kBAAkBiD,kBAAkBmJ,MAAM;gBAC5Dy3B,cAActqC;gBAEdnN,IAAI,mDAAmDob,KAAK,QACxD,qFAAqF;mBAExF;gBACAxd,GAAG+S,KAAK;oBAEL,IAAIwmC,SAASQ,OAAOzB,eAAe36B,MAAM3c,MAAMohB,MAAM;oBAErD,IAAIm3B,UAAUA,OAAO1qC,gBAAgB7O,GAAG2a,WAAW;wBAC/C4+B,OAAO1qC,KAAKiM,SAASb,KAAK4/B,cAAcxqC,SAASwqC,cAActqC;2BAE9D;wBACDnN,IAAIob,KAAK,6BAA6B;wBACtCq8B,cAActqC;;mBAEnBtN;;YAGP,OAAO43C;;QAKXf,sBAAsB,SAAS16B;YAC3B;YAEA,IAAI26B,gBAAgB36B,KAAK26B,eACrBle,cAAczc,KAAKyc,aACnBmf,gBAAgB57B,KAAK46B;YAIzB,KAAKne,gBAAgBke,eAAe;gBAChC,IAAIiB,kBAAkB,cAAc;oBAChC,OAAO;;gBAEX,OAAOA;;YAIX,KAAKjB,eAAe;gBAChB,OAAOle;;YAIX,IAAI76B,GAAG4J,QAAQW,OAAO23B,KAAKliC,GAAGsyC,SAAShxC,UAAU20C,yBAAyB8C,kBAAkB,GAAG;gBAC3F,IAAIA,kBAAkB,cAAc;oBAChC,OAAO/4C,GAAGgW,kBAAkBwD,eAAeu/B,gBAAgBle;;gBAG/D,OAAOke;;YAGX,OAAOle;;QAIXoe,UAAU,SAAS36B,cAAc27B;YAC7B;YAEA,IAAIC,aAAa57B,aAAavJ,YAAY,MACtColC,cAAcF,wBAAwB92C,QAAQ,aAC9C62C,gBAAgBC,wBAAwBjB,SACxCoB,aAAa,IACbC,YAAYr6C,GAAG4U,aAAa0J,eAC5Bg8B,gBAAgB;YAEpB,IAAIL,wBAAwBj5C,QAAQi5C,wBAAwBj5C,KAAKwK,OAAOpH,QAAQ;gBAC5Ek2C,gBAAgB,OAAOL,wBAAwBj5C,OAAO;;YAG1D,IAAIk5C,cAAc,GAAG;gBACjBE,aAAa97B,aAAatJ,OAAO,GAAGklC;gBAEpC,IAAIF,kBAAkBG,aAAa;oBAC/BE,YAAYF,YAAYxwC,MAAM,KAAK;;gBAGvCywC,cAAcE,gBAAgB,MAAMD;mBAEnC;gBACDD,aAAa97B,eAAeg8B;;YAGhC,OAAOF;;QAIX/B,iBAAiB,SAASpd;YACtB;YAEAA,QAAQj7B,GAAGuG,WAAW00B;YAEtB,OAAOA,MAAMsf,KAAK,SAASC,GAAGC;gBAC1B,IAAID,EAAE52B,UAAU62B,EAAE72B,SAAS;oBACvB,OAAO;;gBAEX,IAAI42B,EAAE52B,UAAU62B,EAAE72B,SAAS;oBACvB,QAAQ;;gBAEZ,OAAO;;;QAIfs1B,sBAAsB,SAAS96B,MAAMs8B;YACjC;YAEA,IAAI32C,OAAO9B,MACP6hB,uBAAuB1F,KAAK0F,sBAC5B1hB,MAAMgc,KAAKhc,KACXwhB,UAAUxF,KAAKwF,SACfgX,SAASxc,KAAKwc,QACdz3B,OAAOib,KAAKjb,MACZsF,UAAU2V,KAAK3V,SACf0wC,aAAa/6B,KAAK+6B,YAClBne,cAAc5c,KAAK4c,eAAe0f,WAAWv3C,SAAS,gBAAgBA,SAAS,cAC/E02C,gBAAgB,IAAI75C,GAAGmP,WACvBwrC,iBAAiB,IAAI36C,GAAGk7B,eAAe94B,MACvCmG,SAAS2E,SAASC,cAAc;YAEpC/K,IAAI,+CAA+Cs4C,WAAW15C;YAE9D25C,eAAer2B,SAASo2B,YAAYnyC;gBAASqb,SAASA;gBAASgX,QAAQA;gBAAQ9W,sBAAsBA;eAAuB7J,KAAK;gBAC7H,IAAI2gC,qBAAqBryC,OAAOI,UAAUxF,MAAMsF,UAC5CoyC,gBAAgB;oBACZz4C,IAAI,2CAA2Cs4C,WAAW15C;oBAC1D,IAAI6N,OAAO7O,GAAG0I,cAAckyC;oBAC5Bf,cAAcxqC,QAAQR;;gBAG9B,IAAImsB,aAAa;oBACbj3B,KAAK+2C,kBAAkBJ,YAAYE,oBAAoBx4C,KAAK6X,KAAK,SAAS8gC;wBACtEH,qBAAqBG;wBACrBF;uBAEJ;wBACIz4C,IAAI,yFAAyF;wBAC7Fy4C;;uBAGH;oBACDA;;eAEL;gBACCz4C,IAAI,mDAAmDs4C,WAAW15C,MAAM;gBACxE64C,cAActqC,QAAQ4pC;;YAG1B,OAAOU;;QAIXiB,mBAAmB,SAASE,eAAeJ,oBAAoBx4C;YAC3D;YAEA,IAAI64C,SAAS,IAAIhsC,cACbisC,kBAAkB,IAAIl7C,GAAGmP,WACzBgsC,uBAAuB;YAE3BF,OAAO7rC,SAAS;gBACZ+rC,uBAAuBF,OAAO7zC;gBAC9B8zC,gBAAgB7rC,QAAQrP,GAAGo7C,aAAajM,QAAQgM,sBAAsBP;;YAG1EK,OAAO3rC,UAAU;gBACblN,IAAI,qBAAqB44C,cAAch6C,OAAO,4DAA4D;gBAC1Gk6C,gBAAgB3rC;;YAGpB0rC,OAAOI,cAAcL;YAErB,OAAOE;;QAGXI,gBAAgB,SAAS1yC;YACrB;YAEA,IAAIE,YAAYY,YAAYb,aAAaY;YAGzC,IAAIb,QAAQe,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cd,aAAae,KAAKjB,QAAQe,MAAM,KAAK;mBAEpC;gBACDb,aAAagB,UAAUlB,QAAQe,MAAM,KAAK;;YAI9CD,aAAad,QAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBd,cAAc,IAAIkB,YAAYjB,WAAW1E;YACzCqF,WAAW,IAAIO,WAAWnB;YAC1B7I,GAAGY,KAAKkI,YAAY,SAASlH,KAAKqI;gBAC9BR,SAAS7H,OAAOqI,UAAUC,WAAW;;YAGzC,OAAOjI,KAAKs5C,YAAY1yC,aAAaa;;QAGzC6xC,aAAa,SAASl7C,MAAMmI;YACxB;YAEA,IAAIQ,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;YAErC,IAAIK,aAAa;gBACbA,YAAYC,OAAOjJ;gBACnB,OAAOgJ,YAAYE,QAAQf;mBAE1B;gBACD,OAAO,IAAIgB,OAAMnJ;oBAAQ8C,MAAMqF;;;;;IChZ3CxI,GAAGo7C,eAAe;QAGjB,IAAIA;QAEDA,aAAaI,UAAU,qBACF,qBACA,qBACA,qBACA;QAErBJ,aAAaK,WAAW,SAASxuC;YAE7B,IAAIyuC,SAAS,IACTC,MAAMC,MAAMC,OAAO,IACnBC,MAAMC,MAAMC,MAAMC,OAAO,IACzBroC,IAAI;YAER,GAAG;gBACC+nC,OAAO1uC,MAAM2G;gBACbgoC,OAAO3uC,MAAM2G;gBACbioC,OAAO5uC,MAAM2G;gBAEbkoC,OAAOH,QAAQ;gBACfI,QAASJ,OAAO,MAAM,IAAMC,QAAQ;gBACpCI,QAASJ,OAAO,OAAO,IAAMC,QAAQ;gBACrCI,OAAOJ,OAAO;gBAEd,IAAIK,MAAMN,OAAO;oBACdI,OAAOC,OAAO;uBACV,IAAIC,MAAML,OAAO;oBACrBI,OAAO;;gBAGVP,SAASA,SACNz5C,KAAKu5C,QAAQ57C,OAAOk8C,QACpB75C,KAAKu5C,QAAQ57C,OAAOm8C,QACpB95C,KAAKu5C,QAAQ57C,OAAOo8C,QACpB/5C,KAAKu5C,QAAQ57C,OAAOq8C;gBACvBN,OAAOC,OAAOC,OAAO;gBACrBC,OAAOC,OAAOC,OAAOC,OAAO;qBACvBroC,IAAI3G,MAAM7I;YAEnB,OAAOs3C;;QAGXN,aAAajM,UAAU,SAASgN,gBAAgBC;YAE5C,IAAIC,uBAAuB;YAE3B,KAAKF,eAAe/4C,MAAMi5C,uBAC1B;gBACC,OAAOD;;YAGR,IAAIE,WAAWr6C,KAAKs6C,SAASJ,eAAen1C,QAAQq1C,sBAAsB;YAC1E,IAAIG,WAAWv6C,KAAKw6C,eAAeH;YAEnC,IAAI1kB,QAAQ31B,KAAKy6C,iBAAiBN,mBAAmBI;YAErD,OAAOH,uBAAuBp6C,KAAKw5C,SAAS7jB;;QAKhDwjB,aAAasB,mBAAmB,SAASN,mBAAmBI;YAEpD,IAAIG,YAAY16C,KAAK26C,aAAaJ,WAC9BK,gBAAgB56C,KAAK66C,WAAWV,mBAAmBO,YACnDI,UAAU,IAAI/yC,WAAW6yC;YAE7B,OAAOE;;QAIf3B,aAAawB,eAAe,SAASJ;YAE7B,IAAIQ;YACJ,KAAK,IAAIC,IAAI,GAAGA,IAAIT,SAASp4C,QAAQ64C,KACrC;gBACID,MAAMR,SAASS;gBACf,IAAID,IAAI,MAAM,MAAMA,IAAI,MAAM,KAC9B;oBACI,OAAOA;;;YAGf;;QAIR5B,aAAa0B,aAAa,SAASV,mBAAmBO;YAE9C,IAAIO,YAAYd,kBAAkBp1C,QAAQ,2BAA2B,KACjEm2C,MAAMl7C,KAAKs6C,SAASW,YACpBE,gBAAgBD,IAAIvzC,QAAQ,KAAI,IAChCyzC,MAAMF,IAAIr9C,MAAM,GAAGs9C,gBACnBE,MAAMH,IAAIr9C,MAAMs9C,gBAChBG,QAAQF;YAEZE,QAAQA,MAAMpqC,OAAOwpC;YACrBY,QAAQA,MAAMpqC,OAAOmqC;YACtB,OAAOC;;QAKdnC,aAAaqB,iBAAiB,SAASe;YAEnC,IAAIC,OAAO,GACPjB;YAEJ,OAAO,GACP;gBACI,IAAIgB,cAAcC,SAAS,MAAMD,cAAcC,OAAO,MAAM,KAAI;oBAAC;;gBACjE,IAAID,cAAcC,SAAS,MAAMD,cAAcC,OAAO,MAAM,KAC5D;oBACIA,QAAQ;uBAGZ;oBACI,IAAIr5C,SAASo5C,cAAcC,OAAO,KAAK,MAAMD,cAAcC,OAAO,IAC9DC,WAAWD,OAAOr5C,SAAS,GAC3B44C,MAAMQ,cAAc19C,MAAM29C,MAAMC;oBACpClB,SAAS16C,KAAKk7C;oBACdS,OAAOC;;gBAEX,IAAID,OAAOD,cAAcp5C,QAAO;oBAAC;;;YAGrC,OAAOo4C;;QAKXpB,aAAamB,WAAW,SAAStvC;YAE7B,IAAIyuC,SAAS,IACTC,MAAMC,MAAMC,OAAO,IACnBC,MAAMC,MAAMC,MAAMC,OAAO,IACzBroC,IAAI,GACJupC;YAGJ,IAAIQ,aAAa;YACjB,IAAIA,WAAWz8C,KAAK+L,QAAQ;gBACxB,MAAM,IAAI/G,MAAM,8DACZ;;YAER+G,QAAQA,MAAMjG,QAAQ,uBAAuB;YAE7C,GAAG;gBACC80C,OAAO75C,KAAKu5C,QAAQ5xC,QAAQqD,MAAMrN,OAAOgU;gBACzCmoC,OAAO95C,KAAKu5C,QAAQ5xC,QAAQqD,MAAMrN,OAAOgU;gBACzCooC,OAAO/5C,KAAKu5C,QAAQ5xC,QAAQqD,MAAMrN,OAAOgU;gBACzCqoC,OAAOh6C,KAAKu5C,QAAQ5xC,QAAQqD,MAAMrN,OAAOgU;gBAEzC+nC,OAAQG,QAAQ,IAAMC,QAAQ;gBAC9BH,QAASG,OAAO,OAAO,IAAMC,QAAQ;gBACrCH,QAASG,OAAO,MAAM,IAAKC;gBAE3BkB,IAAIr7C,KAAK65C;gBAET,IAAIK,QAAQ,IAAI;oBACbmB,IAAIr7C,KAAK85C;;gBAEZ,IAAIK,QAAQ,IAAI;oBACbkB,IAAIr7C,KAAK+5C;;gBAGZF,OAAOC,OAAOC,OAAO;gBACrBC,OAAOC,OAAOC,OAAOC,OAAO;qBAEvBroC,IAAI3G,MAAM7I;YAEnB,OAAO+4C;;QAIX,OAAO/B;;IC7KXp7C,GAAGq7B,gBAAgB,SAAS1oB,UAAUyS;QAClC;QAEA,IAAIw4B,sBACAC,cAAc,GACdC,YAAY,GAEZC,kBAAkB,GAClBC,iBAAiB,GACjBC,gBAAgB,SAAS9wB,QAAQC;YAC7B,IAAID,WAAW4wB,kBAAkB3wB,UAAU4wB,eAAe;gBACtDrrC,SAASwa,QAAQC;;YAGrB2wB,iBAAiB5wB;YACjB6wB,gBAAgB5wB;WAQpB8wB,mBAAmB,SAAS9pB,QAAQ+pB;YAChC,IAAIC,OAAO;YAEXp+C,GAAGY,KAAKwzB,QAAQ,SAASxyB,KAAKy8C;gBAC1B,IAAIr+C,GAAG4J,QAAQu0C,WAAWE,aAAa,GAAG;oBACtCD,OAAO;oBACP,OAAO;;;YAIf,OAAOA;WAGX5wB,WAAW,SAAShQ;YAChB8gC,oBAAoB9gC,KAAK,IAAI;mBACtBogC,gBAAgBpgC;WAG3B6W,gBAAgB,SAASF,YAAYC,QAAQ+pB;YACzC,IAAI/pB,OAAOhwB,WAAW,KAAK85C,iBAAiB9pB,QAAQ+pB,YAAY;gBAC5DF,cAAcH,WAAWA;gBACzB77C,KAAK6a;;WAIbyhC,QAAQ,SAAS/gC;YACb,IAAIe,OAAO6G,QAAQ5H;YAGnB,IAAIe,OAAO,GAAG;gBACV+/B,oBAAoB9gC,IAAI,GAAGe;gBAC3Bq/B,gBAAgBpgC;oBAAO2P,QAAQ;oBAAGC,OAAO7O;;;WAYjD+/B,sBAAsB,SAAS9gC,IAAIghC,WAAWC;YAC1C,IAAIC,YAAYd,gBAAgBpgC,MAAMogC,gBAAgBpgC,IAAI2P,SAAS,GAC/DwxB,WAAWf,gBAAgBpgC,MAAMogC,gBAAgBpgC,IAAI4P,QAAQ;YAEjE,IAAIoxB,eAAe,KAAKC,cAAc,GAAG;gBACrCZ,eAAea;gBACfZ,aAAaa;mBAEZ;gBACD,IAAIH,WAAW;oBACXX,eAAeW,YAAYE;;gBAE/B,IAAID,UAAU;oBACVX,aAAaW,WAAWE;;;YAIhCV,cAAcJ,aAAaC;;QAGnC99C,GAAGuG,OAAOtE;YAENoyB,eAAeA;YAGf3V,gBAAgB,SAASlB,IAAIuB,WAAWD;gBACpC,IAAIA,cAAc9e,GAAG6d,OAAOoC,YAAYnB,cAAc9e,GAAG6d,OAAOkC,UAAU;oBACtEyN,SAAShQ;uBAER,IAAIsB,cAAc9e,GAAG6d,OAAOQ,YAAY;oBACzCkgC,MAAM/gC;;;YAKdwX,sBAAsB,SAASxX,IAAI2P,QAAQC;gBACvCkxB,oBAAoB9gC,IAAI2P,QAAQC;gBAChCwwB,gBAAgBpgC;oBAAO2P,QAAQA;oBAAQC,OAAOA;;;YAIlD6J,WAAW,SAASzZ;gBAChB+gC,MAAM/gC;;YAGVV,OAAO;gBACH8gC;gBACAC,cAAc;gBACdC,YAAY;;;;ICzHxB99C,GAAGmqB,eAAe,SAASnP;QACvB;QAEA,IAAI/b,SAAS2/C;QAEb3/C;YACImrB,eAAe;YACfzpB;gBACIyB,KAAK,SAASC,SAAS8H;gBACvBmgB,eAAe,SAASzb;;;QAIhC,SAASgwC,QAAQ5zC;YACb,OAAOA,KAAK9H,QACR8H,KAAK9H,KAAKyG,QAAQ,cAAc;;QAGxC,SAASk1C;YACLF,qBAAqB5+C,GAAGf,QAAQmrB,eAAellB,OAAO,SAAS,SAASuxB;gBACpE,IAAIsoB,gBAAgBtoB,MAAMsoB;gBAE1B,IAAIA,eAAe;oBACf/+C,GAAGY,KAAKm+C,cAAcnxC,OAAO,SAAShM,KAAKqJ;wBACvC,IAAI4zC,QAAQ5zC,OAAO;4BACf,IAAI4D,OAAO5D,KAAK+zC;4BAChB//C,QAAQ0B,UAAU2pB,cAAczb;;;;;;QAOpD,SAASowC;YACL,IAAIL,oBAAoB;gBACpBA;;;QAIR5+C,GAAGuG,OAAOtH,SAAS+b;QACnB8jC;QAEA9+C,GAAGuG,OAAOtE;YACN6a,OAAO;gBACHmiC;;;;ICpCZj/C,GAAGwxB,cAAc,SAASvyB,SAASigD,aAAa98C;QAC5C;QACA,IAAI2B,OAAQ9B,MACRw4B,kBAAkBx7B,QAAQw7B,iBAC1B0kB,SAASlgD,QAAQyD,SACjBivB,aAAa1yB,QAAQ0yB;QAGzB3xB,GAAGuG,OAAOtE;YAIN4vB,aAAa;YAIbD,eAAeD;YAGfF,gBAAgB;YAGhBC,uBAAuB;gBAEnB,IAAIytB,UAAU,MAAM;oBAChB,OAAO;;gBAGX,OAAOp7C,KAAKq7C,UAAUD;;;QAK9B,SAASE,qBAAqBF;YAC1B,IAAIA,OAAO92C,aAAa,WAAW;gBAC/BtE,KAAK8tB,cAAcstB,OAAO92C,aAAa;;;QAM/C,SAASi3C,aAAaH,QAAQI;YAC1B,IAAIJ,OAAOK,kBAAkBL,OAAOK,iBAAiB;gBACjDp9C,IAAI,0DAA0D;gBAC9Dm9C;mBAEC;gBACD,OAAO;;;QAKf,SAASE,oBAAoBN;YACzB,IAAII,eAAeJ,OAAOO;YAG1B1/C,GAAGm/C,QAAQj6C,OAAO,UAAU,SAASuxB;gBACjCA,QAAQA,SAASxtB,OAAOwtB;gBAExB,IAAIA,MAAMtkB,gBAAgB;oBACtBskB,MAAMtkB;uBAEL;oBACDskB,MAAMpkB,cAAc;;gBAGxBitC,aAAaH,QAAQI,iBAAiBL;;YAK1CC,OAAOO,SAAS;gBACZJ,aAAaH,QAAQI,iBAAiBL;;;QAM9C,SAASS,gBAAgBR;YACrB,IAAIA,QAAQ;gBACR,IAAIn/C,GAAGmL,SAASg0C,SAAS;oBACrBA,SAASjyC,SAASg6B,eAAeiY;;gBAGrC,IAAIA,QAAQ;oBACR/8C,IAAI;oBACJi9C,qBAAqBF;oBACrB1kB,mBAAmBglB,oBAAoBN;;;YAI/C,OAAOA;;QAGXA,SAASQ,gBAAgBR;QACzBl9C,KAAKwvB,mBAAmB0tB;;IAG5Bn/C,GAAGuG,OAAOvG,GAAGwxB,YAAYlwB;QAGrB89C,WAAW,SAAShrC;YAChB;YACA,IAAIf,UACAusC,oBAAoB,SAASz8C;gBACzB,IAAI08C,oBACA,UACA,SACA,SACA;gBAGJ,OAAO7/C,GAAG4J,QAAQi2C,iBAAiB18C,KAAKpD,iBAAiB;eAE7D+/C,kBAAkB,SAAS38C;gBACvB,OAAOnD,GAAG4J,UAAS,YAAY,WAAUzG,KAAKpD,kBAAkB;eAEpEggD,cAAc,SAAS57C;gBACnB,IAAI27C,gBAAgB37C,GAAGhB,UAAUgB,GAAG67C,SAAS;oBACzC,OAAO;;gBAGX,OAAO77C,GAAGgT,YAAYhT,GAAGhB,KAAKpD,kBAAkB;eAEpDkgD,cAAc,SAASC;gBACnB,IAAIx1C,QAAQ;gBAEZ1K,GAAGY,KAAKZ,GAAGkgD,QAAQz4C,YAAY,SAAS7F,KAAK8F;oBACzC,IAAIA,MAAMmF,QAAQ9M,kBAAkB,YAAY2H,MAAMy4C,UAAU;wBAC5Dz1C,QAAQhD,MAAMgD;wBACd,OAAO;;;gBAIf,OAAOA;;YAGf1K,GAAGY,KAAKwT,KAAKgsC,UAAU,SAASx+C,KAAKuC;gBACjC,KAAKnE,GAAGuM,QAAQpI,IAAI,SAASA,GAAG0I,QAAQ9M,kBAAkB,eACtD6/C,kBAAkBz7C,GAAGhB,UACpB48C,YAAY57C,KAAK;oBAElBkP,IAAIlP,GAAGnD,QAAQmD,GAAGuG;uBAEjB,IAAIvG,GAAG0I,QAAQ9M,kBAAkB,aAAaggD,YAAY57C,KAAK;oBAChE,IAAIuG,QAAQu1C,YAAY97C;oBAExB,IAAIuG,UAAU,MAAM;wBAChB2I,IAAIlP,GAAGnD,QAAQ0J;;;;YAK3B,OAAO2I;;;ICzJfrT,GAAGglC,cAAchlC,GAAGglC;IACpBhlC,GAAGglC,YAAYyB,oBAAoB,SAASxnC,SAASghC;QACjD;QAEA,IAAInP,UAAU7uB,MACVihB,UAAU+c,MAAM/c,SAChByC,UAAUsa,MAAMta,SAChBvjB,MAAM69B,MAAM79B;QAKhB,SAASi+C,qBAAqB7iC,IAAIypB;YAG9B,IAAIxT,UAAU6sB,KAAKC;YAGnB;gBAEID,MAAMrZ,OAAOa,mBAAmBb,OAAOuZ,cAActzC;gBACrDqzC,YAAYD,IAAI/Y,KAAK90B;gBAErBrQ,IAAI;gBACJA,IAAI,iBAAiBm+C;gBAErB,IAAIA,aAAaA,UAAUn9C,MAAM,WAAW;oBACxCm9C,YAAYD,IAAI/Y,KAAK5/B,WAAWA,WAAW84C;;gBAG/ChtB,WAAW3C,QAAQ2W,mBAAmB8Y;cAE1C,OAAOp+C;gBACHC,IAAI,0DAA0DD,MAAME,UAAU,KAAK;gBACnFoxB;oBAAYpkB,SAAS;;;YAGzB,OAAOokB;;QAMX,SAASitB,WAAWljC,IAAIypB;YACpB,IAAIznC,SAASP,QAAQwqB,YAAY3E,IAAItH,KACjC2L,SAASlqB,QAAQkqB,OAAOppB,kBAAkB,QAAQ,QAAQ,QAC1D8gB,WAAW5hB,QAAQyqB,cAAc5E,IAAItH,KACrCxc,OAAOkiB,QAAQ1F;YAEnBhe,OAAOP,QAAQsqB,YAAY5D,QAAQnI;YACnChe,OAAOP,QAAQq5B,iBAAiBt3B;YAEhC,OAAO8vB,QAAQkX;gBACX7e,QAAQA;gBACRtI,UAAUA;gBACVrhB,QAAQA;gBACRg5B,cAAcv5B,QAAQu5B;gBACtByP,YAAYhB,OAAOjmC;;;QAI3BiB,KAAKyiC,aAAa,SAASlnB;YACvB,IAAIvQ,QAAQ6jB,QAAQtU,SAASgB,KACzBypB,SAASnW,QAAQiX,cAAcvqB,KAC/BtO,UAAU,IAAIlP,GAAGmP,WACjBiF;YAEJA,OAAOssC,WAAWljC,IAAIypB;YACtB7yB,KAAKE,YAAYrH;YAEjB6jB,QAAQ8W,iBAAiBX,QAAQ,SAAS0Z;gBACtCv+C,IAAI;gBAEJ,IAAIqxB,WAAWktB,sBAAsBA,sBAAsBN,qBAAqB7iC,IAAIypB;gBAEpFnW,QAAQ6W,iBAAiBnqB;gBAGzB,KAAKve,QAAQ0qB,KAAKoI,UAAU;oBACxB/xB,GAAGinC,QAAQnhC;;gBAGf,IAAI2tB,SAASpkB,SAAS;oBAClBH,QAAQG,QAAQokB;uBAEf;oBACDvkB,QAAQK,QAAQkkB;;;YAIxBrxB,IAAI,gCAAgCob;YACpCpJ,KAAKsrC;YACL1/C,GAAGoU,MAAMtO;YAET,OAAOoJ;;QAGXlP,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGymC;YACnBxnC;gBACI6nC,QAAQ7nC,QAAQ0qB,KAAKoI;gBACrBtF,WAAWxtB,QAAQwtB;;YAGvBwT;gBACIzS,UAAUvuB,QAAQuuB;gBAClBtK,SAASA;gBACTyC,SAASA;gBACTvjB,KAAKA;;;;IC5GjBpC,GAAGglC,cAAchlC,GAAGglC;IACpBhlC,GAAGglC,YAAYmD,mBAAmB,SAAS/pB,MAAM6hB;QAC7C;QAEA,IAAInP,UAAU7uB,MACVihB,UAAU+c,MAAM/c,SAChBkC,UAAU6a,MAAM7a,SAChBO,UAAUsa,MAAMta,SAChBvjB,MAAM69B,MAAM79B,KACZw+C,YAAYxiC,KAAKma,kBAAkBna,KAAKoa,cAExCqoB,4BAA4B,SAASrjC,IAAIhe,QAAQwuB;YAC7C,IAAIzP,OAAO6G,QAAQ5H,KACfxc,OAAOkiB,QAAQ1F;YAEnBhe,OAAO4e,KAAK5F,SAASshB,WAAWC,aAAa/L,UAAUqc;YACvD7qC,OAAO4e,KAAK5F,SAASshB,WAAWE,kBAAkBhM,UAAU5f;YAC5D5O,OAAO4e,KAAK5F,SAASshB,WAAWG,aAAajM,UAAUzP;YACvD/e,OAAO4e,KAAK5F,SAASshB,WAAWK,cAAcnM,UAAUsc;YACxD9qC,OAAO4e,KAAKqa,qBAAqBla;YAMjC,IAAIqiC,WAAW;gBACXphD,OAAO4e,KAAKka,iBAAiBt3B;;WAIrC8/C,yBAAyB,IAAI9gD,GAAGglC,YAAY+b;YACxCp3B,MAAMvL,KAAKuL;YACX9I,UAAUzC,KAAK5F,SAASnJ,QAAQwR;YAChCze,KAAKA;YAGT4+C,iCAAiC,SAASxjC,IAAIhG;YAC1C,IAAItI,UAAU,IAAIlP,GAAGmP;YAErBqI,IAAIwmB,qBAAqB;gBACrB,IAAIxmB,IAAIgnB,eAAe,GAAG;oBACtB,IAAIp3B,SAAS65C,wBAAwBzjC,IAAIhG;oBAEzC,IAAIpQ,OAAOiI,SAAS;wBAChBH,QAAQG,QAAQjI,OAAOqsB,UAAUjc;2BAEhC;wBACDtI,QAAQK,QAAQnI,OAAOqsB,UAAUjc;;;;YAK7C,OAAOtI;WAGXgyC,0BAA0B,SAAS1jC;YAC/B,IAAIhe,SAAS4e,KAAKqL,YAAY3E,IAAItH,KAC9Bxc,OAAOkiB,QAAQ1F,KACfe,OAAO6G,QAAQ5H;YAEnBhe,OAAO4e,KAAKmL,YAAY5D,QAAQnI;YAChChe,OAAO4e,KAAKka,iBAAiBt3B;YAC7BxB,OAAO4e,KAAKqa,qBAAqBla;YACjC/e,OAAO4e,KAAK5F,SAASshB,WAAWK,cAAcrJ,QAAQgS,gBAAgBtlB;YAEtE,OAAOhe;WAGX2hD,wBAAwB,SAAS3pC,KAAKic;YAClC,OAAOzzB,GAAG4J,UAAS,KAAK,KAAK,KAAK,KAAK,OAAM4N,IAAIqG,UAAU,MACtD4V,SAASpkB,WACVokB,SAAS3W;WAGjBmkC,0BAA0B,SAASzjC,IAAIhG;YACnC,IAAIic;YAEJrxB,IAAI,wCAAwCob;YAC5Cpb,IAAI,oBAAoBoV,IAAI0gC;YAE5BzkB,WAAW2tB,cAAc,MAAM5pC;YAE/B;gBACInI,UAAU8xC,sBAAsB3pC,KAAKic;gBACrCA,UAAUA;;WAKlB2tB,gBAAgB,SAAS7zC,QAAQiK;YAC7B,IAAIic;YAEJ;gBACIrxB,IAAIpC,GAAGyL,OAAO,6CAA6C+L,IAAIqG,QAAQrG,IAAI0gC;gBAC3EzkB,WAAWzzB,GAAGuU,UAAUiD,IAAI0gC;cAEhC,OAAO/1C;gBACHoL,UAAUnL,IAAI,uDAAuDD,MAAME,UAAU,KAAK;;YAG9F,OAAOoxB;WAGX4tB,4BAA4B,SAAS7jC;YACjC,IAAItO,UAAU,IAAIlP,GAAGmP;YAErB2xC,uBAAuBQ,SACf9jC,IACAsT,QAAQgZ,WAAWtsB,KACnB0jC,wBAAwB1jC,KACxBY,KAAKoL,cAAc1E,IAAItH,KAE1BvD,KAAK,SAASzC;gBACXtI,QAAQG,QAAQ+xC,cAAc,OAAO5pC,MAAMA;eAC5C,SAASA;gBACRtI,QAAQK,QAAQ6xC,cAAc,OAAO5pC,MAAMA;;YAGnD,OAAOtI;WAGXqyC,8BAA8B,SAAS/hD,QAAQgY,KAAKrJ,YAAYqP;YAC5D,IAAIvJ,WAAW,IAAI5G,YACf8b,SAAS/K,KAAK+K,QACdtI,WAAWzC,KAAKsL,cAAc5E,IAAItH,KAClCxc,OAAOkiB,QAAQ1F,KACfe,OAAO6G,QAAQ5H;YAEnBhe,OAAO4e,KAAKmL,YAAY5D,QAAQnI;YAChChe,OAAO4e,KAAKka,iBAAiBt3B;YAE7B,IAAI4/C,WAAW;gBACXphD,OAAO4e,KAAKqa,qBAAqBla;;YAIrC,KAAKH,KAAKoa,cAAc;gBACpB,KAAKooB,WAAW;oBACZphD,OAAO4e,KAAKqO,aAAazrB;;gBAE7B6f,WAAW7gB,GAAGoT,QAAQ5T,QAAQqhB;;YAGlCrJ,IAAI2mB,KAAKhV,QAAQtI,UAAU;YAE3B,IAAIzC,KAAKuL,KAAKoI,YAAY3T,KAAKuL,KAAK6Q,iBAAiB;gBACjDhjB,IAAIC,kBAAkB;;YAG1B,IAAImpC,WAAW;gBACX,IAAIxiC,KAAKoa,cAAc;oBACnBx4B,GAAGgU,aAAaxU,QAAQyU;;gBAG5BA,SAAS3K,OAAO8U,KAAKqO,WAAWte;gBAChC,OAAO8F;;YAGX,OAAO9F;WAGXqzC,mBAAmB,SAAShkC,IAAIhG;YAC5B,IAAIiqC,eAAerjC,KAAKoL,cAAc1E,IAAItH,KACtCrP,aAAa2iB,QAAQ1M,QAAQ5G;YAEjChG,IAAIqnB,iBAAiB,UAAU;YAC/BrnB,IAAIqnB,iBAAiB,oBAAoB;YACzCrnB,IAAIqnB,iBAAiB,iBAAiB;YAEtC,KAAK+hB,WAAW;gBACZppC,IAAIqnB,iBAAiB,gBAAgB;gBAErCrnB,IAAIqnB,iBAAiB,eAAe1wB,WAAWhL;;YAGnDnD,GAAGY,KAAK6gD,cAAc,SAASzgD,MAAMZ;gBACjCoX,IAAIqnB,iBAAiB79B,MAAMZ;;;QAIvCJ,GAAGuG,OAAOtE;YACNkhC,aAAa,SAAS3lB,IAAIujB,UAAUzG;gBAChC,IAAItM,YAAY8C,QAAQkQ,cAAcxjB,IAAIujB,WACtCvpB,MAAMsZ,QAAQgZ,WAAWtsB,IAAIujB,WAC7BxiB,OAAO6G,QAAQ5H,KACftO,SAASwyC,QAAQliD;gBAErB0P,UAAU8xC,+BAA+BxjC,IAAIhG;gBAC7CsZ,QAAQqa,yBAAyB3tB,IAAIujB,UAAU/S,UAAUzP;gBACzD/e,SAAS4e,KAAKqL,YAAY3E,IAAItH;gBAC9BqjC,0BAA0BrjC,IAAIhe,QAAQwuB;gBAEtC,IAAIsM,UAAU;oBACV96B,OAAO4e,KAAK9E,OAAOwgB,WAAWQ,YAAY;;gBAG9ConB,SAASH,4BAA4B/hD,QAAQgY,KAAKwW,UAAUnf,MAAM2O;gBAClEgkC,iBAAiBhkC,IAAIhG;gBACrBA,IAAI6mB,KAAKqjB;gBAET,OAAOxyC;;YAGXw1B,YAAY,SAASlnB;gBACjB,IAAIrP,aAAa2iB,QAAQ1M,QAAQ5G,KAC7BtO,SAASsI,KAAKhY,QAAQkiD;gBAE1BlqC,MAAMsZ,QAAQgZ,WAAWtsB;gBACzBsT,QAAQqa,yBAAyB3tB;gBACjCtO,UAAU8xC,+BAA+BxjC,IAAIhG;gBAC7ChY,SAAS4e,KAAKqL,YAAY3E,IAAItH;gBAC9BkkC,SAASH,4BAA4B/hD,QAAQgY,KAAKrJ,YAAYqP;gBAC9DgkC,iBAAiBhkC,IAAIhG;gBACrBA,IAAI6mB,KAAKqjB;gBAET,OAAOxyC;;;QAIflP,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGmoC;YACnBlpC,SAASe,GAAGuG;gBAAQ5G,WAAW;eAAgBye;YAC/C6hB,OAAOjgC,GAAGuG;gBAAQqe,aAAaxG,KAAKsL,cAAc5E;eAAMmb;;QAG5DjgC,GAAG2P,SAAS1N,MAAM,SAAS6N;YACvB;gBACIuxB,gBAAgB,SAAS7jB;oBACrB,IAAIY,KAAK5F,SAASnJ,QAAQwR,UAAU;wBAChC,OAAOwgC,0BAA0B7jC;2BAEhC;wBACD,OAAO1N,OAAOuxB,eAAe7jB,IAAIxd,GAAG+S,KAAKquC,eAAen/C,MAAM;;;;;;ICvOlFjC,GAAGglC,YAAY+b,6BAA6B,SAAS/lC;QACjD;QAEA,IAAIixB,WACA9iB,SAAS,QACTlqB;YACI0qB;gBACIqI,UAAU;gBACVD,UAAU;gBACVyI,iBAAiB;;YAErB3Z,UAAU;YACVze,KAAK,SAASsJ,KAAKvB;WAEvBw3C,eACAC;YACI98B,KAAK,SAAStH;gBACV,OAAOve,QAAQ4hB;;;QAI3B7gB,GAAGuG,OAAOtH,SAAS+b;QAEnBixB,YAAYjsC,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7B;YAC/BI,cAAc;YACdC,gBAAezS;YACfA,QAAQA;YACRO,eAAek4B;YACf7lB,oCAAoC;YACpCpS,MAAM1qB,QAAQ0qB;YACdvnB,KAAKnD,QAAQmD;YACbkrB,YAAY,SAAS9P,IAAIhG,KAAKwS;gBAC1B,IAAI9a,UAAUyyC,SAASnkC;uBAEhBmkC,SAASnkC;gBAEhB,IAAIwM,SAAS;oBACT9a,QAAQK,QAAQiI;uBAEf;oBACDtI,QAAQG,QAAQmI;;;;QAK5BxX,GAAGuG,OAAOtE;YACNq/C,UAAU,SAAS9jC,IAAIhG,KAAKhY,QAAQynB;gBAChC,IAAI/X,UAAU,IAAIlP,GAAGmP;gBAErBlQ,QAAQmD,IAAI,4CAA4Cob;gBAExDmkC,SAASnkC,MAAMtO;gBAEf+8B,UAAUjN,cAAcxhB,IACnB6hB,WAAW7/B,QACXggC,YAAYvY,SACZoX,KAAK7mB;gBAEV,OAAOtI;;;;ICjEnBlP,GAAGyE,cAAc,SAASuW;QACtB;QAEA,IAAI/b,SACA4iD,wBAAwB,gBACxBC,yBAAyB,oBACzBC,sBACAC,mBACA/mC,iBAAiB,IAAIjb,GAAGoV;QAE5BnW;YACIsF;YACA09C,oBAAoB;YACpB51B;gBACI61B,YAAY;;YAEhBvhD,WAAW,IAAIX,GAAGyE,YAAY9D;;QAGlCX,GAAGuG,OAAOtH,SAAS+b,GAAG;QAEtB,SAASmnC,mBAAmBhgC,OAAOigC;YAE/B,IAAIC,eAAehhD,MAAMC,UAAUxB,MAAMyB,KAAK4gB;YAE9CljB,QAAQ0B,UAAU2hD,QAAQ,aAAangC,MAAM/d,SAAS;YACtDg+C,eAAeG,aAAa;YAC5BtjD,QAAQ0B,UAAU6hD,+BAA+BH,cAAcD,eAAeK;;QAGlF,SAASC,iBAAiBpnB;YACtB,IAAIqnB,oBAAoB,IAAI3iD,GAAGmP;YAE/B,IAAImsB,MAAMvvB,QAAQ;gBACduvB,MAAMlZ,KAAK,SAASA;oBAChB,IAAIphB,OAAOs6B,MAAMt6B,MACb4hD,WAAWtnB,MAAMsnB,UACjBC,wBAAwBD,SAASh5C,QAAQ5I;oBAG7C4hD,WAAWA,SAAS5tC,OAAO,GAAG6tC;oBAG9B,IAAID,SAAShjD,OAAO,OAAO,KAAK;wBAC5BgjD,WAAWA,SAAS5tC,OAAO;;oBAG/BoN,KAAK0gC,SAASF;oBACdZ,aAAalgD,KAAKsgB;oBAClBugC,kBAAkBtzC;mBAEtB,SAAS0zC;oBACL9jD,QAAQ0B,UAAU2hD,QAAQ,sBAAsBhnB,MAAMsnB,WAAW,wBAAwBG,UAAU1wB,OAAO,KAAK;oBAC/GswB,kBAAkBpzC;;mBAGrB,IAAI+rB,MAAM0nB,aAAa;gBACxBC,oBAAoB3nB,OAAOrhB,KACvB,SAASipC,eAAe3lC;oBACpB,IAAI4lC,cAAc5lC,QAAQnZ;oBAE1BpE,GAAGY,KAAK2c,SAAS,SAAS3b,KAAK05B;wBAC3BonB,iBAAiBpnB,OAAO5gB,KAAK;4BACzByoC,eAAe;4BAEf,IAAIA,gBAAgB,GAAG;gCACnBR,kBAAkBtzC;;;;oBAK9B,KAAKkO,QAAQnZ,QAAQ;wBACjBu+C,kBAAkBtzC;;mBAI1B,SAAS+zC,YAAYL;oBACjB9jD,QAAQ0B,UAAU2hD,QAAQ,sBAAsBhnB,MAAMsnB,WAAW,wBAAwBG,UAAU1wB,OAAO,KAAK;oBAC/GswB,kBAAkBpzC;;;YAK9B,OAAOozC;;QAIX,SAASM,oBAAoB3nB,OAAO2f,QAAQoI,cAAcC;YACtD,IAAIp0C,UAAUo0C,mBAAmB,IAAItjD,GAAGmP,WACpCo0C,YAAYtI,UAAU3f,MAAMkoB;YAEhCD,UAAUE,YACN,SAASC,YAAYnmC;gBACjB,IAAIomC,aAAaN,eAAeA,aAAalwC,OAAOoK,WAAWA;gBAE/D,IAAIA,QAAQnZ,QAAQ;oBAChBwnB,WAAW;wBACPq3B,oBAAoB3nB,OAAOioB,WAAWI,YAAYz0C;uBACnD;uBAEF;oBACDA,QAAQG,QAAQs0C;;eAIxBz0C,QAAQK;YAGZ,OAAOL;;QAGX,SAAS00C,mBAAmBj2C,cAAcy0C;YACtC,IAAIyB,4BACAC,4BAA4B,IAAI9jD,GAAGmP;YAEvClQ,QAAQ0B,UAAUojD;YAClB3B,eAAeG,aAAa;YAE5B,IAAI50C,aAAawU,MAAM/d,SAAS,MAAMnF,QAAQgjD,oBAAoB;gBAC9DhjD,QAAQ0B,UAAU6hD;gBAClBvjD,QAAQ0B,UAAUqjD,UAAU,qBAAqB;gBACjD5B,eAAeG,aAAa;gBAC5BuB,0BAA0Bv0C;mBAEzB;gBACDyyC;gBAEA,IAAIhiD,GAAG0N,sBAAsBC,eAAe;oBACxC3N,GAAGY,KAAK+M,aAAaC,OAAO,SAAShM,KAAKqJ;wBACtC,IAAIqwB,QAAQrwB,KAAK4C;wBAEjB,IAAIytB,OAAO;4BAEP,IAAIA,MAAMvvB,QAAQ;gCACdi2C,aAAalgD,KAAKmJ,KAAK+zC;mCAGtB;gCACD6E,sBAAsB/hD,KAAK4gD,iBAAiBpnB,OAAO5gB,KAAK;oCACpDmpC,sBAAsBtf;oCACtB,IAAIsf,sBAAsBz/C,WAAW,GAAG;wCACpC0/C,0BAA0Bz0C;;;;;;uBAO7C;oBACD2yC,eAAer0C,aAAawU;;gBAGhC,IAAI0hC,sBAAsBz/C,WAAW,GAAG;oBACpC0/C,0BAA0Bz0C;;;YAIlC,OAAOy0C;;QAGX,SAASG,cAAcC;YACnB,IAAIC,WAAW,IAAInkD,GAAGokD;gBAClBvC,uBAAuBA;gBACvBn/C,SAASwhD;gBACTG,SAAS,SAASjyC;oBACdpS,GAAGkkD,UAAUp9C,SAAS7H,QAAQotB,QAAQ61B;oBACtC9vC,EAAEkyC;;gBAENC,uBAAuB,SAASnyC;oBAC5BpS,GAAGkkD,UAAUn9C,YAAY9H,QAAQotB,QAAQ61B;;gBAE7CsC,QAAQ,SAASpyC;oBACbwxC,mBAAmBxxC,EAAEzE,cAAcw2C,UAAUlqC,KACzC;wBACIkoC,mBAAmBH,cAAcmC;uBAErC;wBACIllD,QAAQ0B,UAAU2hD,QAAQ,uEAAuE;;;;YAMjHrnC,eAAexF,YAAY;gBACvB0uC,SAAS7uC;;YAGbtV,GAAGkkD,UAAUh8C,aAAa45C,2BAA2B9hD,GAAGkkD,UAAUn/C;YAElEg9C,gBAAgBjgD,KAAKqiD;YAErB,OAAOA;;QAGX,SAASM,WAAWC;YAChB,IAAIC;YAEJ3kD,GAAGY,KAAK8jD,UAAU/2C,aAAai3C,OAAO,SAASzkD,KAAKC;gBAChD,IAAIA,QAAQ,SAAS;oBACjBukD,WAAW;oBACX,OAAO;;;YAIf,OAAOA;;QAWX,SAASE,mBAAmBzyC;YACxB,IAAIpS,GAAGuR,WAAW;gBACd,QAAQa,EAAE0yC;;YAGd,IAAI9kD,GAAGmR,UAAU;gBACb,OAAOiB,EAAE6qC,IAAI,KAAK7qC,EAAE2yC,IAAI;;YAG5B,OAAO3yC,EAAE6qC,MAAM,KAAK7qC,EAAE2yC,MAAM;;QAGhC,SAASC;YACL,IAAIC,YAAYhmD,QAAQsF,kBAEpB2gD,qBAAqB;gBACjBt5B,WAAW;oBACP5rB,GAAGY,KAAKqkD,WAAW,SAASrjD,KAAKuiD;wBAC7BnkD,GAAGmkD,UAAUj8C,aAAa45C,2BAA2B9hD,GAAGmkD,UAAUp/C;wBAClE/E,GAAGmkD,UAAUp9C,YAAY9H,QAAQotB,QAAQ61B;;mBAE9C;;YAGXliD,GAAGY,KAAKqkD,WAAW,SAASrjD,KAAKuiD;gBAC7B,IAAI/B,iBAAiB6B,cAAcE;gBAGnC,IAAIc,UAAU7gD,UAAUpE,GAAGgW,kBAAkB8C,UAAU;oBACnDmC,eAAe/V,OAAOgI,UAAU,aAAa,SAASkF;wBAClD,KAAKgwC,eAAeG,kBAAkBkC,WAAWryC,IAAI;4BACjDpS,GAAGY,KAAKqkD,WAAW,SAASrjD,KAAKuiD;gCAG7B,IAAIA,oBAAoBgB,eACpBnlD,GAAGmkD,UAAUj8C,aAAa45C,yBAAyB;oCAEnD9hD,GAAGmkD,UAAUn+C;wCAAKf,SAAS;;;;;;;;YAQnDgW,eAAe/V,OAAOgI,UAAU,aAAa,SAASkF;gBAClD,IAAIyyC,mBAAmBzyC,IAAI;oBACvB8yC;;;YAORjqC,eAAe/V,OAAOlF,GAAGkN,UAAUzF,WAAW,IAAI,cAAc,SAAS2K;gBACrE8yC;;YAGJjqC,eAAe/V,OAAOgI,UAAU,QAAQ,SAASkF;gBAC7CA,EAAED;gBACF+yC;;YAGJjqC,eAAe/V,OAAOgI,UAAU20C,uBAAuBqD;;QAG3DF;QAEAhlD,GAAGuG,OAAOtE;YACNmjD,oBAAoB,SAAS1iD;gBACzBzD,QAAQsF,iBAAiBzC,KAAKY;gBAC9BuhD,cAAcvhD;;YAGlB2iD,gBAAgB,SAAS3iD;gBACrB,IAAIkR,GACA0xC,MAAMrmD,QAAQsF;gBAElB,KAAKqP,KAAK0xC,KAAK;oBACX,IAAIA,IAAI1xC,OAAOlR,SAAS;wBACpB,OAAO4iD,IAAIrmC,OAAOrL,GAAG;;;;YAKjC0B,SAAS;gBACL2F,eAAe3F;gBACftV,GAAGY,KAAKmhD,iBAAiB,SAASngD,KAAKuiD;oBACnCA,SAAS7uC;;;;;IAMzBtV,GAAGyE,YAAY9D,YAAY;QACvB;QAEA;YACIojD,wBAAwB;YACxBvB,gCAAgC,SAASrgC,OAAOojC;YAChDvB,WAAW,SAAS3xB,MAAMmzB;gBACtBxlD,GAAGoC,IAAI,6BAA6BiwB,OAAO,6BAA6BmzB,iBAAiB,KAAK;;YAElGlD,SAAS,SAASjgD,SAAS8H;gBACvBnK,GAAGoC,IAAIC,SAAS8H;;;;IAK5BnK,GAAGokD,iBAAiB,SAASppC;QACzB;QAEA,IAAIC,iBAAiB,IAAIjb,GAAGoV,kBACxBnW,SAASyD,SAAS+iD,aAAaC;QAEnCzmD;YACIyD,SAAS;YACT2hD,SAAS,SAASjyC;YAClBskB,SAAS,SAAStkB;YAElBmyC,uBAAuB,SAASnyC;YAChCoyC,QAAQ,SAASpyC;;QAGrBpS,GAAGuG,OAAOtH,SAAS+b;QACnBtY,UAAUzD,QAAQyD;QAElB,SAASijD;YACL,OAAO3lD,GAAGmR,YAAanR,GAAGuR,aAAavR,GAAGwR;;QAG9C,SAASo0C,mBAAmBxzC;YAExB,KAAKszC,qBAAqB;gBAGtB,IAAIC,0BAA0B;oBAC1B1qC,eAAe/V,OAAOgI,UAAU,YAAY,SAASkF;wBACjDA,EAAED;;uBAEH;oBACH8I,eAAe/V,OAAOgI,UAAU,YAAY,SAASkF;wBACjD,IAAIA,EAAEzE,cAAc;4BAChByE,EAAEzE,aAAak4C,aAAa;4BAC5BzzC,EAAED;;;;gBAKduzC,sBAAsB;;;QAI9B,SAASI,gBAAgB1zC;YAGrB,KAAKpS,GAAGgW,kBAAkB8C,UAAU;gBAChC,OAAO;;YAGX,IAAIitC,YAAYC,KAAK5zC,EAAEzE,cAEvBs4C,WAAWjmD,GAAGmR;YAOd40C,aAAa/lD,GAAG2Q,QAAQ3Q,GAAGgW,kBAAkB8C,WAAW,OAAOktC,GAAGE,kBAAkB;YACpF,OAAOF,MAAMD,eAAeC,GAAG7jC,UAAW8jC,YAAYD,GAAGpB,MAAMp/C,YAAYwgD,GAAGpB,MAAMp/C,SAAS;;QAGjG,SAAS2gD,oBAAoBC;YACzB,IAAIA,eAAe9lD,WAAW;gBAC1BmlD,cAAcW;;YAElB,OAAOX;;QAGX,SAASY;YACL,IAAIC;YAEJ,SAASC;gBACLD,iBAAiBp5C,SAASs5C,YAAY;gBACtCF,eAAeG,UAAUxnD,QAAQ4iD,uBAAuB,MAAM;;YAGlE,IAAI54C,OAAOy9C,aAAa;gBACpB;oBACIJ,iBAAiB,IAAII,YAAYznD,QAAQ4iD;kBAE7C,OAAOjK;oBACH2O;;mBAGH;gBACDA;;YAGJr5C,SAASy5C,cAAcL;;QAG3B,SAASM;YACL3rC,eAAe/V,OAAOxC,SAAS,YAAY,SAAS0P;gBAChD,KAAK0zC,gBAAgB1zC,IAAI;oBACrB;;gBAKJ,IAAIy0C,SAAS7mD,GAAG2Q,QAAQ3Q,GAAGgW,kBAAkB8C,WAAW,OAAO1G,EAAEzE,aAAau4C;gBAC9E,IAAIW,WAAW,UAAUA,WAAW,YAAY;oBAC5Cz0C,EAAEzE,aAAak4C,aAAa;uBACzB;oBACHzzC,EAAEzE,aAAak4C,aAAa;;gBAGhCzzC,EAAEkyC;gBACFlyC,EAAED;;YAGN8I,eAAe/V,OAAOxC,SAAS,aAAa,SAAS0P;gBACjD,KAAK+zC,uBAAuB;oBACxB,KAAKL,gBAAgB1zC,IAAI;wBACrB;;oBAEJnT,QAAQolD,QAAQjyC;;;YAIxB6I,eAAe/V,OAAOxC,SAAS,aAAa,SAAS0P;gBACjD,KAAK0zC,gBAAgB1zC,IAAI;oBACrB;;gBAGJnT,QAAQy3B,QAAQtkB;gBAEhB,IAAI0yC,gBAAgB53C,SAAS45C,iBAAiB10C,EAAE20C,SAAS30C,EAAE40C;gBAE3D,IAAIhnD,GAAGiC,MAAMuD,SAASs/C,gBAAgB;oBAClC;;gBAGJ7lD,QAAQslD,sBAAsBnyC;;YAGlC6I,eAAe/V,OAAOxC,SAAS,QAAQ,SAAS0P;gBAC5C,KAAK+zC,uBAAuB;oBACxB,KAAKL,gBAAgB1zC,IAAI;wBACrB;;oBAGJA,EAAED;oBACFC,EAAEkyC;oBACFrlD,QAAQulD,OAAOpyC;oBAEfi0C;;;;QAKZT;QACAgB;QAEA5mD,GAAGuG,OAAOtE;YACNsgD,cAAc,SAAS6D;gBACnB,OAAOD,oBAAoBC;;YAG/B9wC,SAAS;gBACL2F,eAAe3F;;YAGnBmtC,YAAY;gBACR,OAAO//C;;;;KCvelB;QACG;QAEA1C,GAAGinD;YACClmC,iBAAiB,SAASC;gBACtB/e,KAAKilD,QAAQ5lD,UAAUyf,gBAAgB/e,MAAMC,MAAMT;gBACnDS,KAAKklD,YAAYC;;YAGrBvkC,kBAAkB;gBACd5gB,KAAKilD,QAAQ5lD,UAAUuhB,iBAAiB7gB,MAAMC,MAAMT;gBACpDS,KAAKklD,YAAYE;;YAGrBC,kBAAkB,SAAS5kD;gBACvBT,KAAKslD,QAAQtlD,KAAKslD,KAAKnC,mBAAmB1iD;;YAG9C8kD,qBAAqB,SAAS9kD;gBAC1B,IAAIT,KAAKslD,MAAM;oBACX,OAAOtlD,KAAKslD,KAAKlC,eAAe3iD;;;YAIxC+kD,iBAAiB,SAASjqC;gBACtB,KAAKvb,KAAKklD,YAAYO,gBAAgBlqC,KAAK;oBACvC,OAAOvb,KAAKklD,YAAYQ,iBAAiBnqC;;;YAIjDV,OAAO;gBACH7a,KAAKilD,QAAQ5lD,UAAUwb,MAAM9a,MAAMC,MAAMT;gBACzCS,KAAKklD,YAAYrqC;gBAEjB,KAAK7a,KAAKpB,SAASqlB,UAAUjkB,KAAKklD,YAAY1iC,aAAa;oBACvDxiB,KAAKwtB,mBAAmBxtB,KAAK4pB;wBACzBnpB,SAAST,KAAKklD,YAAY1iC;wBAC1BjJ,OAAOvZ,KAAKpB,SAASiH,KAAK6kB;uBAC3BlQ;;gBAGP,IAAIxa,KAAKslD,MAAM;oBACXtlD,KAAKslD,KAAKjyC;oBACVrT,KAAKslD,OAAOtlD,KAAK2lD;;gBAGrB3lD,KAAK4lD,qBAAqB;gBAC1B5lD,KAAK6lD,yBAAyB;gBAE9B7lD,KAAK8lD;;YAGT//B,SAAS,SAASxK,IAAI8B;gBAClB,IAAI0oC,oBAAoB/lD,KAAKpB,SAASiyB,eAAexT;gBAErDrd,KAAKilD,QAAQ5lD,UAAU0mB,QAAQhmB,MAAMC,MAAMT;gBAC3CS,KAAKklD,YAAYc,eAAezqC,IAAIwqC;;YAGxCniC,aAAa,SAASrI;gBAClB,IAAIisB,SAASxnC,KAAKilD,QAAQ5lD,UAAUukB,YAAY7jB,MAAMC,MAAMT;gBAE5DioC,UAAUxnC,KAAKklD,YAAYe,aAAa1qC;gBACxC,OAAOisB;;YAGX3mB,gBAAgB,SAAStF;gBACrB,IAAI2qC,YAAYlmD,KAAKilD,QAAQ5lD,UAAUwhB,eAAe9gB,MAAMC,MAAMT;gBAElE2mD,aAAalmD,KAAKklD,YAAYiB,gBAAgB5qC;gBAC9C,OAAO2qC;;YAGXE,OAAO,SAASC;gBACZ,OAAOrmD,KAAKklD,YAAYoB,UAAUD;;YAGtCE,eAAe,SAAS9kC;gBACpB,IAAItB,OAAOngB,KAAKmiB,QAAQV;gBAExB,OAAOtB,KAAKqmC;;;QAOpBzoD,GAAG0oD;YACChkC,YAAY,SAASjJ;gBACjB,IAAIyK,SAASjkB,KAAKilD,QAAQ5lD,UAAUojB,WAAW1iB,MAAMC,MAAMT;gBAE3D,KAAK0kB,QAAQ;oBACT,IAAIzK,aAAaxZ,KAAKwtB,kBAAkB;wBACpCvJ,SAASjkB,KAAKklD,YAAY1iC;;;gBAIlC,OAAOyB;;YAGXyiC,iBAAiB,SAASjlC;gBACtBzhB,KAAKklD,YAAYyB,WAAWllC;;YAGhCqkC,iCAAiC;gBAC7B9lD,KAAK4mD,2BAA2B7oD,GAAG8oD,2BAA2B7mD,KAAK8mD;gBAInE9mD,KAAK+mD,0BAA0BhpD,GAAGuR;gBAElC,IAAItP,KAAKgnD,0BACT;oBACIhnD,KAAKinD,wBAAwBjnD,KAAKknD;oBAClClnD,KAAKmnD,+BAA+BnnD,KAAKonD;oBACzCpnD,KAAKqnD,6BAA6BrnD,KAAKsnD;;;YAI/C3B,mBAAmB;gBACf,IAAI7jD,OAAO9B,MACPsC,mBAAmBtC,KAAKpB,SAAS2oD,YAAYC,gBAC7CC,aAAaznD,KAAKklD,aAClBwC,kBAAkBD,WAAWE;gBAEjCD,mBAAmBplD,iBAAiBzC,KAAK6nD;gBAEzC,OAAO,IAAI3pD,GAAGyE;oBACVF,kBAAkBA;oBAClB09C,oBAAoBhgD,KAAKpB,SAASuM;oBAClCif;wBACI61B,YAAYjgD,KAAKpB,SAASwrB,QAAQ61B;;oBAEtCvhD;wBACIojD,wBAAwB;4BACpB2F,WAAWG;;wBAEfrH,gCAAgC,SAASrgC,OAAOojC;4BAC5CmE,WAAWI;4BAEX9pD,GAAGY,KAAKuhB,OAAO,SAASvgB,KAAKwgB;gCACzBA,KAAKqmC,eAAelD;;4BAGxB,IAAIpjC,MAAM/d,QAAQ;gCACdL,KAAK+c,SAASqB,OAAO,MAAM;;;wBAGnC6hC,WAAW,SAAS3xB,MAAM03B;4BACtBhmD,KAAKqkB,WAAWiK,MAAM03B;;wBAE1BzH,SAAS,SAASjgD,SAAS8H;4BACvBpG,KAAK3B,IAAIC,SAAS8H;;;;;YAMlC4+C,4BAA4B;gBACxB,IAAIhlD,OAAO9B;gBAEX,OAAO,IAAIjC,GAAG8oD;oBACVY,YAAYznD,KAAKklD;oBAEjB/kD,KAAK,SAASC,SAAS2nD;wBACnBjmD,KAAK3B,IAAIC,SAAS2nD;;oBAGtBC,cAAc,SAASvmC;wBACnB3f,KAAKqf,WAAWM;;oBAGpB8J,UAAU,SAAS9J;wBACf3f,KAAKye,OAAOkB;;oBAGhBwmC,SAAS,SAASxmC;wBACd3f,KAAK4iB,MAAMjD;;oBAGfymC,SAAS,SAASzmC;wBACd3f,KAAK8hB,YAAYnC;;oBAGrB0mC,YAAY,SAAS1mC;wBACjB3f,KAAK+e,eAAeY;;oBAGxB2mC,WAAW,SAAS3mC;wBAChB,OAAO3f,KAAKmf,QAAQQ;;;;YAKhCulC,wBAAwB;gBAEpB,OAAOhnD,KAAKklD,YAAYmD,6BAChBroD,KAAKpB,SAAS8wB,cACf3xB,GAAGuqD,wBACHvqD,GAAGwqD,6BACHxqD,GAAGwqD;;YAGdC,sBAAsB;gBAClB,IAAI1mD,OAAO9B,MACPynD,aAAaznD,KAAKklD;gBAEtB;oBACIuC,YAAYA;oBACZtnD,KAAK,SAASC,SAAS2nD;wBACnBjmD,KAAK3B,IAAIC,SAAS2nD;;oBAEtBU,mBAAmB,SAAShnC;wBACxB,OAAO3f,KAAKmhB;4BAAY1H,IAAIkG;2BAAS7F;;oBAEzCwsC,WAAW,SAAS3mC;wBAChB,OAAO3f,KAAKmf,QAAQQ;;oBAExBinC,WAAW,SAASntC,IAAI8B;wBACpBvb,KAAKikB,QAAQxK,IAAI8B;;oBAErBsrC,uBAAuB,SAASptC,IAAIqtC;wBAChC,IAAIC,UAAU9qD,GAAG0pD,WAAWqB,aAAavtC,MACrCwtC,kBAAkBhrD,GAAG0pD,WAAW/B,iBAAiBnqC;wBAErD,IAAIqtC,WAAW;4BACXC,QAAQhkD,SAAS;4BACjB4iD,WAAWuB,aAAaztC;4BACxBksC,WAAWwB,aAAa1tC;+BAEvB;4BACDstC,QAAQ/jD,YAAY;4BACpB2iD,WAAWyB,aAAa3tC;4BACxBksC,WAAW0B,aAAa5tC;;wBAI5BwtC,gBAAgBlkD,SAAS,WAAWC,YAAY;;;;YAK5D2kB,uBAAuB,SAASlO,IAAIuB,WAAWD;gBAC3C7c,KAAKilD,QAAQ5lD,UAAUoqB,sBAAsB1pB,MAAMC,MAAMT;gBAEzD,IAAIS,KAAKgnD,0BAA0B;oBAE/B,IAAIhnD,KAAKklD,YAAYQ,iBAAiBnqC,OAAOsB,cAAc9e,GAAG6d,OAAOiC,WAAW;wBAC5E7d,KAAKklD,YAAYkE,qBAAqB7tC;wBACtCvb,KAAKklD,YAAY+D,aAAa1tC;;;gBAItC,IAAIuB,cAAc/e,GAAG6d,OAAOuC,mBAAmBtB,cAAc9e,GAAG6d,OAAOsC,WAAW;oBAC9Ele,KAAKklD,YAAYmE,UAAU9tC;oBAC3Bvb,KAAKklD,YAAYoE,cAAc/tC;oBAC/Bxd,GAAGiC,KAAKklD,YAAYQ,iBAAiBnqC,KAAKzW,YAAY9E,KAAKupD,SAASC;uBAEnE,IAAI3sC,cAAc9e,GAAG6d,OAAOyC,eAAe;oBAC5Cre,KAAKklD,YAAYuE,UAAUluC;;;YAInC6rC,gCAAgC;gBAC5B,IAAIjrC,OAAOpe,GAAGuG,WAAWtE,KAAKwoD;gBAE9B,OAAO,IAAIzqD,GAAG2rD,4BAA4BvtC;;YAG9CmrC,8BAA8B;gBAC1B,IAAInrC,OAAOpe,GAAGuG,WAAWtE,KAAKwoD;gBAE9B,OAAO,IAAIzqD,GAAGwqD,0BAA0BpsC;;YAG5C+qC,yBAAyB;gBACrB,IAAI/qC,OAAOpe,GAAGuG,WAAWtE,KAAKwoD;gBAE9B,OAAO,IAAIzqD,GAAGuqD,qBAAqBnsC;;YAGvCiX,gBAAgB,SAAS7X;gBACrBvb,KAAKilD,QAAQ5lD,UAAU+zB,eAAerzB,MAAMC,MAAMT;gBAClDS,KAAKklD,YAAYyE,YAAYpuC;;YAGjC4V,gBAAgB,SAASe,YAAYC;gBACjCnyB,KAAKilD,QAAQ5lD,UAAU8xB,eAAepxB,MAAMC,MAAMT;gBAClDS,KAAKklD,YAAY0E;;YAGrB52B,WAAW,SAASzX,IAAIxc;gBACpB,IAAIohB,OAAOngB,KAAKmiB,QAAQ5G;gBAExB,IAAI4E,QAAQA,KAAK0gC,UAAU7gD,KAAKpB,SAAS2oD,YAAYsC,sBAAsB;oBACvE7pD,KAAKkkB,aAAaqF,YAAYhO;wBAC1BuuC,QAAQ3pC,KAAK0gC;;;gBAIrB7gD,KAAKilD,QAAQ5lD,UAAU2zB,UAAUjzB,MAAMC,MAAMT;gBAC7CS,KAAK+pD,WAAWxuC,IAAIxc;;YAIxBm0B,cAAc,SAAS3X;gBAEnB,IAAIvb,KAAKgnD,0BAA0B;oBAC/BhnD,KAAKklD,YAAYkE,qBAAqB7tC;oBACtCvb,KAAKklD,YAAYiE,aAAa5tC;oBAG9B,KAAKvb,KAAK+mD,wBAAwB;wBAC9B/mD,KAAKqnD,2BAA2B2C,WAAWhqD,KAAKklD,YAAY4D,aAAavtC;;;;YAMrF6P,aAAa,SAAS7P,IAAIxc,MAAMmsB,QAAQC;gBACpCnrB,KAAKilD,QAAQ5lD,UAAU+rB,YAAYrrB,MAAMC,MAAMT;gBAE/CS,KAAKklD,YAAY+E,eAAe1uC,IAAI2P,QAAQC;gBAE5C,IAAIA,UAAU,KAAK/mB,KAAKC,MAAM6mB,SAASC,QAAQ,SAAS,KAAK;oBACzDnrB,KAAKklD,YAAYgF,WAAW3uC;oBAC5Bvb,KAAKklD,YAAYuE,UAAUluC;oBAC3Bvb,KAAKklD,YAAYiF,aAAa5uC;oBAC9Bvb,KAAKklD,YAAYoE,cAAc/tC,IAAIvb,KAAKpB,SAASiH,KAAKukD;oBAGtDpqD,KAAKqqD,iBAAiB9uC;uBAErB;oBAEDvb,KAAKqqD,iBAAiB9uC,IAAI2P,QAAQC;;;YAI1CwI,kBAAkB,SAASzI,QAAQC;gBAC/BnrB,KAAKilD,QAAQ5lD,UAAUs0B,iBAAiB5zB,MAAMC,MAAMT;gBACpDS,KAAKklD,YAAY7I,oBAAoBnxB,QAAQC;;YAGjDG,aAAa,SAAS/P,IAAIxc,MAAMoG,QAAQoQ;gBACpC,IAAI+0C,eAAetqD,KAAKilD,QAAQ5lD,UAAUisB,YAAYvrB,MAAMC,MAAMT,YAC9DkoD,aAAaznD,KAAKklD,aAClB7kC,gBAAgBonC,WAAW/B,iBAAiBnqC,KAC5CzZ,OAAO9B;gBAEX,SAASuqD,eAAeplD;oBAGpB,KAAKkb,eAAe;wBAChB;;oBAGJonC,WAAW6B,cAAc/tC;oBAEzBxd,GAAGsiB,eAAevb,YAAYhD,KAAKynD,SAASC;oBAC5C/B,WAAW0C,aAAa5uC;oBAExB,IAAIzZ,KAAKmhB;wBAAY1H,IAAIA;uBAAKK,WAAW7d,GAAG6d,OAAOyC,eAAe;wBAC9DopC,WAAWyC,WAAW3uC;;oBAE1BksC,WAAWkC,YAAYpuC;oBAEvB,IAAIpW,OAAOiI,SAAS;wBAChBtL,KAAK0oD,sBAAsBjvC;2BAE1B;wBACDxd,GAAGsiB,eAAexb,SAAS/C,KAAKynD,SAASkB;wBACzChD,WAAWiD,WAAWnvC;wBAEtB,IAAIksC,WAAWkD,sBAAsB7oD,KAAKiiB,gBAAgBxI,KAAK;4BAC3Dxd,GAAGsiB,eAAexb,SAAS/C,KAAKynD,SAASrN;4BACzCuL,WAAWmD,UAAUrvC;;wBAEzBzZ,KAAK+oD,2BAA2BtvC,IAAIpW;;;gBAK5C,IAAImlD,wBAAwBvsD,GAAGmP,SAAS;oBACpCo9C,aAAa7xC,KAAK,SAASqyC;wBACvBP,eAAeO;;uBAIlB;oBACDP,eAAeplD;;gBAGnB,OAAOmlD;;YAGXE,uBAAuB,SAASjvC;gBAC5B,IAAIksC,aAAaznD,KAAKklD;gBAEtB,IAAIllD,KAAK6vB,qBAAqB;oBAC1B43B,WAAWsD,iBAAiBxvC;;gBAGhCxd,GAAG0pD,WAAW/B,iBAAiBnqC,KAAK1W,SAAS7E,KAAKupD,SAASn8C;gBAE3DpN,KAAKgrD,sBAAsBzvC;;YAG/BoQ,eAAe,SAASpQ;gBACpBvb,KAAKilD,QAAQ5lD,UAAUssB,cAAc5rB,MAAMC,MAAMT;gBACjDS,KAAKklD,YAAY+F,YAAY1vC;;YAGjCsQ,WAAW,SAAStQ,IAAIxc;gBACpB,IAAIurD,eAAetqD,KAAKilD,QAAQ5lD,UAAUwsB,UAAU9rB,MAAMC,MAAMT;gBAEhES,KAAKklD,YAAY+F,YAAY1vC;gBAE7B,OAAO+uC;;YAGXt+B,gBAAgB,SAASzQ,IAAIwQ;gBACzB/rB,KAAKilD,QAAQ5lD,UAAU2sB,eAAejsB,MAAMC,MAAMT;gBAIlD,IAAIwsB,UAAU+L,YAAY,KAAK93B,KAAKwgB,SAASyjB,YAAY1oB,KAAK;oBAC1Dvb,KAAKklD,YAAYgG,WAAW3vC;;;YAIpCkQ,WAAW,SAASlQ,IAAIxc;gBACpBiB,KAAKilD,QAAQ5lD,UAAUosB,UAAU1rB,MAAMC,MAAMT;gBAC7CS,KAAK0mD,gBAAgBnrC;gBAErB,IAAIvb,KAAK6tB,sBAAsB,GAAG;oBAC9B7tB,KAAKklD,YAAY0E;;;YAIzBp3B,oBAAoB,SAASjX;gBACzB,IAAI4vC,oBAAoBC,SAASC;gBAEjCrrD,KAAKilD,QAAQ5lD,UAAUmzB,mBAAmBzyB,MAAMC,MAAMT;gBAEtDS,KAAKsrD,gBAAgB/vC;gBAErB,IAAIvb,KAAKpB,SAAS8lB,MAAM6mC,mBAAmB;oBACvCJ,qBAAqBnrD,KAAK6jB,aAAatI;oBACvC6vC,UAAUprD,KAAKpB,SAAS8lB,MAAMwQ;oBAE9Bm2B,YAAYrrD,KAAKpB,SAAS8lB,MAAM8mC,cAAczmD,QAAQ,iBAAiBomD;oBACvEE,YAAYA,UAAUtmD,QAAQ,gBAAgBqmD;oBAE9CprD,KAAKklD,YAAYoE,cAAc/tC,IAAI8vC;oBACnCttD,GAAGiC,KAAKklD,YAAYQ,iBAAiBnqC,KAAK1W,SAAS7E,KAAKupD,SAASC;;;YAKzEv4B,sBAAsB,SAAS1V;gBAC3B,IAAIvb,KAAKilD,QAAQ5lD,UAAU4xB,qBAAqBlxB,MAAMC,MAAMT,YAAY;oBACpES,KAAKklD,YAAYuG,cAAclwC;oBAC/Bxd,GAAGiC,KAAKklD,YAAYQ,iBAAiBnqC,KAAKzW,YAAY9E,KAAKupD,SAASkB;oBACpEzqD,KAAKklD,YAAYoE,cAAc/tC;oBAC/Bvb,KAAKklD,YAAY+F,YAAY1vC;oBAC7Bvb,KAAKsrD,gBAAgB/vC;oBACrB,OAAO;uBAEN;oBACDxd,GAAGiC,KAAKklD,YAAYQ,iBAAiBnqC,KAAK1W,SAAS7E,KAAKupD,SAASrN;oBACjEl8C,KAAKklD,YAAY0F,UAAUrvC;oBAC3B,OAAO;;;YAIf6F,iBAAiB,SAAS7F;gBACtB,IAAI8X,oBAAoBt1B,GAAG+S,KAAK9Q,KAAK0rD,wBAAwB1rD;gBAE7DA,KAAKilD,QAAQ5lD,UAAU+hB,gBAAgB9hB,KAAKU,MAAMub,IAAI8X;;YAG1Dq4B,wBAAwB,SAASnwC,IAAIG,MAAM4X;gBACvC,IAAItzB,KAAKpB,SAASuiB,WAAWwqC,cAAc;oBACvC3rD,KAAK4rD,mBAAmB7rD,MAAMC,MAAMT;uBAEnC;oBACDS,KAAK6rD,mBAAmB9rD,MAAMC,MAAMT;;;YAI5CyoB,mBAAmB,SAASzM,IAAIhG,KAAKwS;gBACjC/nB,KAAKilD,QAAQ5lD,UAAU2oB,kBAAkBjoB,MAAMC,MAAMT;gBAErDS,KAAKklD,YAAYyE,YAAYpuC;gBAE7B,IAAIwM,SAAS;oBACT/nB,KAAKklD,YAAYoE,cAAc/tC,IAAIvb,KAAKpB,SAASuiB,WAAW2qC;oBAC5D9rD,KAAKklD,YAAY6F,iBAAiBxvC;uBAEjC;oBACDvb,KAAK0mD,gBAAgBnrC;;;YAI7BswC,oBAAoB,SAAStwC,IAAIG,MAAM4X;gBACnCtzB,KAAKklD,YAAY6G,iBAAiBxwC;gBAClCvb,KAAKklD,YAAY+F,YAAY1vC;gBAC7Bvb,KAAKklD,YAAYoE,cAAc/tC,IAAIvb,KAAKpB,SAASuiB,WAAW6qC;gBAC5DhsD,KAAKyzB,eAAeC,WAAW3zB,MAAMC,MAAMT;;YAG/CqsD,oBAAoB,SAASrwC,IAAIG,MAAMme;gBAEnC,IAAI3mB,WAAWlT,KAAKihB,QAAQ1F,KACxB0wC,iBAAiBjsD,KAAKpB,SAASuiB,WAAW8qC,eAAelnD,QAAQ,iBAAiBmO,WAClFwI,OAAO1b,KAAK0jB,QAAQnI,KACpB2wC,oBAAoB3sD,WACpBuC,OAAO9B,MACPuB;gBAEJA,SAASvB,KAAKpB,SAASutD,YAAYF;gBAEnC,IAAIluD,GAAG+Z,iBAAiBvW,SAAS;oBAC7BA,OAAOyW,KAAK;wBACRlW,KAAK+pD,mBAAmB9rD,MAAM+B,MAAMoqD;;uBAGvC,IAAI3qD,WAAW,OAAO;oBACvBO,KAAK+pD,mBAAmB9rD,MAAM+B,MAAMoqD;;;YAI5CnC,YAAY,SAASxuC,IAAIxc,MAAMqtD;gBAC3B,IAAIC,aACAC,eAAe,GACfC,cAAcvsD,KAAKwgB,SAASwjB,UAAUzoB,OAAOvb,KAAKpB,SAAS0Y,QAAQk1C,YACnElV;gBAEJ,IAAIt3C,KAAKpB,SAASoE,QAAQypD,cAAc;oBACpC,IAAIzsD,KAAK4lD,qBAAqB,KAAK5lD,KAAK6lD,yBAAyB,GAAG;wBAChEyG,eAAetsD,KAAK6lD,yBAAyB;;oBAGjDwG;wBACIpqD,OAAOqqD;;;gBAIf,KAAKF,QAAQ;oBACT,IAAIpsD,KAAKpB,SAASw3B,gCAAgCr4B,GAAGgW,kBAAkBqC,eAAe;wBAClFpW,KAAKklD,YAAYwH;;oBAMrB,KAAK1sD,KAAKpB,SAASuM,UAAU;wBACzBmsC,SAASt3C,KAAKijB;4BAAY1H,IAAIA;;wBAE9Bvb,KAAK2sD,qBAAqB3sD,KAAK2sD,sBAAsBrV,OAAO96B;wBAE5D,IAAI86B,OAAO96B,iBAAiBxc,KAAK2sD,uBAAuBrV,OAAO96B,cAAc;4BACzExc,KAAKwgB,SAASC;4BACdzgB,KAAK4sD;4BACL5sD,KAAK2sD,qBAAqB;;;;gBAKtC,IAAIP,QAAQ;oBACRpsD,KAAKklD,YAAY2H,eAAetxC,IAAIvb,KAAKpB,SAASiyB,eAAe9xB,OAAOstD,aAAaE;oBACrFvsD,KAAKklD,YAAY4H,gBAAgBvxC,IAAIvb,KAAKiiB,eAAe1G,KAAK,MAAMvb,KAAKpB,SAASmuD,WAAWt0B;uBAE5F;oBACDz4B,KAAKklD,YAAYhpC,QAAQX,IAAIvb,KAAKpB,SAASiyB,eAAe9xB,OAAOstD,aAAaE;oBAC9EvsD,KAAKklD,YAAY8H,gBAAgBzxC,IAAIvb,KAAKmiB,QAAQ5G,KAAKvb,KAAKpB,SAASmuD,WAAWt0B;;gBAGpFz4B,KAAK6lD,0BAA0B;gBAE/B,IAAIuG,UACCpsD,KAAKpB,SAASoE,QAAQiqD,oBAAoBlvD,GAAGgW,kBAAkBqC,eAAgB;oBAEhFpW,KAAKqqD,iBAAiB9uC;;;YAI9BqxC,YAAY;gBACR5sD,KAAKklD,YAAYE;gBACjBplD,KAAK4gB;;YAGTypC,kBAAkB,SAAS9uC,IAAI2xC,YAAYrR;gBACvC,IAAIv/B,OAAOtc,KAAKmjB,QAAQ5H,KACpB4xC,iBAAiBntD,KAAK6sB,YAAYvQ;gBAEtC,IAAIA,QAAQ,GAAG;oBACX,IAAI4wC,eAAe7uD,aAAaw9C,cAAcx9C,WAAW;wBACrD8uD,iBAAiBntD,KAAKotD,gBAAgBF,YAAYrR;;oBAGtD77C,KAAKklD,YAAY5nC,WAAW/B,IAAI4xC;;;YAIxCC,iBAAiB,SAASC,cAAcxR;gBACpC,IAAIz7C,UAAUJ,KAAKpB,SAASiH,KAAKynD;gBACjC,SAAS/+C,EAAExP,MAAM4xB;oBAAevwB,UAAUA,QAAQ2E,QAAQhG,MAAM4xB;;gBAEhEpiB,EAAE,aAAanK,KAAKC,MAAMgpD,eAAexR,YAAY;gBACrDttC,EAAE,gBAAgBvO,KAAK6sB,YAAYgvB;gBACnC,OAAOz7C;;YAGXyqD,4BAA4B,SAAStvC,IAAIiW;gBACrC,IAAI+7B,MAAMC,kBAAkBC;gBAE5BF,OAAOvtD,KAAKpB,SAAS8uD,wBAAwBH;gBAC7CC,mBAAmBxtD,KAAKpB,SAAS8uD,wBAAwBF;gBAEzD,IAAID,SAAS,UAAU;oBACnBE,gBAAgBj8B,SAASg8B;oBACzB,KAAKC,eAAe;wBAChBA,gBAAgBztD,KAAKpB,SAASiH,KAAK8nD;;oBAGvC3tD,KAAKklD,YAAYoE,cAAc/tC,IAAIkyC;oBAEnC,IAAIztD,KAAKpB,SAAS8uD,wBAAwBE,eAAe;wBACrD5tD,KAAK6tD,aAAatyC,IAAIkyC;;uBAGzB,IAAIF,SAAS,WAAW;oBACzBvtD,KAAKklD,YAAYoE,cAAc/tC,IAAIvb,KAAKpB,SAASiH,KAAK8nD;uBAErD,IAAIJ,SAAS,QAAQ;oBACtBvtD,KAAKG,IAAI,4CAA4CotD,OAAO,kBAAkB;;;YAItFM,cAAc,SAAStyC,IAAI1V;gBACvB7F,KAAKklD,YAAYQ,iBAAiBnqC,IAAIhC,QAAQ1T;;YAGlDylD,iBAAiB,SAAS/vC;gBACtB,KAAKvb,KAAKpB,SAASw3B,+BAA+Br4B,GAAGgW,kBAAkBqC,eAAe;oBAClFpW,KAAKklD,YAAYwF,WAAWnvC;;;YAIpC4K,YAAY,SAASiK,MAAMrxB,MAAMiK;gBAC7B,IAAI5I,UAAUJ,KAAKilD,QAAQ5lD,UAAU8mB,WAAWpmB,MAAMC,MAAMT;gBAC5DS,KAAKpB,SAASkvD,YAAY1tD;;YAG9B0mB,aAAa,SAAS1mB;gBAClBJ,KAAKilD,QAAQ5lD,UAAUynB,YAAY/mB,MAAMC,MAAMT;gBAC/CS,KAAKpB,SAASkvD,YAAY1tD;;YAG9B2tD,mBAAmB;gBACf,IAAIjsD,OAAO9B;gBAEXA,KAAKpB,SAASF,UAAU6pB,kBAAkB;oBACtC,IAAInoB,UAAU0B,KAAKlD,SAASwpB,MAAM4lC,mBAC9BC,aAAansD,KAAKlD,SAASwpB,MAAM5I;oBAErC,OAAO1d,KAAKlD,SAASsvD,WAAW9tD,SAAS6tD;;;YAIjDrhC,qBAAqB,SAASrR,IAAIxc;gBAC9BiB,KAAK4lD,sBAAsB;gBAC3B5lD,KAAKilD,QAAQ5lD,UAAUutB,oBAAoB7sB,MAAMC,MAAMT;;YAG3D+gB,wBAAwB,SAAS3U,OAAOpO,QAAQqhB;gBAC5C5e,KAAK4lD,qBAAqBj6C,MAAMxJ;gBAChCnC,KAAK6lD,yBAAyB;gBAC9B7lD,KAAKilD,QAAQ5lD,UAAUihB,uBAAuBvgB,MAAMC,MAAMT;;YAG9DyrD,uBAAuB,SAASvpC;gBAC5B,IAAIgF,eAAezmB,KAAKiiB,eAAeR,SACnC0sC,aAAanuD,KAAKijB;oBAAY1H,IAAIkG;mBAAS7F;gBAE/C,IAAIuyC,eAAepwD,GAAG6d,OAAO4C,YACxBiI,gBACDzmB,KAAKpB,SAASmuD,WAAWqB,aAAaC,sBACrCtwD,GAAGgW,kBAAkBiD,gBAAgB;oBAItChX,KAAKklD,YAAY4H,gBAAgBrrC,QAAQgF,cAAczmB,KAAKpB,SAASmuD,WAAWt0B;;;YAIxFxZ,gBAAgB,SAASqH;gBACrB,IAAI/K,KAAKvb,KAAKilD,QAAQ5lD,UAAU4f,eAAelf,MAAMC,MAAMT;gBAE3DS,KAAK+pD,WAAWxuC,IAAIvb,KAAKihB,QAAQ1F,KAAK;gBACtCvb,KAAKklD,YAAYyE,YAAYpuC;gBAC7Bvb,KAAKklD,YAAYgF,WAAW3uC;gBAC5Bvb,KAAKwqD,sBAAsBjvC;gBAE3B,OAAOA;;YAGXiR,UAAU,SAASjR,IAAIgC;gBACnBvd,KAAKilD,QAAQ5lD,UAAUmtB,SAASzsB,MAAMC,MAAMT;gBAE5CS,KAAKklD,YAAY5nC,WAAW/B,IAAIvb,KAAK6sB,YAAYtP;;YAGrDuX,yBAAyB;gBACrB90B,KAAKklD,YAAYC;gBACjBnlD,KAAKilD,QAAQ5lD,UAAUy1B,wBAAwB/0B,MAAMC,MAAMT;;;;IC7sBvExB,GAAGC,eAAe,SAAS+a,GAAGrb;QAC1B;QAEA,IAAIoE,OAAO9B;QAKXA,KAAKilD,UAAUvnD,YAAYK,GAAGL,WAAWy4B,oBAAoBp4B,GAAGo4B;QAChEn2B,KAAKilD,QAAQllD,MAAMC,MAAMT;QAGzBxB,GAAGuG,OAAOtE,KAAKpB;YACX6B,SAAS;YAETwjB,QAAQ;YAERqqC,aAAa;YAEb/G;gBACIC;gBACAqC,sBAAsB;;YAG1BhkD;gBACIynD,gBAAgB;gBAChBK,YAAY;gBACZvD,oBAAoB;gBACpB5iB,QAAQ;;YAGZ+mB,UAAU;YAEVnkC;gBACIo/B,UAAU;gBACVtN,WAAW;gBACX9uC,SAAS;gBACTq9C,MAAM;gBACN+D,UAAU;gBACV1rD,MAAM;gBACNm9C,YAAY;;YAGhByN;gBACIH,MAAM;gBACNC,kBAAkB;gBAClBI,eAAe;;YAGnBt9B;gBACIm+B,mBAAmB;gBACnBC,oBAAoB;;YAGxBhqC;gBACI6mC,mBAAmB;gBACnBC,eAAe;;YAGnBrqC;gBACIwqC,cAAc;gBACdM,gBAAgB;gBAChBD,oBAAoB;gBACpBF,oBAAoB;;YAIxB9oD;gBACIiqD,kBAAkB;gBAClBR,cAAc;;YAGlBrkC;gBACIumC,eAAe;gBACfX,mBAAmB;;YAGvBjB;gBACIt0B,eAAe;gBACfm2B,UAAU;gBACVR;oBACIC,mBAAmB;oBACnBQ,kBAAkB;oBAClBC,aAAa;;gBAEjBC,mBAAmB;;YAGvBz3C;gBACIk1C,YAAY;;YAGhBsB,aAAa,SAAS1tD;gBAClB,IAAI0B,KAAKojD,YAAY8J,UAAU,UAAU;oBACrC,OAAOltD,KAAKojD,YAAY+J,WAAW,SAAS7uD;uBAE3C;oBACDupB,WAAW;wBACP3iB,OAAOqqB,MAAMjxB;uBACd;;;YAIX+rD,aAAa,SAAS/rD;gBAClB,IAAI0B,KAAKojD,YAAY8J,UAAU,YAAY;oBACvC,OAAOltD,KAAKojD,YAAY+J,WAAW,WAAW7uD;uBAE7C;oBACD,OAAO4G,OAAOkoD,QAAQ9uD;;;YAI9B8tD,YAAY,SAAS9tD,SAAS+uD;gBAC1B,IAAIrtD,KAAKojD,YAAY8J,UAAU,WAAW;oBACtC,OAAOltD,KAAKojD,YAAY+J,WAAW,UAAU7uD,SAAS+uD;uBAErD;oBACD,OAAOnoD,OAAOooD,OAAOhvD,SAAS+uD;;;WAGvC;QAGHpxD,GAAGuG,OAAOtE,KAAKpB,UAAUma,GAAG;QAE5B/Y,KAAKklD,cAAc,IAAInnD,GAAGsxD;YACtBlvD,KAAKpC,GAAG+S,KAAK9Q,KAAKG,KAAKH;YACvBsvD,gBAAgBtvD,KAAKpB,SAAS2vD;YAC9BgB,aAAavvD,KAAKpB,SAAS6B;YAC3B+uD,iBAAiBxvD,KAAKpB,SAAS0vD;YAC/BrqC,QAAQjkB,KAAKpB,SAASqlB;YACtBy0B,gBAAgB14C,KAAKgiB;YACrBoI;gBACItnB,MAAM9C,KAAKpB,SAASwrB,QAAQtnB;gBAC5B0rD,UAAUxuD,KAAKpB,SAASwrB,QAAQokC;;YAEpC/Z;gBACIgb,WAAWzvD,KAAKpB,SAASmuD,WAAW6B;gBACpCG,mBAAmB/uD,KAAKpB,SAASmuD,WAAWgC;;YAEhDX;gBACIsB,iBAAiB1vD,KAAKpB,SAASmuD,WAAWqB,aAAaC;gBACvDsB,uBAAuB3vD,KAAKpB,SAASmuD,WAAWqB,aAAaS;gBAC7De,qBAAqB5vD,KAAKpB,SAASmuD,WAAWqB,aAAaU;;YAE/DjpD,MAAM7F,KAAKpB,SAASiH;;QAGxB,IAAI7F,KAAKpB,SAASqrB,YAAYmH,qBAAqBrzB,GAAG+R,YAAY/R,GAAGiS,aAAa;YAC9EhQ,KAAKklD,YAAY2K,cAAc7vD,KAAKpB,SAAS0xB,SAASgB;eAErD,KAAKvzB,GAAGgW,kBAAkB0D,aAAczX,KAAKpB,SAAS8oB,KAAKoI,aAAa/xB,GAAGgW,kBAAkB2D,YAAa;YAC3G1X,KAAKklD,YAAY2K,cAAc7vD,KAAKpB,SAAS0xB,SAASo+B;eAErD;YACD1uD,KAAK61B;YAEL71B,KAAKklD,YAAY7W;YAEjBruC,KAAKupD,WAAWvpD,KAAKpB,SAASwrB;YAE9B,KAAKpqB,KAAKpB,SAASqlB,UAAUjkB,KAAKklD,YAAY1iC,aAAa;gBACvDxiB,KAAKwtB,mBAAmBxtB,KAAK4pB;oBACzBnpB,SAAST,KAAKklD,YAAY1iC;oBAC1BjJ,OAAOvZ,KAAKpB,SAASiH,KAAK6kB;mBAC3BlQ;;YAGPxa,KAAK8lD;YAEL,IAAI/nD,GAAGyE,eAAezE,GAAGgW,kBAAkB8C,UAAU;gBACjD7W,KAAKslD,OAAOtlD,KAAK2lD;;YAGrB,IAAI3lD,KAAKpB,SAASwpB,MAAMD,iBAAiBnoB,KAAKpB,SAASwpB,MAAMumC,eAAe;gBACxE,IAAI5wD,GAAGmqB,cAAc;oBACjBloB,KAAK+tD;uBAEJ;oBACD/tD,KAAKG,IAAI,mCAAmC;;;YAIpDH,KAAK4lD,qBAAqB;YAC1B5lD,KAAK6lD,yBAAyB;;;IAKtC9nD,GAAGuG,OAAOvG,GAAGC,aAAaqB,WAAWtB,GAAG0gB;IACxC1gB,GAAGuG,OAAOvG,GAAGC,aAAaqB,WAAWtB,GAAGsoB;IAGxCtoB,GAAGuG,OAAOvG,GAAGC,aAAaqB,WAAWtB,GAAGinD;IACxCjnD,GAAGuG,OAAOvG,GAAGC,aAAaqB,WAAWtB,GAAG0oD;IC5LxC1oD,GAAGsxD,aAAa,SAASlzC;QACrB;QAEA,IAAI2zC,eAAe,cACfC,oBAAoB,eACpBC,0BAA0B,eAC1BC,8BAA8B,mBAE9BC,qBAAqB,oBACrBC,sBAAsB,qBACtBC,oBAAoB,kBACpBC,uBAAuB,qBACvBC;YACIC,SAAStlD,SAASulD;YAClBC;WAEJC,mBAAmB,OACnBC,sBAAsB,GACtBC,+BAA+B,OAC/BC,2BACAC,oBAAoB,GACpB9zD;YACImD,KAAK;YACLs0C;gBACIgb,WAAW;gBACXV,mBAAmB;;YAEvBO,gBAAgB;YAChBC,aAAa;YACbC,iBAAiB;YACjBvrC,QAAQ;YACRy0B,gBAAgB;YAChBtuB;gBACItnB,MAAM;gBACN0rD,UAAU;;YAEdJ;gBACIsB,iBAAiB;gBACjBC,uBAAuB;gBACvBC,qBAAqB;;YAEzB/pD;gBACI2hC,QAAQ;;WAGhBupB;YACI9sC,QAAQ;YACR+sC,aAAa;YACbC,oBAAoB;YACpBC,eAAe;YACfC,eAAe;YACfC,gBAAgB;YAChBC,cAAc;YACdh0D,UAAU;YACVi0D,MAAM;YACNC,MAAM;YACNC,sBAAsB;YACtBp6C,aAAa;YACbq6C,2BAA2B;YAC3BC,kBAAkB;YAClBvxC,MAAM;YACNwxC,SAAS;YACTr1C,MAAM;YACNiE,QAAQ;YACRpJ,OAAO;YACPy6C,gBAAgB;YAChBC,cAAc;YACdntC,OAAO;YACPotC,YAAY;YACZC,mBAAmB;YACnBC,cAAc;YACdC,UAAU;YACVC,gBAAgB;YAChBC,uBAAuB;YACvBC,WAAW;WAEfC,wBACAC,iCAAiC,IAAIv0D,GAAGmP,WACxCqlD,+BAA+B,IAAIx0D,GAAGmP,WACtC/M,KACAqyD,qBACAC,qBACAC,cACAtwC,WACA8M,UACAyjC,gBACAC,aAKAC,6BAA6B;YACzB,IAAIC,kBAAmB91D,QAAQoxD,aAAauB,uBACxCoD,aAAa/1D,QAAQoxD,aAAawB,qBAClCzzC;gBACIwF,SAASmvC;gBACT5uC,OAAO0wC;;YAGf,IAAID,gBAAgB;gBAChB,IAAIG,iBAAiB;oBACjB91D,QAAQ07C,eAAer2B,SAASywC,iBAAiB,IAAIhlB,SAAS3xB,MAAMnE,KAChE,SAASg7C;wBACLV,+BAA+BllD,QAAQ4lD;uBAE3C;wBACIV,+BAA+BhlD;wBAC/BnN,IAAI,0DAA0D2yD,iBAAiB;;uBAItF;oBACDR,+BAA+BhlD;;gBAGnC,IAAIylD,YAAY;oBACZ/1D,QAAQ07C,eAAer2B,SAAS0wC,YAAY,IAAIjlB,SAAS3xB,MAAMnE,KAC3D,SAASg7C;wBACLT,6BAA6BnlD,QAAQ4lD;uBAEzC;wBACIT,6BAA6BjlD;wBAC7BnN,IAAI,kEAAkE4yD,YAAY;;uBAIzF;oBACDR,6BAA6BjlD;;;WAOzC2lD,oBAAoB,SAASb;YACzB,IAAIc,sBAAsB,IAAIn1D,GAAGmP;YAEjCqlD,6BAA6Bv6C,KAAK,SAASoyB;gBACvC+oB,4BAA4B/oB,KAAKgoB;gBAEjC,KAAKA,UAAUlkB,KAAK;oBAChBkkB,UAAUlkB,MAAM9D,IAAI8D;oBACpBkkB,UAAUjlD,SAAS;wBACfilD,UAAUjlD,SAAS;wBACnBimD,KAAKhB;wBACLc,oBAAoB9lD;;uBAGvB;oBACD8lD,oBAAoB9lD;;eAEzB;gBAICtK,KAAKsvD;gBACLc,oBAAoB9lD;;YAGxB,OAAO8lD;WAGXG,qBAAqB,SAAS93C,IAAI3O,MAAMuP;YACpC,IAAIi2C,YAAYkB,aAAa/3C;YAE7Bpb,IAAI,kCAAkCob;YACtC3O,KAAK2mD,gBAAgBh4C;YAErB,OAAOve,QAAQ07C,eAAer2B,SAASzV,MAAMwlD,WAAWj2C,MAAMnE,KAC1D;gBACI24C;gBACAyC,KAAKhB;gBACLC,kBAAkB92C,IAAInO;eAE1B;gBACIilD,kBAAkB92C,IAAIjO;gBAItB,KAAKtQ,QAAQoxD,aAAasB,iBAAiB;oBACvC8D,+BAA+Bj4C,IAAI62C;;;WAKnDqB,4BAA4B;YACxB,IAAI5C,qBAAqB1uD,QAAQ;gBAC7ByuD,+BAA+B;gBAE/B,IAAI8C,qBAAqB7C,qBAAqBt9C;gBAE9C,IAAImgD,mBAAmBC,QAAQ;oBAC3BC,kCAAkCF;uBAEjC;oBACDG,+BAA+BH;;mBAGlC;gBACD9C,+BAA+B;;WAIvCkD,YAAY,SAASv4C;YACjB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBxwC;WAGtDyzC,cAAc,SAASz4C;YACnB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBa;WAGtDqC,YAAY,SAAS/yD;YACjB,OAAO6yD,cAAc3xC,WAAW2uC,gBAAgB7vD,OAAO;WAG3DgzD,YAAY,SAAS34C;YACjB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBc;WAGtDsC,oBAAoB;YAChB,OAAOJ,cAAc3xC,WAAW2uC,gBAAgBmB;WAGpDkC,cAAc,SAAS74C;YACnB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBiB;WAGtD7vC,UAAU,SAAS5G;YACf,OAAO+0C,UAAUG,IAAIl1C,OAAOxd,GAAGmxB,UAAU3pB,gBAAgBwqD,oBAAoBx0C;WAGjFvI,cAAc,SAASuI;YACnB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgB5wC;WAGtDk0C,WAAW,SAAS94C;YAChB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgB55C;WAGtDm9C,cAAc,SAAS/4C;YAGnB,IAAIA,MAAM,MAAM;gBACZ,OAAOw4C,cAAc3xC,WAAW2uC,gBAAgBU,8BAC5CsC,cAAc3xC,WAAW2uC,gBAAgBW;;YAIjD,OAAOqC,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBS,yBAC9CuC,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgB35C;WAGnDm9C,WAAW,SAASh5C;YAChB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBrsC;WAGtDvB,UAAU,SAAS5H;YACf,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBz0C;WAGtDk4C,aAAa,SAASj5C;YAClB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBY;WAGtDoC,gBAAgB,SAAS/iD,SAASyjD;YAC9B,OAAOzjD,WAAWjT,GAAGiT,SAASzL,gBAAgBkvD;WAGlDnB,eAAe,SAAS/3C;YACpB,OAAOo3C,kBAAkBoB,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBqB;WAGxEtvD,OAAO,SAASZ;YACZA,MAAMnE,GAAGmE,IAAI2C,SAAS7H,QAAQotB,QAAQtnB;WAM1CqwD,8BAA8B,SAASniC,aAAaohC;YAChD,IAAI17B,WAAW1F,YAAYjuB,MAAM2zB,UAC7BD,YAAYzF,YAAYjuB,MAAM0zB;YAElC,IAAIA,aAAaC,aAAa07B,UAAUrvD,MAAM2zB,aAAa07B,UAAUrvD,MAAM0zB,WAAW;gBAClF14B,GAAGq0D,WAAWruD;oBACV2yB,UAAUA;oBACVD,WAAWA;;;WAQvB+8B,iCAAiC,SAASj4C,IAAI62C;YAC1C,IAAIsC,aAAarC,kBAAkB92C,OAAO,IAAIxd,GAAGmP,UAAUI,WACvDqnD,2BAA2B,IAAI52D,GAAGmP;YAEtColD,+BAA+Bt6C,KAAK,SAASoyB;gBACzCsqB,WAAW18C,KACP;oBACI28C,yBAAyBvnD;mBAE7B;oBACI+lD,4BAA4B/oB,KAAKgoB;oBAEjCA,UAAUjlD,SAAS;wBACfilD,UAAUjlD,SAAS;wBACnBwnD,yBAAyBvnD;;oBAG7BglD,UAAUlkB,MAAM9D,IAAI8D;oBACpBklB,KAAKhB;;;YAKjB,OAAOuC;WAWXC,sBAAsB;YAClB,IAAIC,UACAC,YACAC,cACAC,gBACAC,cACAC,eACAjT,UACAmQ,WACAF,gBACAiD,YACAC;YAEJj1D,IAAI;YAGJ,IAAInD,QAAQsyD,kBAAkB,MAAM;gBAChC,MAAM,IAAIrrD,MAAM;;YAIpB,IAAIlG,GAAGmL,SAASlM,QAAQsyD,iBAAiB;gBACrCuF,WAAW5pD,SAASg6B,eAAejoC,QAAQsyD;gBAE3C,IAAIuF,aAAa,MAAM;oBACnB,MAAM,IAAI5wD,MAAMlG,GAAGyL,OAAO,2CAA2CxM,QAAQsyD;;gBAGjFwF,aAAaD,SAASrkD;mBAErB;gBACD,IAAIxT,QAAQsyD,eAAe9+C,cAAcnS,WAAW;oBAChD,MAAM,IAAI4F,MAAM,mEACZ;;gBAGR6wD,aAAa93D,QAAQsyD,eAAe9+C;;YAGxCskD,aAAa/2D,GAAGqL,QAAQ0rD;YACxBE,iBAAiB/pD,SAASC,cAAc;YACxC8pD,eAAe3iD,YAAYtU,GAAGsS,UAAUykD;YACxCM,aAAar3D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgB1zD;YAIhE,IAAIL,QAAQinB,QAAQ;gBAChBixC,gBAAgBn3D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgB9sC;gBACnE,IAAIixC,eAAe;oBACfn3D,GAAGm3D,eAAerxD;;;YAS1B,KAAK9F,GAAGyE,gBAAgBzE,GAAGgW,kBAAkB8C,UAAU;gBACnDq7C,iBAAiBn0D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgBmB;gBACpE,IAAIA,gBAAgB;oBAChBn0D,GAAGm0D,gBAAgBruD;;;YAI3Bo+C,WAAWlkD,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgBO;YAI9D,IAAIrP,aAAalkD,GAAGyE,aAAa;gBAC7BrC,IAAI,2BAA2B;gBAC/BpC,GAAGkkD,UAAUp+C;;YAGjB,KAAK9F,GAAGgW,kBAAkB8C,UAAU;gBAEhCu+C,WAAWz6C,gBAAgBw1C;gBAE3B,IAAIlO,YAAYlkD,GAAGkkD,UAAUh8C,aAAaiqD,qBAAqB;oBAI3DnyD,GAAGkkD,UAAUl+C;wBACTf,SAAS;;;mBAIhB,IAAIjF,GAAGq3D,YAAYnvD,aAAakqD,wBAAwBlO,UAAU;gBACnEkT,aAAap3D,GAAGkkD,UAAU18C,gBAAgBwrD,gBAAgBkB;gBAC1DkD,cAAcp3D,GAAGo3D,YAAYtxD;;YAKjCuuD,YAAYr0D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgBqB;YAC/D,KAAKO,gBAAgB;gBACjBP,aAAar0D,GAAGq0D,WAAWvuD;mBAE1B,IAAIuuD,WAAW;gBAChBtB,mBAAmB1uB,SAASgwB,UAAUhsD,aAAa4pD;gBAEnDc,mBAAmBA,mBAAmB,IAAIA,mBAAmB;gBAE7D8B,cAAc70D,GAAGq0D,WAAWnsD,aAAagqD;;YAE7C0C,iBAAiBA,kBAAkBP;YAEnCI,sBAAsBz0D,GAAGi3D,gBAAgBhwD,WAAW+rD,gBAAgBgB,mBAAmB5vD,SAAS;YAChGswD,sBAAsB10D,GAAGi3D,gBAAgBhwD,WAAW+rD,gBAAgBrsC,OAAOviB,SAAS;YAEpF4yD,eAAeh3D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgBQ;YAElE,IAAIwD,gBAAgB,MAAM;gBACtB,MAAM,IAAI9wD,MAAM;;YAGpBgxD,eAAeF,aAAavkD;YAC5BukD,aAAavkD,YAAY;YAGzB,IAAIwkD,eAAe1vD,qBAAqB,UAAUnD,QAAQ;gBACtD8I,SAASC,cAAc;;YAG3B/K,IAAI;YAEJ;gBACIouD,UAAUxwD,GAAGqL,QAAQ4rD,eAAexkD;gBACpC6kD,cAAct3D,GAAGqL,QAAQ6rD;;WAIjCK,cAAc,SAASpzD,IAAID,OAAOitB;YAC9B,IAAIqmC,WAAWrmC,UACXsmC,WAAWD,SAAS7vD;YAExB,IAAIzD,QAAQ,GAAG;gBACXuzD,WAAWz3D,GAAGw3D,UAAU/vD,WAAWvD,OAAO0D;;YAI9C4vD,SAAS7xD,aAAaxB,IAAIszD;WAG9B3B,iCAAiC,SAASH;YACtC,IAAIn4C,KAAKm4C,mBAAmBn4C,IACxBk6C,gBAAgB/B,mBAAmB+B,eACnCC,qBAAqBD,iBAAiBA,cAAclC,eACpDnB,YAAYkB,aAAa/3C,KACzBY;gBACI0F,sBAAsB6xC,mBAAmB7xC;gBACzCF,SAASmvC;gBACTn4B,QAAQ;gBACRzW,OAAO;;YAGf,IAAInkB,GAAGgW,kBAAkBiD,eAAe;gBACpC,IAAIo7C,WAAW;oBACX,IAAIp1D,QAAQy3C,OAAOgb,aAAazyD,QAAQy3C,OAAOgb,aAAakB,qBAAqB;wBAC7E6C,+BAA+Bj4C,IAAI62C;wBACnCqB;2BAEC;wBACDR,kBAAkBb,WAAW35C,KAAK;4BAC9B45C,kBAAkB92C,MAAM,IAAIxd,GAAGmP;4BAE/BmlD,kBAAkB92C,IAAI9C,KAAK;gCACvBkR,WAAW8pC,2BAA2Bz2D,QAAQy3C,OAAOsa;;4BAMzD,IAAI2G,sBAAsB,MAAM;gCAC5BC,iBAAiBp6C,IAAIm6C;mCAEpB;gCACDrC,mBAAmB93C,IAAIk6C,eAAet5C;;;;uBAMjD;oBACDs3C;;mBAGH,IAAIrB,WAAW;gBAChBa,kBAAkBb;gBAClBqB;;WAIRG,oCAAoC,SAASF;YACzC,IAAIn4C,KAAKm4C,mBAAmBn4C,IACxBkL,eAAeitC,mBAAmBjtC,cAClCmvC,iBAAiBlC,mBAAmBkC,gBACpCxD,YAAYkB,aAAa/3C,KACzBY;gBACI0F,sBAAsB6xC,mBAAmB7xC;gBACzCK,OAAO0wC;gBACPjxC,SAASmvC;;YAGjB,IAAIsB,WAAW;gBACX,IAAI3rC,cAAc;oBACd,IAAIzpB,QAAQy3C,OAAOgb,aAAazyD,QAAQy3C,OAAOgb,aAAakB,qBAAqB;wBAC7E6C,+BAA+Bj4C,IAAI62C;wBACnCqB;2BAEC;wBACD,IAAImC,gBAAgB;4BAChB3C,kBAAkBb;;wBAGtB,OAAOp1D,QAAQ07C,eAAer2B,SAASoE,cAAc2rC,WAAWj2C,MAAMnE,KAClE;4BACIo7C,KAAKhB;4BACLzB;4BACAhnC,WAAW8pC,2BAA2Bz2D,QAAQy3C,OAAOsa;2BAGzD;4BACIyE,+BAA+Bj4C,IAAI62C;4BACnCzoC,WAAW8pC,2BAA2Bz2D,QAAQy3C,OAAOsa;;;uBAKhE;oBACDyE,+BAA+Bj4C,IAAI62C;oBACnCqB;;;WAKZoC,sBAAsB,SAASt6C,IAAIu6C;YAC/B,IAAIC,MAAMzB,YAAY/4C,KAElBy6C,sBAAsBz6C,MAAM,OAAOw1C,gBAAgBW,mBAAmBX,gBAAgB35C;YAE1F,IAAI2+C,QAAQh4D,GAAGg4D,KAAKxxD,SAASyxD,sBAAsB;gBAC/CD,MAAMh4D,GAAGg4D,KAAKxwD,gBAAgBywD;;YAGlC,IAAID,KAAK;gBACLh4D,GAAGg4D,KAAKhyD;oBAAK2mC,OAAOorB,UAAU;;gBAC9BC,IAAI3jD,aAAa,iBAAiB0jD;;WAI1C1C,OAAO,SAASlxD;YACZA,MAAMnE,GAAGmE,IAAI4C,YAAY9H,QAAQotB,QAAQtnB;WAG7C6yD,mBAAmB,SAASM,mBAAmBC;YAC3C,IAAIC,kBAAkB7C,aAAa2C,oBAC/BG,kBAAkB9C,aAAa4C;YAEnC/1D,IAAIpC,GAAGyL,OAAO,sFAAsFysD,mBAAmBC,mBAAmBA;YAG1I7D,kBAAkB6D,mBAAmBl+C,KAAK;gBACtC24C;gBACA0B,kBAAkB4D,mBAAmB7oD;gBACrCjN,IAAIpC,GAAGyL,OAAO,wEAAwE0sD,mBAAmBD;gBACzGE,gBAAgBjoB,MAAMkoB,gBAAgBloB;gBACtCklB,KAAK+C;eAET;gBACI9D,kBAAkB4D,mBAAmB3oD;gBACrC,KAAKtQ,QAAQoxD,aAAasB,iBAAiB;oBACvC8D,+BAA+ByC,mBAAmBE;;;;QAKlEp4D,GAAGuG,OAAOtH,SAASmf;QACnBhc,MAAMnD,QAAQmD;QAId,KAAKpC,GAAGgW,kBAAkBiD,eAAe;YACrCha,QAAQy3C,OAAOsa,oBAAoB;YACnC/xD,QAAQy3C,OAAOgb,YAAY;;QAG/BrtC,YAAYplB,QAAQuyD;QACpBoD,iBAAiB31D,QAAQ07C,mBAAmBr6C;QAC5Cq0D,eAAekC;QAEf/B;QAEA90D,GAAGuG,OAAOtE;YACNquC,QAAQ;gBACJluC,IAAI;gBAEJwwD,sBAAsB;gBAEtBvuC,UAAU5R,YAAYkiD,aAAanE;gBACnCzrD,KAAKqxD;gBACLn0D,KAAKq2D;gBACLnnC,WAAWlyB,QAAQwyD,mBAAmBuE,cAAc3xC,WAAW2uC,gBAAgBQ;gBAE/EpxD,IAAI;;YAGR0vD,eAAe,SAASzvD;gBACpB,IAAIk2D,eAAev4D,GAAGsS,UAAUjQ;gBAChCgiB,UAAU5R,YAAY;gBACtB4R,UAAU/P,YAAYikD;;YAG1Bz7C,OAAO;gBACH7a,KAAKquC;;YAGT+W,YAAY;gBACRl2B,SAAS1e,YAAY;;YAGzBk8C,eAAe;gBACXgE,mBAAmB;;YAGvBx0C,SAAS,SAASX,IAAIxc,MAAMw3D,aAAaC,aAAaC;gBAClD,IAAIC,SAAS34D,GAAGsS,UAAUqiD,aAAa2C,eACnCsB,aAAa5C,cAAc2C,QAAQ3F,gBAAgB5wC,OACnDi1C,aAAarB,cAAc3xC,WAAW2uC,gBAAgB1zD,WACtDgjB,gBAAgBo2C,QAAQnG,UAAUC,UAAUrhC,UAC5C0nC;gBAEJ,IAAIH,OAAO;oBACPnG,UAAUG,IAAIl1C,MAAMm7C;;gBAGxB34D,GAAG24D,QAAQ7xD,SAASkrD,oBAAoBx0C;gBACxC65C,WAAWz6C,gBAAgBw1C;gBAE3B,IAAIwG,YAAY;oBACZ54D,GAAG44D,YAAY/wD,QAAQ7G;oBACvB43D,WAAWvkD,aAAa,SAASrT;;gBAGrC23D,OAAOtkD,aAAa09C,cAAcv0C;gBAElC,IAAIg7C,aAAa;oBACbjB,YAAYoB,QAAQH,YAAYt0D,OAAOoe;uBAEtC;oBACDA,cAAchO,YAAYqkD;;gBAG9B,IAAIF,aAAa;oBACbE,OAAO3zD,MAAMC,UAAU;oBACvBjF,GAAG24D,QAAQ7xD,SAASwrD;uBAEnB;oBACDvtD,KAAKwxD,YAAY/4C;oBACjBzY,KAAKqgB,QAAQ5H;oBACbzY,KAAKoxD,UAAU34C;oBACfzY,KAAKyxD,SAASh5C;oBACdzY,KAAKuxD,SAAS94C;oBACdzY,KAAKkxD,YAAYz4C;oBAEjB,IAAIm1C,kBAAkB;wBAClB1wD,KAAKkqD,WAAW3uC;;oBAGpBq7C,QAAQtD,aAAa/3C;oBACrB,IAAIq7C,UAAUA,MAAM1oB,KAAK;wBACrBqkB,6BAA6Bv6C,KAAK,SAAS6+C;4BACvCD,MAAM1oB,MAAM2oB,WAAW3oB;4BACvB,IAAI2oB,WAAW9zD,MAAM0zB,aAAaogC,WAAW9zD,MAAM2zB,UAAU;gCACzD34B,GAAG64D,OAAO7yD;oCACN0yB,WAAWogC,WAAW9zD,MAAM0zB;oCAC5BC,UAAUmgC,WAAW9zD,MAAM2zB;;;4BAInC08B,KAAKwD;;;;;YAMrB/J,gBAAgB,SAAStxC,IAAIxc,MAAMw3D,aAAaC;gBAC5Cx2D,KAAKkc,QAAQX,IAAIxc,MAAMw3D,aAAaC,aAAa;;YAGrDrR,eAAe;gBACXj2B,SAAS7c,YAAYi+C,UAAUC;gBAC/BD,UAAUC,UAAUtlD,SAASulD;gBAC7BF,UAAUG;;YAGd9J,YAAY,SAASprC;gBACjBxd,GAAGokB,QAAQ5G,KAAK1X;;YAGpByiD,WAAW,SAASpkD;gBAChB,IAAI40D,cAAc50D;gBAElB,IAAI40D,aAAa;oBAEb,OAAOA,YAAY1wD,aAAa0pD,iBAAiB,MAAM;wBACnDgH,cAAcA,YAAYlzD;;oBAG9B,OAAOw+B,SAAS00B,YAAY1wD,aAAa0pD;;;YAIjDiH,aAAa;gBACT,OAAO7nC;;YAGXk6B,sBAAsB,SAAS7tC;gBAC3B,IAAI3I,WAAWI,YAAYuI;gBAE3B3I,YAAY7U,GAAG6U,UAAU/N,SAAS7H,QAAQotB,QAAQokC;;YAGtDxI,gBAAgB,SAASzqC,IAAIxc;gBACzB,IAAIi4D,aAAahkD,YAAYuI;gBAE7B,IAAIy7C,YAAY;oBACZj5D,GAAGi5D,YAAYpxD,QAAQ7G;oBACvBi4D,WAAW5kD,aAAa,SAASrT;;;YAIzCiqD,cAAc,SAASztC;gBACnBzY,KAAKkQ,YAAYuI;;YAGrB2tC,cAAc,SAAS3tC;gBACnB63C,KAAKpgD,YAAYuI;;YAGrB07C,YAAY,SAAS/0D;gBACjB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgB5wC;;YAG3CqC,WAAW;gBACP,OAAOxlB,QAAQinB,UAAU8vC,cAAc3xC,WAAW2uC,gBAAgB9sC;;YAGtE4jC,oBAAoB;gBAChB/kD,KAAKqxD;;YAGTvM,oBAAoB;gBAChBwL,KAAKe;;YAGTxM,aAAa;gBACT,OAAOoM,cAAc3xC,WAAW2uC,gBAAgBO;;YAGpDjJ,wBAAwB;gBACpB,OAAOmK;;YAGXnJ,WAAW,SAAS9tC;gBAChBzY,KAAKyxD,SAASh5C;;YAGlBovC,iBAAiB;gBACb,OAAO8H;;YAGX7H,WAAW,SAASrvC;gBAChB63C,KAAKmB,SAASh5C;;YAGlBmqC,kBAAkB,SAASnqC;gBACvB,OAAO4G,QAAQ5G;;YAGnB4tC,cAAc,SAAS5tC;gBACnB,IAAI27C,OAAO9C,YAAY74C;gBAEvB27C,QAAQn5D,GAAGm5D,MAAMryD,SAAS7H,QAAQotB,QAAQokC;;YAG9C/I,iBAAiB,SAASlqC;gBACtB,OAAOxd,GAAGokB,QAAQ5G,KAAKhX,SAAS8rD;;YAGpCpH,cAAc,SAAS1tC;gBACnB,IAAI27C,OAAO9C,YAAY74C;gBAEvB27C,QAAQn5D,GAAGm5D,MAAMpyD,YAAY9H,QAAQotB,QAAQokC;;YAGjD2I,YAAY,SAASj1D;gBACjB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBiB,cAAc;;YAGzDlJ,cAAc,SAASvtC;gBACnB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBgB;;YAGtDqF,aAAa,SAASl1D;gBAClB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBgB,mBAAmB;;YAG9D9H,gBAAgB,SAAS1uC,IAAI2P,QAAQC;gBACjC,IAAI4qC,MAAMzB,YAAY/4C,KAClBu6C;gBAEJ,IAAIC,OAAO5qC,QAAQ,GAAG;oBAClB2qC,UAAU1xD,KAAKC,MAAM6mB,SAASC,QAAQ;oBAEtC,IAAI2qC,YAAY,KAAK;wBACjBhzD,KAAKizD;2BAEJ;wBACD3C,KAAK2C;;oBAGTF,oBAAoBt6C,IAAIu6C;;;YAIhCzZ,qBAAqB,SAASnxB,QAAQC;gBAClCnrB,KAAKiqD,eAAe,MAAM/+B,QAAQC;;YAGtCg/B,cAAc,SAAS5uC;gBACnB,IAAIw6C,MAAMzB,YAAY/4C;gBAEtBw6C,OAAOjzD,KAAKizD;;YAGhBM,mBAAmB;gBACfr2D,KAAKmqD;;YAGTsB,eAAe,SAASlwC;gBACpBs6C,oBAAoBt6C,IAAI;gBACxBvb,KAAKq2D,kBAAkB96C;;YAG3BquC,oBAAoB;gBAChB5pD,KAAKyrD;;YAGTf,YAAY,SAASnvC;gBACjB,KAAKm1C,kBAAkB;oBACnB,IAAInwC,SAASuzC,UAAUv4C;oBAEvBgF,UAAUxiB,GAAGwiB,QAAQzb,YAAY9H,QAAQotB,QAAQtnB;;;YAIzDonD,YAAY,SAAS3uC;gBACjBzY,KAAKgxD,UAAUv4C;;YAGnB87C,UAAU,SAASn1D;gBACf,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBxwC,QAAQ;;YAGnD2qC,YAAY,SAAS3vC;gBACjB63C,KAAKiB,SAAS94C;gBACdzY,KAAKkxD,YAAYz4C;;YAGrB0qC,cAAc,SAAS1qC;gBACnBvb,KAAKspD,cAAc/tC,IAAIve,QAAQ6I,KAAK2hC;gBACpCxnC,KAAKs3D,oBAAoB/7C;gBACzBzY,KAAK0xD,WAAWj5C;;YAGpBkuC,WAAW,SAASluC;gBAChBzY,KAAKuxD,SAAS94C;;YAGlBg8C,SAAS,SAASr1D;gBACd,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgB55C,OAAO;;YAGlDqgD,kBAAkB,SAASt1D;gBACvB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBa,gBAAgB;;YAG3D0F,qBAAqB,SAAS/7C;gBAC1B63C,KAAKY,YAAYz4C;gBACjBzY,KAAKuxD,SAAS94C;;YAGlB4qC,iBAAiB,SAAS5qC;gBACtBvb,KAAKspD,cAAc/tC,IAAI;gBACvBvb,KAAKkrD,WAAW3vC;gBAChB63C,KAAKoB,WAAWj5C;;YAGpBwvC,kBAAkB,SAASxvC;gBACvB63C,KAAKc,UAAU34C;;YAGnBwwC,kBAAkB,SAASxwC;gBACvBzY,KAAKoxD,UAAU34C;;YAGnBk8C,gBAAgB,SAASv1D;gBACrB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBc,cAAc;;YAGzD6F,SAAS,SAASx1D;gBACd,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBrsC,OAAO;;YAGlDpH,YAAY,SAAS/B,IAAI1V;gBACrB,IAAIyW,OAAO6G,QAAQ5H;gBAEnB,IAAIe,MAAM;oBACN82C,KAAK92C;oBACLve,GAAGue,MAAM1W,QAAQC;;;YAIzByjD,eAAe,SAAS/tC,IAAI1V;gBACxB,IAAI8xD,SAAS5D,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBe;gBAExD,IAAI6F,QAAQ;oBAER,IAAI9xD,QAAQ,MAAM;wBACd9H,GAAG45D,QAAQ3xD;2BAEV;wBACDjI,GAAG45D,QAAQ/xD,QAAQC;;;;YAK/B8jD,aAAa,SAASpuC;gBAClBxd,GAAGokB,QAAQ5G,KAAKzW,YAAYsrD;gBAC5BttD,KAAK0xD,WAAWj5C;;YAGpB0vC,aAAa,SAAS1vC;gBAClBxd,GAAGokB,QAAQ5G,KAAK1W,SAASurD;gBACzBgD,KAAKoB,WAAWj5C;;YAGpByxC,iBAAiB,SAASzxC,IAAIk6C,eAAe5zC;gBACzC,KAAK7hB,KAAKylD,gBAAgBlqC,KAAK;oBAC3Bs1C,qBAAqBhxD;wBAAM0b,IAAIA;wBAAIsG,sBAAsBA;wBAAsB4zC,eAAeA;;qBAC7F7E,gCAAgC6C;;;YAIzC3G,iBAAiB,SAASvxC,IAAIkL,cAAcmvC,gBAAgB/zC;gBACxD,KAAK7hB,KAAKylD,gBAAgBlqC,KAAK;oBAC3Bs1C,qBAAqBhxD;wBAAMgiB,sBAAsBA;wBAAsB8xC,QAAQ;wBAAMp4C,IAAIA;wBAAIkL,cAAcA;wBAAcmvC,gBAAgBA;;qBACxIhF,gCAAgC6C;;;YAIzCzE,WAAW,SAAS9tD;gBAChB,OAAOnD,GAAGgW,kBAAkB4C,mBAAmBs9C,UAAU/yD;;YAG7D+tD,YAAY,SAAS/tD,MAAMd,SAAS+uD;gBAChC,IAAIyI,SAAS3D,UAAU/yD,OACnB22D,YAAY9D,cAAc6D,QAAQ7G,gBAAgBI,gBAClD2G,UAAUF,OAAOtyD,qBAAqB,SAAS,IAC/CyyD,YAAYhE,cAAc6D,QAAQ7G,gBAAgBE,qBAClD+G,QAAQjE,cAAc6D,QAAQ7G,gBAAgBK,iBAC9CnkD,UAAU,IAAIlP,GAAGmP,WAEjB+qD,eAAe;oBACXF,UAAU10D,oBAAoB,SAAS60D;oBACvCF,SAASA,MAAM30D,oBAAoB,SAAS80D;oBAC5ClrD,QAAQK;mBAGZ4qD,qBAAqB;oBACjBH,UAAU10D,oBAAoB,SAAS60D;oBACvCN,OAAOQ;mBAGXD,iBAAiB;oBACbP,OAAOv0D,oBAAoB,SAAS40D;oBACpCD,MAAM30D,oBAAoB,SAAS80D;oBACnCP,OAAOQ;oBAEPnrD,QAAQG,QAAQ0qD,WAAWA,QAAQrvD;;gBAG3CmvD,OAAO10D,iBAAiB,SAAS+0D;gBACjCF,UAAU70D,iBAAiB,SAASg1D;gBACpCF,SAASA,MAAM90D,iBAAiB,SAASi1D;gBAEzC,IAAIL,SAAS;oBACTA,QAAQrvD,QAAQ0mD;;gBAEpB0I,UAAU9xD,cAAc3F;gBAExBw3D,OAAOS;gBAEP,OAAOprD;;;;IC/gCnBlP,GAAGu6D,iBAAiB,SAASC,GAAGC;QAC5B;QAEA,IAAIllD,WAAW,IAAIvV,GAAGoV,kBAClBgJ;YACIs8C,WAAW;YACXC,UAAU;YACVC,WAAW,SAAShrD,QAAQ6mB;;QAKpCz2B,GAAGuG,OAAOtE;YACNgqD,YAAY,SAASvpD;gBACjBupD,WAAWvpD;;YAGf4S,SAAS;gBACLC,SAASD;;;QAIjB,SAAS22C,WAAWvpD;YAChB6S,SAASrQ,OAAOxC,SAAS0b,KAAKs8C,WAAW,SAASjkC;gBAE9CA,QAAQA,SAASxtB,OAAOwtB;gBAGxB,IAAI7mB,SAAS6mB,MAAM7mB,UAAU6mB,MAAMokC;gBAEnCz8C,KAAKw8C,UAAUhrD,QAAQ6mB;;;QAK/Bz2B,GAAGuG,OAAOk0D;YACNK,mBAAmB,SAAS7vD;gBACxB,OAAOA,KAAK8vD;;YAGhBC,mBAAmB;gBACf,OAAOzlD;;;QAIfvV,GAAGuG,OAAO6X,MAAMo8C;QAEhB,IAAIp8C,KAAKu8C,UAAU;YACf1O,WAAW7tC,KAAKu8C;;;IClDxB36D,GAAG8oD,0BAA0B,SAAS0R;QAClC;QAEA,IAAIS,2BACA78C;YACIsrC,YAAY;YACZtnD,KAAK,SAASC,SAAS2nD;YACvBC,cAAc,SAASvmC;YACvB8J,UAAU,SAAS9J;YACnBwmC,SAAS,SAASxmC;YAClBymC,SAAS,SAASzmC;YAClB0mC,YAAY,SAAS1mC;YACrB2mC,WAAW,SAAS3mC;WAExBw3C;YACI14C,QAAQ,SAAShF;gBAAMY,KAAKoP,SAAShQ;;YACrCmJ,OAAQ,SAASnJ;gBAAMY,KAAK8rC,QAAQ1sC;;YACpCs2C,cAAc,SAASt2C;gBAAMY,KAAK6rC,aAAazsC;;YAC/CpE,OAAO,SAASoE;gBAAMY,KAAK+rC,QAAQ3sC;;YACnCq2C,gBAAgB,SAASr2C;gBAAMY,KAAKgsC,WAAW5sC;;;QAGvD,SAAS29C,aAAavrD,QAAQ6mB;YAC1Bz2B,GAAGY,KAAKs6D,gBAAgB,SAASE,YAAYtqC;gBACzC,IAAIuqC,2BAA2BD,WAAWx7D,OAAO,GAAGC,gBAAgBu7D,WAAWt7D,MAAM,IACjF4jB;gBAEJ,IAAItF,KAAKsrC,WAAW,OAAO2R,0BAA0BzrD,SAAS;oBAC1D8T,SAAStF,KAAKsrC,WAAWnB,UAAU34C;oBACnC5P,GAAGmS,eAAeskB;oBAClBrY,KAAKhc,IAAIpC,GAAGyL,OAAO,gEAAgE2S,KAAKisC,UAAU3mC,SAASA;oBAC3GoN,QAAQpN;oBACR,OAAO;;;;QAKnB1jB,GAAGuG,OAAO6X,MAAMo8C;QAEhBp8C,KAAKs8C,YAAY;QACjBt8C,KAAKw8C,YAAYO;QACjB/8C,KAAKu8C,WAAWv8C,KAAKsrC,WAAWsP;QAEhCh5D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu6D,eAAen8C,MAAM68C;;IC1ChDj7D,GAAGuqD,uBAAuB,SAASiQ;QAC/B;QAEA,IAAIS,2BACA78C;YACIsrC,YAAY;YACZtnD,KAAK,SAASC,SAAS2nD;YACvB39B;gBACIjK,MAAM;gBACN6xC,cAAc;;YAElBvJ,mBAAmB,SAAShnC;YAC5B2mC,WAAW,SAAS3mC;;QAG5B1jB,GAAGuG,OAAO6X,MAAMo8C;QAGhB,SAASW,aAAavrD,QAAQ6mB;YAC1B,IAAIrY,KAAKsrC,WAAWwP,WAAWtpD,WAAWwO,KAAKsrC,WAAW0P,WAAWxpD,SAAS;gBAC1E,IAAI8T,SAAStF,KAAKsrC,WAAWnB,UAAU34C,SACnCiO,SAASO,KAAKssC,kBAAkBhnC;gBAGpC,IAAI7F,WAAW7d,GAAG6d,OAAOiC,WAAW;oBAChC1B,KAAKhc,IAAIpC,GAAGyL,OAAO,6DAA6D2S,KAAKisC,UAAU3mC,SAASA;oBACxG1jB,GAAGmS,eAAeskB;oBAElBwkC,qBAAqBK,mBAAmB53C,QAAQ9T,QAAQ;;;;QAKpEwO,KAAKs8C,YAAY;QACjBt8C,KAAKw8C,YAAYO;QAEjBn7D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7D,oBAAoBn9C,MAAM68C;;ICpCrDj7D,GAAG2rD,8BAA8B,SAAS6O,GAAGS;QACzC;QAEA,IAAI78C;YACIsrC,YAAY;YACZgB,mBAAmB,SAAShnC;YAC5BthB,KAAK,SAASC,SAAS2nD;;QAG/B,KAAKiR,sBAAsB;YACvBA;;QAIJ,SAASO,iBAAiB5rD,QAAQ6mB;YAC9B,IAAIrY,KAAKsrC,WAAW2P,YAAYzpD,SAAS;gBACrC,IAAI8T,SAAStF,KAAKsrC,WAAWnB,UAAU34C,SACnCiO,SAASO,KAAKssC,kBAAkBhnC;gBAEpC,IAAI7F,WAAW7d,GAAG6d,OAAOiC,WAAW;oBAChC1B,KAAKhc,IAAIpC,GAAGyL,OAAO,mEAAmE2S,KAAKisC,UAAU3mC,SAASA;oBAC9Gu3C,qBAAqBK,mBAAmB53C,QAAQ9T;;;;QAK5DwO,KAAKs8C,YAAY;QACjBt8C,KAAKw8C,YAAYY;QAEjBx7D,GAAGuG,OAAO6X,MAAMo8C;QAChBx6D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7D,oBAAoBn9C,MAAM68C;;ICzBrDj7D,GAAGwqD,4BAA4B,SAASpsC;QACpC;QAEAA,KAAKs8C,YAAY;QACjBt8C,KAAKu8C,WAAW;QAEhB36D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAG2rD,4BAA4BvtC;;ICVvDpe,GAAGu7D,sBAAsB,SAASf,GAAGS;QACjC;QAEA,IAAI78C;YACIsrC,YAAY;YACZtnD,KAAK,SAASC,SAAS2nD;YACvBU,mBAAmB,SAAShnC;YAC5B2mC,WAAW,SAAS3mC;YACpBinC,WAAW,SAASjnC,QAAQpE;YAC5BsrC,uBAAuB,SAASlnC,QAAQmnC;;QAGhD,SAAS4Q,yBAAyB/3C;YAC9B,IAAIg4C,kBAAkBt9C,KAAKisC,UAAU3mC,SACjC5O,SAAS4mD,gBAAgB3mD,YAAY;YAEzC,IAAID,SAAS,GAAG;gBACZ4mD,kBAAkBA,gBAAgB1mD,OAAO,GAAGF;;YAGhD,OAAO4mD;;QAGX,SAASC,qBAAqBj4C;YAC1B,IAAIk4C,WAAWx9C,KAAKisC,UAAU3mC;YAC9B,OAAO1jB,GAAG4U,aAAagnD;;QAI3B,SAASC,iBAAiBC,oBAAoBp4C;YAC1C,IAAIpE,UAAUw8C,mBAAmBpxD,OAC7BqxD;YAEJ,IAAIz8C,YAAYhf,aAAaN,GAAGqL,QAAQiU,SAASlb,SAAS,GAAG;gBACzD23D,gBAAgBJ,qBAAqBj4C;gBAErC,IAAIq4C,kBAAkBz7D,WAAW;oBAC7Bgf,UAAUA,UAAU,MAAMy8C;;gBAG9B39C,KAAKusC,UAAUjnC,QAAQpE;;YAG3BlB,KAAKwsC,sBAAsBlnC,QAAQ;;QAIvC,SAASs4C,yBAAyBjC,SAASr2C;YACvCu3C,qBAAqBD,oBAAoB91D,OAAO60D,SAAS,QAAQ;gBAC7D8B,iBAAiB9B,SAASr2C;;;QAKlC,SAASu4C,6BAA6BlC,SAASr2C;YAC3Cu3C,qBAAqBD,oBAAoB91D,OAAO60D,SAAS,SAAS,SAAStjC;gBAEvE,IAAIpE,OAAOoE,MAAMylC,WAAWzlC,MAAM0lC;gBAElC,IAAI9pC,SAAS,IAAI;oBACbwpC,iBAAiB9B,SAASr2C;;;;QAKtC1jB,GAAGuG,OAAO6X,MAAMo8C;QAEhBp8C,KAAKu8C,WAAWv8C,KAAKsrC,WAAWsP;QAEhCh5D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu6D,eAAen8C,MAAM68C;QAE5Cj7D,GAAGuG,OAAO00D;YACNK,oBAAoB,SAAS99C,IAAI5N,QAAQwsD;gBACrC,IAAIN,qBAAqB19C,KAAKsrC,WAAWqB,aAAavtC;gBAEtDY,KAAKwsC,sBAAsBptC,IAAI;gBAE/Bs+C,mBAAmBpxD,QAAQ+wD,yBAAyBj+C;gBAEpD,IAAI4+C,YAAY;oBACZN,mBAAmBO;;gBAGvBL,yBAAyBF,oBAAoBt+C;gBAC7Cy+C,6BAA6BH,oBAAoBt+C;;;;G7CvF9BvU","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return q.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&q.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),q.attach(document,"dragleave",function(e){s(e)&&t()}),q.attach(qq(document).children()[0],"mouseenter",function(e){t()}),q.attach(document,"drop",function(e){e.preventDefault(),t()}),q.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],q=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){q.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",q="qq-drop-area-text",f="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){ -var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,f,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),f=qq(a).getFirstByClass(F.drop),f&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(f).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(q)&&f&&(_=qq(f).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(q),f&&qq(f).hasAttribute(h)&&qq(f).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),f=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(q),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(f),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(f),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,q,f,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),q=d&&h&&a(),f=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:q,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:f}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i);return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[] +;return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function q(e){return function(){s(e,!0)}}function f(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var q=o._getFileState(t).chunking.inProgress;d=q?qq.indexOf(q,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,q=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===q.length)l.finalize(e);else{q.push(r),o._getFileState(e).chunking.inProgress=q,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e) +;var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[q(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(f("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;f(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){f("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(f("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||f("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,q=s.getUuid,f=s.log,m=new qq.WindowReceiveMessage({log:f});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(f("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){f("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){f("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,q=o.getDataByUuid,f=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),q(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),q=u;s[t]=h,qq.each(s,function(e,t){q+=t}),m(e,r,q,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,q=u.height,f=s.getContext("2d"),m=new qq.Promise;return f.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:q,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:q}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,q,c.newWidth,c.newHeight),"warn"),h=c.newWidth,q=c.newHeight)),a(s,h,q,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*q/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA;KCCT,SAASC;QACN;QACA,IAAIC,KACAC,kBAAiB,gBAAgB;QAErC,SAASC,KAAKC;YACV,IAAIC,cAAcC,mBAAmBF,gBACjCG,sBAAsBC,uBAAuBH;YAEjDI,SAASF;YACTG,aAAaL,aAAaE;YAE1B,OAAON;;QAGX,SAASO,uBAAuBG;YAC5B,IAAIC,eAAeC,aAAa,iBAC5BC,YAAYD,aAAa;YAG7B,IAAID,cAAc;gBAGdA,eAAeA,aAAaG,OAAO,GAAGC,gBAAgBJ,aAAaK,MAAM,GAAGC;gBAE5E,IAAIJ,WAAW;oBACX,OAAO,IAAIK,GAAGL,WAAW,iBAAiBF,cAAcD;;gBAG5D,OAAO,IAAIQ,GAAG,iBAAiBP,cAAcD;mBAE5C;gBACD,IAAIG,WAAW;oBACX,OAAO,IAAIK,GAAGL,WAAWM,aAAaT;;gBAG1C,OAAO,IAAIQ,GAAGC,aAAaT;;;QAInC,SAASU,UAAUC,KAAKC;YACpB,IAAIC,OAAOvB,IAAIuB,KAAK;YAEpB,IAAID,KAAK;gBACL,IAAIC,SAASC,WAAW;oBACpBD;;gBAEJA,KAAKF,OAAOC;gBACZtB,IAAIuB,KAAK,gBAAgBA;mBAExB;gBACD,IAAIA,SAASC,WAAW;oBACpB,OAAO;;gBAEX,OAAOD,KAAKF;;;QAMpB,SAASb,SAASiB;YACd,OAAOL,UAAU,YAAYK;;QAGjC,SAASb,aAAac,QAAQC;YAC1B,OAAOP,UAAUM,QAAQC;;QAK7B,SAASlB,aAAamB,iBAAiBtB;YACnC,IAAIuB,YAAYD,gBAAgBC;YAEhC9B,EAAE+B,KAAKxB,oBAAoByB,SAASF,WAAW,SAASG,MAAMC;gBAC1D,IAAIC,MAAMC;gBAEVD,OAAO,WAAWE,KAAKJ,MAAM;gBAC7BE,OAAOA,KAAKG,UAAU,GAAG,GAAGpB,gBAAgBiB,KAAKG,UAAU;gBAC3DF,sBAAsBnC;gBAEtB6B,UAAUG,QAAQ;oBACd,IAAIM,eAAeC,MAAMC,UAAUxB,MAAMyB,KAAKC,YAC1CC,sBACAC,yBAAyBC;oBAE7B9C,EAAE+B,KAAKQ,cAAc,SAASQ,KAAKC;wBAC/BJ,gBAAgBK,KAAKC,kBAAkBF;;oBAG3CH,0BAA0BX,kBAAkBiB,MAAMC,MAAMb;oBAExD;wBACIO,4BAA4BV,oBAAoBiB,eAAelB,MAAMS;sBAEzE,OAAOU;wBACHnC,GAAGoC,IAAI,yDAAyDD,MAAME,SAAS;;oBAInF,IAAIX,2BAA2B,MAAM;wBACjC,OAAOA;;oBAEX,OAAOC;;;YAIfvC,oBAAoByB,SAASF,YAAYA;;QAI7C,SAASxB,mBAAmBmD,QAAQC;YAChC,IAAIC,SAASC;YAEb,IAAIF,SAASjC,WAAW;gBACpB,IAAIgC,OAAO7C,iBAAiB,SAAS;oBACjC+C;wBAAYE,SAAS5D,IAAI;;uBAExB;oBACD0D;;mBAGH;gBACDA,UAAUD;;YAGd1D,EAAE+B,KAAK0B,QAAQ,SAASxB,MAAMV;gBAC1B,IAAIvB,EAAE8D,QAAQ7B,MAAM/B,kBAAkB,GAAG;oBACrCW,aAAaoB,MAAMV;uBAElB,IAAIA,eAAevB,GAAG;oBACvB2D,QAAQ1B,QAAQV,IAAI;uBAEnB,IAAIvB,EAAE+D,cAAcxC,MAAM;oBAC3BoC,QAAQ1B;oBACR3B,mBAAmBiB,KAAKoC,QAAQ1B;uBAE/B,IAAIjC,EAAEgE,QAAQzC,MAAM;oBACrBqC;oBACA5D,EAAE+B,KAAKR,KAAK,SAASwB,KAAKkB;wBACtB,IAAIC;wBAEJ,IAAID,oBAAoBjE,GAAG;4BACvBA,EAAEmE,MAAMP,WAAWK;+BAElB,IAAIjE,EAAE+D,cAAcE,WAAW;4BAChC3D,mBAAmB2D,UAAUC;4BAC7BN,UAAUX,KAAKiB;+BAEd;4BACDN,UAAUX,KAAKgB;;;oBAGvBN,QAAQ1B,QAAQ2B;uBAEf;oBACDD,QAAQ1B,QAAQV;;;YAIxB,IAAImC,SAASjC,WAAW;gBACpB,OAAOkC;;;QAIf,SAASS,eAAeC;YACpB,OAAOrE,EAAEsE,KAAKD,aAAa,aACtBA,QAAQE,MAAM,SACf9D,WAAW4D,aAAa5C;;QAKhC,SAAS+C,gBAAgBH;YACrB,IAAII,kBACAC,WAAWlC,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW,IACjDgC;YAEJrE,mBAAmBoE,UAAUD;YAE7BE,SAASlE,WAAW4D,SAASlB,MAAM1C,YAAYgE;YAE/C,OAAOvB,kBAAkByB;;QAI7B,SAASzB,kBAAkB3B;YACvB,IAAIqD,iBAAiBrD;YAIrB,IAAIA,OAAO,eAAeA,QAAQ,aAC9BA,IAAIsD,aAAa,KAAKtD,IAAIsD,aAAa,MAAMtD,IAAIuD,WAAW;gBAE5DF,iBAAiB5E,EAAEuB;;YAGvB,OAAOqD;;QAGX5E,EAAE+E,GAAGC,eAAe,SAASC;YACzB,IAAIC,OAAO9B,MAAM+B,WAAWxC,WAAWyC;YAEvChC,KAAKrB,KAAK,SAASsD,OAAOC;gBACtBrF,MAAMD,EAAEsF;gBAER,IAAI7E,cAAc2D,eAAea,mBAAmB;oBAChDG,QAAQnC,KAAKuB,gBAAgBrB,MAAM+B,MAAMC;oBAEzC,IAAID,KAAKK,WAAW,GAAG;wBACnB,OAAO;;uBAGV,WAAWN,qBAAqB,aAAaA,kBAAkB;oBAChE9E,KAAKgD,MAAM+B,MAAMC;uBAEhB;oBACDnF,EAAEsD,MAAM,YAAa2B,mBAAmB;;;YAIhD,IAAIG,QAAQG,WAAW,GAAG;gBACtB,OAAOH,QAAQ;mBAEd,IAAIA,QAAQG,SAAS,GAAG;gBACzB,OAAOH;;YAGX,OAAOhC;;OAGboC;KCtOD,SAASxF;QACN;QACA,IAAIyF,cAAc,mBACdxF;QAEJ,SAASE,KAAKC;YACV,KAAKA,SAAS;gBACVA;;YAGJA,QAAQsF,qBAAoBzF;YAC5B,IAAII,cAAcC,mBAAmBF;YACrCM,aAAaL;YACbsF,IAAI,IAAIxE,GAAGyE,YAAYvF;YAEvB,OAAOJ;;QAGX,SAASoB,UAAUC,KAAKC;YACpB,IAAIC,OAAOvB,IAAIuB,KAAKiE;YAEpB,IAAIlE,KAAK;gBACL,IAAIC,SAASC,WAAW;oBACpBD;;gBAEJA,KAAKF,OAAOC;gBACZtB,IAAIuB,KAAKiE,aAAajE;mBAErB;gBACD,IAAIA,SAASC,WAAW;oBACpB,OAAO;;gBAEX,OAAOD,KAAKF;;;QAIpB,SAASqE,IAAIjE;YACT,OAAOL,UAAU,eAAeK;;QAGpC,SAAShB,aAAamB;YAClB,IAAIC,YAAYD,gBAAgBC;YAEhC9B,EAAE+B,KAAK,IAAIZ,GAAGyE,YAAY9D,aAAa,SAASG,MAAM4D;gBAClD,IAAI1D,OAAOF,MACP6D;gBAEJA,cAAc7F;gBAEd6B,UAAUG,QAAQ;oBACd,IAAI8D,OAAOvD,MAAMC,UAAUxB,MAAMyB,KAAKC,YAClCqD,sBAAsBF,YAAYzC,eAAelB,MAAM4D;oBAE3D,OAAOC;;;;QAMnB,SAAS1F,mBAAmBmD,QAAQC;YAChC,IAAIC,SAASC;YAEb,IAAIF,SAASjC,WAAW;gBACpBkC;mBAEC;gBACDA,UAAUD;;YAGd1D,EAAE+B,KAAK0B,QAAQ,SAASxB,MAAMV;gBAC1B,IAAIA,eAAevB,GAAG;oBAClB2D,QAAQ1B,QAAQV,IAAI;uBAEnB,IAAIvB,EAAE+D,cAAcxC,MAAM;oBAC3BoC,QAAQ1B;oBACR3B,mBAAmBiB,KAAKoC,QAAQ1B;uBAE/B,IAAIjC,EAAEgE,QAAQzC,MAAM;oBACrBqC;oBACA5D,EAAE+B,KAAKR,KAAK,SAASwB,KAAKkB;wBACtB,IAAIA,oBAAoBjE,GAAG;4BACvBA,EAAEmE,MAAMP,WAAWK;+BAElB;4BACDL,UAAUX,KAAKgB;;;oBAGvBN,QAAQ1B,QAAQ2B;uBAEf;oBACDD,QAAQ1B,QAAQV;;;YAIxB,IAAImC,SAASjC,WAAW;gBACpB,OAAOkC;;;QAIf,SAASS,eAAeC;YACpB,OAAOrE,EAAEsE,KAAKD,aAAa,YACvBA,YAAY,aACZsB,MAAMtB,aAAa5C;;QAG3B,SAAS+C,gBAAgBH;YACrB,IAAII,kBAAkBC,WAAWlC,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW;YACvErC,mBAAmBoE,UAAUD;YAC7B,OAAOkB,MAAMtB,SAASlB,MAAMwC,OAAOlB;;QAGvCzE,EAAE+E,GAAGkB,kBAAkB,SAAShB;YAC5B,IAAIC,OAAO9B,MAAM+B,WAAWxC,WAAWyC;YAEvChC,KAAKrB,KAAK,SAASsD,OAAOC;gBACtBrF,MAAMD,EAAEsF;gBAER,IAAIK,SAASvB,eAAea,mBAAmB;oBAC3CG,QAAQnC,KAAKuB,gBAAgBrB,MAAM+B,MAAMC;oBAEzC,IAAID,KAAKK,WAAW,GAAG;wBACnB,OAAO;;uBAGV,WAAWN,qBAAqB,aAAaA,kBAAkB;oBAChE9E,KAAKgD,MAAM+B,MAAMC;uBAEhB;oBACDnF,EAAEsD,MAAM,YAAa2B,mBAAmB;;;YAIhD,IAAIG,QAAQG,WAAW,GAAG;gBACtB,OAAOH,QAAQ;mBAEd,IAAIA,QAAQG,SAAS,GAAG;gBACzB,OAAOH;;YAGX,OAAOhC;;OAGboC;IC7IF,IAAIrE,KAAK,SAAS0C;QACd;QAEA;YACIqC,MAAM;gBACFrC,QAAQsC,MAAMC,UAAU;gBACxB,OAAOhD;;YAIXiD,QAAQ,SAAS/B,MAAMS;gBACnB,IAAIlB,QAAQyC,kBAAkB;oBAC1BzC,QAAQyC,iBAAiBhC,MAAMS,IAAI;uBAChC,IAAIlB,QAAQ0C,aAAa;oBAC5B1C,QAAQ0C,YAAY,OAAOjC,MAAMS;;gBAErC,OAAO;oBACH5D,GAAG0C,SAAS2C,OAAOlC,MAAMS;;;YAIjCyB,QAAQ,SAASlC,MAAMS;gBACnB,IAAIlB,QAAQ4C,qBAAqB;oBAC7B5C,QAAQ4C,oBAAoBnC,MAAMS,IAAI;uBACnC,IAAIlB,QAAQ0C,aAAa;oBAC5B1C,QAAQ6C,YAAY,OAAOpC,MAAMS;;gBAErC,OAAO3B;;YAGXuD,UAAU,SAASC;gBAKf,KAAKA,YAAY;oBACb,OAAO;;gBAIX,IAAI/C,YAAY+C,YAAY;oBACxB,OAAO;;gBAGX,IAAI/C,QAAQ8C,UAAU;oBAClB,OAAO9C,QAAQ8C,SAASC;uBACrB;oBAEH,UAAUA,WAAWC,wBAAwBhD,WAAW;;;YAOhEiD,cAAc,SAASC;gBACnBA,SAASC,WAAWF,aAAajD,SAASkD;gBAC1C,OAAO3D;;YAGX6D,QAAQ;gBACJpD,QAAQmD,WAAWE,YAAYrD;gBAC/B,OAAOT;;YAOX+D,KAAK,SAASC;gBAEV,IAAIvD,QAAQsC,SAAS,MAAM;oBACvB,MAAM,IAAIhF,GAAGkG,MAAM;;gBAIvB,IAAID,OAAOE,WAAW,MAAM;oBACxB,WAAWzD,QAAQsC,MAAMmB,YAAY,mBAAoBzD,QAAe,YAAM,aAAa;wBACvFuD,OAAOG,SAAS,mBAAmBC,KAAKC,MAAM,MAAML,OAAOE,WAAW;;;gBAG9EnG,GAAGuG,OAAO7D,QAAQsC,OAAOiB;gBAEzB,OAAOhE;;YAGXuE,UAAU,SAASxF,MAAMyF;gBACrB,IAAIC,KAAK,IAAIC,OAAO,UAAU3F,OAAO;gBACrC,OAAO0F,GAAGE,KAAKlE,QAAQmE,iBAAiBJ,kBAAkBC,GAAGE,KAAKlE,QAAQmD,WAAWgB;;YAGzFC,UAAU,SAAS9F;gBACf,KAAKhB,GAAG0C,SAAS8D,SAASxF,OAAO;oBAC7B0B,QAAQmE,aAAa,MAAM7F;;gBAE/B,OAAOiB;;YAGX8E,aAAa,SAAS/F;gBAClB,IAAI0F,KAAK,IAAIC,OAAO,UAAU3F,OAAO;gBACrC0B,QAAQmE,YAAYnE,QAAQmE,UAAUG,QAAQN,IAAI,KAAKM,QAAQ,cAAc;gBAC7E,OAAO/E;;YAGXgF,YAAY,SAASJ,WAAWK;gBAC5B,IAAIC,YACAC;gBAEJ,IAAIF,SAASxE,QAAQ2E,eAAe;oBAChC,OAAO3E,QAAQ2E,cAAc,MAAMR;uBAElC,IAAInE,QAAQ4E,kBAAkB;oBAC/B,OAAO5E,QAAQ4E,iBAAiB,MAAMT;;gBAG1CM,aAAazE,QAAQ6E,qBAAqB;gBAE1CvH,GAAGY,KAAKuG,YAAY,SAASvF,KAAKxB;oBAC9B,IAAIJ,GAAGI,KAAKoG,SAASK,YAAY;wBAC7BO,OAAOtF,KAAK1B;;;gBAGpB,OAAO8G,QAAQE,OAAO,KAAKA;;YAG/BI,iBAAiB,SAASX;gBACtB,OAAO7G,GAAG0C,SAASuE,WAAWJ,WAAW;;YAG7CY,UAAU;gBACN,IAAIA,eACAC,QAAQhF,QAAQiF;gBAEpB,OAAOD,OAAO;oBACV,IAAIA,MAAMhE,aAAa,GAAG;wBACtB+D,SAAS3F,KAAK4F;;oBAElBA,QAAQA,MAAME;;gBAGlB,OAAOH;;YAGXI,SAAS,SAASC;gBACdpF,QAAQqF,YAAYD;gBACpBpF,QAAQsF,cAAcF;gBACtB,OAAO7F;;YAGXgG,WAAW;gBACP,OAAOjI,GAAG0C,SAASmF,QAAQ;;YAK/BK,cAAc,SAASC;gBACnB,IAAIC;gBAEJ,IAAI1F,QAAQwF,cAAc;oBAEtB,KAAKxF,QAAQwF,aAAaC,WAAW;wBACjC,OAAO;;oBAIX,OAAO,WAAajH,KAAKwB,QAAQ2F,aAAaF,cAAc;uBAE3D;oBACDC,UAAU1F,QAAQyF;oBAElB,IAAIC,YAAY9H,WAAW;wBACvB,OAAO;;oBAIX,OAAO,WAAaY,KAAKkH,YAAY;;;;;KAMpD;QACG;QAEApI,GAAGsI,eAAe,SAASC,QAAQC,MAAMC;YACrC,OAAOzI,GAAG0I,cAAcH,OAAOI,UAAUH,MAAMC;;QAGnDzI,GAAG0I,gBAAgB,SAASE;YACxB,IAAIC,aAAaC,YACbC,aAAa,SAAS1I,MAAMmI;gBACxB,IAAIQ,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;gBAErC,IAAIK,aAAa;oBACbA,YAAYC,OAAOjJ;oBACnB,OAAOgJ,YAAYE,QAAQf;uBAE1B;oBACD,OAAO,IAAIgB,OAAMnJ;wBAAQ8C,MAAMqF;;;eAGvCiB,UAAUC;YAGd,IAAId,QAAQe,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cd,aAAae,KAAKjB,QAAQe,MAAM,KAAK;mBAEpC;gBACDb,aAAagB,UAAUlB,QAAQe,MAAM,KAAK;;YAI9CD,aAAad,QAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBd,cAAc,IAAIkB,YAAYjB,WAAW1E;YACzCqF,WAAW,IAAIO,WAAWnB;YAC1B7I,GAAGY,KAAKkI,YAAY,SAASlH,KAAKqI;gBAC9BR,SAAS7H,OAAOqI,UAAUC,WAAW;;YAGzC,OAAOnB,WAAWF,aAAaa;;QAGnC1J,GAAGoC,MAAM,SAASC,SAAS8H;YACvB,IAAIlB,OAAOmB,SAAS;gBAChB,KAAKD,SAASA,UAAU,QAAQ;oBAC5BlB,OAAOmB,QAAQhI,IAAIC;uBAGvB;oBACI,IAAI4G,OAAOmB,QAAQD,QAAQ;wBACvBlB,OAAOmB,QAAQD,OAAO9H;2BAErB;wBACD4G,OAAOmB,QAAQhI,IAAI,MAAM+H,QAAQ,OAAO9H;;;;;QAMxDrC,GAAGqK,WAAW,SAASC;YACnB,OAAOA,aAAaA,SAAS5G,YAAY6G,OAAOjJ,UAAUkJ,SAASjJ,KAAK+I,cAAc;;QAG1FtK,GAAGyK,aAAa,SAASH;YACrB,cAAc,aAAe;;QASjCtK,GAAG6C,UAAU,SAAS6H;YAClB,OAAOH,OAAOjJ,UAAUkJ,SAASjJ,KAAKmJ,WAAW,oBAC5CA,SAASzB,OAAOc,eAAeW,MAAMC,UAAUD,MAAMC,OAAOC,gBAAgBb;;QAIrF/J,GAAG6K,aAAa,SAASC;YACrB,OAAOP,OAAOjJ,UAAUkJ,SAASjJ,KAAKuJ,mBAAmB;;QAK7D9K,GAAG+K,aAAa,SAASC;YACrB,OAAOT,OAAOjJ,UAAUkJ,SAASjJ,KAAKyJ,mBAAmB,uBAGpDA,cAAcC,QAAQD,cAAcE;;QAG7ClL,GAAGmL,WAAW,SAASC;YACnB,OAAOb,OAAOjJ,UAAUkJ,SAASjJ,KAAK6J,iBAAiB;;QAG3DpL,GAAGqL,UAAU,SAASC;YAClB,IAAIC,OAAOjK,UAAUkK,MAAM;gBACvB,OAAOF,OAAOE;;YAGlB,OAAOF,OAAOtE,QAAQ,cAAc;;QAOxChH,GAAGyL,SAAS,SAASC;YAEjB,IAAI9G,OAAQvD,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW,IAC9CmK,SAASD,KACTE,mBAAmBD,OAAO/B,QAAQ;YAEtC5J,GAAGY,KAAKgE,MAAM,SAAShD,KAAKxB;gBACxB,IAAIyL,YAAYF,OAAOxK,UAAU,GAAGyK,mBAChCE,WAAWH,OAAOxK,UAAUyK,mBAAmB;gBAEnDD,SAASE,YAAYzL,MAAM0L;gBAC3BF,mBAAmBD,OAAO/B,QAAQ,MAAMgC,mBAAmBxL,IAAIgE;gBAG/D,IAAIwH,mBAAmB,GAAG;oBACtB,OAAO;;;YAIf,OAAOD;;QAGX3L,GAAG+L,SAAS,SAASC;YACjB,OAAO/C,OAAOgD,QAAQ1B,OAAOjJ,UAAUkJ,SAASjJ,KAAKyK,eAAe;;QAGxEhM,GAAGkM,aAAa,SAASC;YACrB,OAAOlD,OAAOmD,YAAY7B,OAAOjJ,UAAUkJ,SAASjJ,KAAK4K,mBAAmB;;QAGhFnM,GAAGqM,gBAAgB,SAASC;YACxB,OAAOtM,GAAG+L,OAAOO,qBAAqBtM,GAAGuM,QAAQD;;QAGrDtM,GAAGuM,UAAU,SAASC,YAAYC;YAC9B,IAAIC,eAAe,SAASvJ;gBACxB,IAAIwJ,iBAAiBxJ,KAAKpD;gBAE1B,IAAI0M,SAAS;oBACT,OAAOE,mBAAmB;;gBAG9B,OAAOA,mBAAmB;;YAG9B,IAAI1D,OAAO2D,kBAAkB;gBACzB,IAAIrC,OAAOjJ,UAAUkJ,SAASjJ,KAAKiL,gBAAgB,6BAA6B;oBAC5E,IAAIA,WAAWrJ,QAAQuJ,aAAaF,WAAWrJ,OAAO;wBAClD,OAAO;;;;YAInB,IAAIqJ,WAAWK,SAAS;gBACpB,IAAIL,WAAWK,QAAQ9M,kBAAkB,SAAS;oBAC9C,IAAIyM,WAAWrJ,QAAQuJ,aAAaF,WAAWrJ,OAAO;wBAClD,OAAO;;;;YAKnB,OAAO;;QAGXnD,GAAG8M,SAAS,SAASC;YACjB,IAAI9D,OAAOO,QAAQe,OAAOjJ,UAAUkJ,SAASjJ,KAAKwL,eAAe,iBAAiB;gBAC9E,OAAO;;;QAIf/M,GAAGgN,uBAAuB;YACtB,IAAIC,QAAQC,SAASC,cAAc;YACnCF,MAAM9J,OAAO;YAEb,OACI8J,MAAMG,aAAa9M,oBACR2L,SAAS,sBACToB,aAAa,sBACZrN,GAAGsN,oBAAqBC,WAAW;;QAIvDvN,GAAGsN,oBAAoB;YACnB,IAAIrE,OAAOuE,gBAAgB;gBACvB,OAAO,IAAIA;;YAGf;gBACI,OAAO,IAAIC,cAAc;cAE7B,OAAOtL;gBACHnC,GAAGoC,IAAI,yCAAyC;gBAChD,OAAO;;;QAIfpC,GAAG0N,wBAAwB,SAASC;YAChC,OAAOA,aAAaC,SAChBD,aAAaC,MAAMxJ,SAAS,KAC5BuJ,aAAaC,MAAM,GAAGC;;QAG9B7N,GAAG8N,0BAA0B;YACzB,QAAQ9N,GAAG+N,kBACP/N,GAAGgN,2BACFf,KAAK3K,UAAUxB,UAAUQ,aAAa2L,KAAK3K,UAAU0M,gBAAgB1N,aAAa2L,KAAK3K,UAAU2M,aAAa3N;;QAGvHN,GAAGkO,YAAY,SAASC,YAAYC,OAAOC;YACvC,IAAIC,SAASH,WAAWrO,SAASqO,WAAWF,YAAYE,WAAWH;YAEnE,OAAOM,OAAO/M,KAAK4M,YAAYC,OAAOC;;QAG1CrO,GAAGuO,mBAAmB,SAAS5D;YAC3B,IAAI6D,aAAa,IACbC,QAAQ,IAAIzE,WAAWW;YAE3B3K,GAAGY,KAAK6N,OAAO,SAAS7M,KAAK8M;gBACzB,IAAIC,eAAeD,IAAIlE,SAAS;gBAEhC,IAAImE,aAAavK,SAAS,GAAG;oBACzBuK,eAAe,MAAMA;;gBAGzBH,cAAcG;;YAGlB,OAAOH;;QAGXxO,GAAG4O,gBAAgB,SAASC,MAAMC,aAAa1K;YAC3C,IAAI2K,cAAc/O,GAAGkO,UAAUW,MAAMC,aAAaA,cAAc1K,SAC5D4K,aAAa,IAAIC,cACjBC,UAAU,IAAIlP,GAAGmP;YAErBH,WAAWI,SAAS;gBAChBF,QAAQG,QAAQrP,GAAGuO,iBAAiBS,WAAW5H;;YAGnD4H,WAAWM,UAAUJ,QAAQK;YAE7BP,WAAWQ,kBAAkBT;YAE7B,OAAOG;;QAGXlP,GAAGuG,SAAS,SAASW,OAAOuI,QAAQC;YAChC1P,GAAGY,KAAK6O,QAAQ,SAAS3O,MAAMV;gBAC3B,IAAIsP,gBAAgB1P,GAAGqK,SAASjK,MAAM;oBAClC,IAAI8G,MAAMpG,UAAUR,WAAW;wBAC3B4G,MAAMpG;;oBAEVd,GAAGuG,OAAOW,MAAMpG,OAAOV,KAAK;uBAE3B;oBACD8G,MAAMpG,QAAQV;;;YAItB,OAAO8G;;QAaXlH,GAAG2P,WAAW,SAASC,QAAQC;YAC3B,IAAIC,aACAxN,SAASuN,SAASC;YAEtB9P,GAAGY,KAAK0B,QAAQ,SAASyN,aAAaC;gBAClC,IAAIJ,OAAOG,iBAAiBzP,WAAW;oBACnCwP,OAAOC,eAAeH,OAAOG;;gBAGjCH,OAAOG,eAAeC;;YAG1B,OAAOJ;;QAMX5P,GAAG4J,UAAU,SAASqG,KAAKC,KAAKC;YAC5B,IAAIF,IAAIrG,SAAS;gBACb,OAAOqG,IAAIrG,QAAQsG,KAAKC;;YAG5BA,OAAOA,QAAQ;YACf,IAAIC,MAAMH,IAAI7L;YAEd,IAAI+L,OAAO,GAAG;gBACVA,QAAQC;;YAGZ,MAAOD,OAAOC,KAAKD,QAAQ,GAAG;gBAC1B,IAAIF,IAAII,eAAeF,SAASF,IAAIE,UAAUD,KAAK;oBAC/C,OAAOC;;;YAGf,QAAQ;;QAIZnQ,GAAGsQ,cAAc;YACb,OAAO,uCAAuCtJ,QAAQ,SAAS,SAASuJ;gBAEpE,IAAIC,IAAInK,KAAKoK,WAAW,KAAK,GAAGC,IAAIH,KAAK,MAAMC,IAAKA,IAAI,IAAM;gBAC9D,OAAOE,EAAElG,SAAS;;;QAM1BxK,GAAG2Q,KAAK;YACJ,OAAOC,UAAUC,UAAUjH,QAAQ,aAAa,KAC5CgH,UAAUC,UAAUjH,QAAQ,gBAAgB;;QAGpD5J,GAAG8Q,MAAM;YACL,OAAOF,UAAUC,UAAUjH,QAAQ,eAAe;;QAGtD5J,GAAG+Q,MAAM;YACL,OAAOH,UAAUC,UAAUjH,QAAQ,eAAe;;QAGtD5J,GAAGgR,OAAO;YACN,OAAOJ,UAAUC,UAAUjH,QAAQ,gBAAgB;;QAGvD5J,GAAGiR,OAAO;YACN,OAAOjR,GAAG2Q,QAAQC,UAAUC,UAAUjH,QAAQ,cAAc;;QAGhE5J,GAAGkR,OAAO;YACN,OAAON,UAAUC,UAAUjH,QAAQ,WAAW;;QAGlD5J,GAAGmR,SAAS;YACR,OAAOP,UAAUQ,WAAW9Q,aAAasQ,UAAUQ,OAAOxH,QAAQ,cAAc;;QAGpF5J,GAAGqR,SAAS;YACR,OAAOT,UAAUQ,WAAW9Q,aAAasQ,UAAUQ,OAAOxH,QAAQ,eAAe;;QAGrF5J,GAAGsR,QAAQ;YACP,OAAOV,UAAUQ,WAAW9Q,aAAasQ,UAAUQ,OAAOxH,QAAQ,cAAc;;QAGpF5J,GAAGuR,UAAU;YACT,QAASvR,GAAGkR,WAAWlR,GAAGiR,UAAUL,UAAUC,UAAUjH,QAAQ,gBAAgB,KAAKgH,UAAUQ,WAAW9Q,aAAasQ,UAAUQ,WAAW;;QAGhJpR,GAAGwR,UAAU;YACT,OAAOZ,UAAUa,aAAa;;QAGlCzR,GAAG0R,UAAU;YACT,OAAOd,UAAUC,UAAU9Q,cAAc6J,QAAQ,gBAAgB;;QAKrE5J,GAAG+N,eAAe;YACd,OAAO/N,GAAG0R,aAAad,UAAUC,UAAU9Q,cAAc6J,QAAQ,YAAY;;QAGjF5J,GAAG2R,OAAO;YACN,OAAO3R,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,eAAe;;QAGlE5J,GAAG6R,OAAO;YACN,OAAO7R,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,eAAe;;QAGlE5J,GAAG8R,OAAO;YACN,OAAO9R,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,eAAe;;QAIlE5J,GAAG+R,SAAS;YACR,OAAO/R,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,iBAAiB;;QAGpE5J,GAAG4R,MAAM;YAEL,OAAOhB,UAAUC,UAAUjH,QAAQ,aAAa,KACzCgH,UAAUC,UAAUjH,QAAQ,aAAa,KACzCgH,UAAUC,UAAUjH,QAAQ,eAAe;;QAGtD5J,GAAGgS,YAAY;YACX,OAAOhS,GAAG4R,SAAShB,UAAUC,UAAUjH,QAAQ,cAAc;;QAGjE5J,GAAGiS,YAAY;YACX,OAAOjS,GAAG4R,UAAU5R,GAAGgS,eAAepB,UAAUC,UAAUjH,QAAQ,eAAe;;QAGrF5J,GAAGkS,mBAAmB;YAClB,OAAOlS,GAAG4R,UAAU5R,GAAGgS,gBAAgBhS,GAAGiS;;QAM9CjS,GAAGmS,iBAAiB,SAASC;YACzB,IAAIA,EAAED,gBAAgB;gBAClBC,EAAED;mBACC;gBACHC,EAAEC,cAAc;;;QAQxBrS,GAAGsS,YAAa;YACZ,IAAIC,MAAMrF,SAASC,cAAc;YACjC,OAAO,SAASqF;gBACZD,IAAIE,YAAYD;gBAChB,IAAI9P,UAAU6P,IAAI5K;gBAClB4K,IAAIxM,YAAYrD;gBAChB,OAAOA;;;QAKf1C,GAAGY,OAAO,SAAS8R,cAAcC;YAC7B,IAAIC,YAAYpP;YAEhB,IAAIkP,cAAc;gBAEd,IAAIzJ,OAAO4J,WAAWH,aAAa9H,gBAAgB3B,OAAO4J,SAAS;oBAC/D,KAAKD,aAAa,GAAGA,aAAaF,aAAatO,QAAQwO,cAAc;wBACjEpP,SAASmP,SAASD,aAAavS,IAAIyS,aAAaF,aAAaI,QAAQJ,aAAavS,IAAIyS;wBACtF,IAAIpP,WAAW,OAAO;4BAClB;;;uBAMP,IAAIxD,GAAG6C,QAAQ6P,iBAAiB1S,GAAG6K,WAAW6H,iBAAiB1S,GAAG+K,WAAW2H,eAAe;oBAC7F,KAAKE,aAAa,GAAGA,aAAaF,aAAatO,QAAQwO,cAAc;wBACjEpP,SAASmP,SAASC,YAAYF,aAAaE;wBAC3C,IAAIpP,WAAW,OAAO;4BAClB;;;uBAIP,IAAIxD,GAAGmL,SAASuH,eAAe;oBAChC,KAAKE,aAAa,GAAGA,aAAaF,aAAatO,QAAQwO,cAAc;wBACjEpP,SAASmP,SAASC,YAAYF,aAAa9S,OAAOgT;wBAClD,IAAIpP,WAAW,OAAO;4BAClB;;;uBAIP;oBACD,KAAKoP,cAAcF,cAAc;wBAC7B,IAAInI,OAAOjJ,UAAU+O,eAAe9O,KAAKmR,cAAcE,aAAa;4BAChEpP,SAASmP,SAASC,YAAYF,aAAaE;4BAC3C,IAAIpP,WAAW,OAAO;gCAClB;;;;;;;QASxBxD,GAAG+S,OAAO,SAASC,SAASC;YACxB,IAAIjT,GAAGyK,WAAWuI,UAAU;gBACxB,IAAIpO,OAAQvD,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW;gBAElD,OAAO;oBACH,IAAI0R,UAAUlT,GAAGuG,WAAW3B;oBAC5B,IAAIpD,UAAU4C,QAAQ;wBAClB8O,UAAUA,QAAQC,OAAO9R,MAAMC,UAAUxB,MAAMyB,KAAKC;;oBAExD,OAAOwR,QAAQhR,MAAMiR,SAASC;;;YAItC,MAAM,IAAIhN,MAAM;;QAmBpBlG,GAAGoT,UAAU,SAASC,KAAKC,MAAMC;YAE7B,IAAIC,iBACAC,SAAS,KACTC,MAAM,SAASC,SAASC;gBACpB,IAAIC,WAAWP,OACR,QAAQ1M,KAAK0M,QACdA,OACAA,OAAO,MAAMM,IAAI,MACjBA;gBACN,IAAKC,aAAa,eAAiBD,MAAM,aAAc;oBACnDJ,WAAW1R,YACC6R,YAAY,WACd3T,GAAGoT,QAAQO,SAASE,UAAU,QAC7BtJ,OAAOjJ,UAAUkJ,SAASjJ,KAAKoS,aAAa,sBAC7CG,mBAAmBD,YAAY,MAAMC,mBAAmBH,aACxDG,mBAAmBD,YAAY,MAAMC,mBAAmBH;;;YAK9E,KAAKJ,cAAcD,MAAM;gBACrBG,SAAU,KAAK7M,KAAK0M,QAAU,MAAM1M,KAAK0M,QAAS,KAAK,MAAM;gBAC7DE,WAAW1R,KAAKwR;gBAChBE,WAAW1R,KAAK9B,GAAGoT,QAAQC;mBACxB,IAAK9I,OAAOjJ,UAAUkJ,SAASjJ,KAAK8R,SAAS,2BAA6BA,QAAQ,aAAc;gBACnGrT,GAAGY,KAAKyS,KAAK,SAASzR,KAAKxB;oBACvBsT,IAAItT,KAAKwB;;mBAEV,WAAYyR,QAAQ,eAAiBA,QAAQ,eAAiBA,QAAQ,UAAW;gBACpFrT,GAAGY,KAAKyS,KAAK,SAASvS,MAAMV;oBACxBsT,IAAItT,KAAKU;;mBAEV;gBACH0S,WAAW1R,KAAKgS,mBAAmBR,QAAQ,MAAMQ,mBAAmBT;;YAGxE,IAAIC,MAAM;gBACN,OAAOE,WAAWO,KAAKN;mBACpB;gBACH,OAAOD,WAAWO,KAAKN,QAClBzM,QAAQ,MAAM,IACdA,QAAQ,QAAQ;;;QAI7BhH,GAAGgU,eAAe,SAASX,KAAKY,UAAUC;YACtC,KAAKD,UAAU;gBACXA,WAAW,IAAI5G;;YAGnBrN,GAAGY,KAAKyS,KAAK,SAASlT,KAAKC;gBACvBD,MAAM+T,eAAeA,eAAe,MAAM/T,MAAM,MAAMA;gBAEtD,IAAIH,GAAGqK,SAASjK,MAAM;oBAClBJ,GAAGgU,aAAa5T,KAAK6T,UAAU9T;uBAE9B,IAAIH,GAAGyK,WAAWrK,MAAM;oBACzB6T,SAAS3K,OAAOnJ,KAAKC;uBAEpB;oBACD6T,SAAS3K,OAAOnJ,KAAKC;;;YAI7B,OAAO6T;;QAGXjU,GAAGmU,aAAa,SAASd,KAAKe;YAC1B,IAAInH;YAEJ,KAAKmH,MAAM;gBACPA,OAAOlH,SAASC,cAAc;;YAGlCnN,GAAGgU,aAAaX;gBACZ/J,QAAQ,SAASnJ,KAAKC;oBAClB6M,QAAQC,SAASC,cAAc;oBAC/BF,MAAMoH,aAAa,QAAQlU;oBAC3B8M,MAAMoH,aAAa,SAASjU;oBAC5BgU,KAAKE,YAAYrH;;;YAIzB,OAAOmH;;QAOXpU,GAAGuU,YAAY,SAASC;YAEpB,IAAIvL,OAAOwL,QAAQzU,GAAGyK,WAAWgK,KAAKC,QAAQ;gBAC1C,OAAOD,KAAKC,MAAMF;mBACf;gBACH,OAAOG,KAAK,MAAMH,OAAO;;;QAUjCxU,GAAG4U,eAAe,SAASC;YACvB,IAAIC,SAASD,SAASE,YAAY,OAAO;YAEzC,IAAID,SAAS,GAAG;gBACZ,OAAOD,SAASG,OAAOF,QAAQD,SAASzQ,SAAS0Q;;;QAIzD9U,GAAGiV,cAAc,SAASC;YAGtB,IAAIlV,GAAGuM,QAAQ2I,kBAAkB;gBAE7B,OAAOA,gBAAgBxK,MAAM1D,QAAQ,aAAa;mBAEjD,IAAIhH,GAAG+L,OAAOmJ,kBAAkB;gBACjC,IAAIA,gBAAgBC,aAAa,QAAQD,gBAAgBC,aAAa7U,WAAW;oBAC7E,OAAO4U,gBAAgBC;;;YAI/B,OAAOD,gBAAgBlU;;QAM3BhB,GAAGoV,iBAAiB;YAChB,IAAIC;YAEJ;gBAEIC,SAAS;oBACL,IAAIC;oBACJ,GAAG;wBACCA,WAAWF,UAAUG;wBACrB,IAAID,UAAU;4BACVA;;6BAGDA;;gBAIXrQ,QAAQ;oBACJ,IAAIN,OAAOpD;oBAEXS,KAAKwT,YAAYzV,GAAG4E,KAAK,IAAIM,OAAOlD,MAAMC,MAAMZ,MAAMC,UAAUxB,MAAMyB,KAAKC,WAAW;;gBAI1FiU,aAAa,SAASC;oBAClBL,UAAUvT,KAAK4T;;;;;KCt2B9B;QACG;QACA,WAAWC,WAAW,cAAcA,OAAOC,KAAK;YAC5CD,OAAO;gBACH,OAAO3V;;eAGV,WAAW6V,WAAW,eAAeA,OAAOC,SAAS;YACtDD,OAAOC,UAAU9V;eAEhB;YACDpB,OAAOoB,KAAKA;;;KCRnB;QACG;QAEAA,GAAGkG,QAAQ,SAAS7D;YAChBJ,KAAKI,UAAU,oBAAoBrC,GAAG+V,UAAU,OAAO1T;;QAG3DrC,GAAGkG,MAAM5E,YAAY,IAAI4E;;ICV7BlG,GAAG+V,UAAU;ICAb/V,GAAGgW,oBAAqB;QACpB;QAEA,IAAIC,mBACAC,wBACAC,kBACAC,2BACAC,oBACAC,kBACAC,gBACAC,wBACAC,oBACAC,uBACAC,2BACAC,wBACAC,yBACAC,uBACAC;QAEJ,SAASC;YACL,IAAIC,YAAY,MACZC;YAEJ;gBACIA,YAAYhK,SAASC,cAAc;gBACnC+J,UAAU/T,OAAO;gBACjBnD,GAAGkX,WAAWnS;gBAEd,IAAImS,UAAUC,UAAU;oBACpBF,YAAY;;cAGpB,OAAOG;gBACHH,YAAY;;YAGhB,OAAOA;;QAIX,SAASI;YACL,QAAQrX,GAAGqR,YAAYrR,GAAGsR,YACtBV,UAAUC,UAAUzN,MAAM,2CAA2C9C;;QAI7E,SAASgX;YACL,QAAQtX,GAAGqR,YAAYrR,GAAGsR,YACtBV,UAAUC,UAAUzN,MAAM,2CAA2C9C;;QAI7E,SAASiX;YACL,IAAItO,OAAOuE,gBAAgB;gBACvB,IAAIgK,MAAMxX,GAAGsN;gBAGb,OAAOkK,IAAIC,oBAAoBnX;;YAGnC,OAAO;;QAIX,SAASoX;YACL,OAAOzO,OAAO0O,mBAAmBrX;;QAKrC,SAASsX;YACL,IAAIL,6BAA6B;gBAC7B,OAAO;;YAGX,OAAOG;;QAGX,SAASG;YAEL,OAAO3K,SAASC,cAAc,SAAS2K,oBAAoBxX;;QAG/D,SAASyX;YACL;gBACI,SAAS9O,OAAO+O,gBAEZhY,GAAGyK,WAAWxB,OAAO+O,aAAaC;cAE1C,OAAO9V;gBAEH,OAAO;;;QAIf,SAAS+V;YACL,IAAIC,OAAOjL,SAASC,cAAc;YAElC,QAAQ,eAAegL,QAAS,iBAAiBA,QAAQ,YAAYA,UAChEnY,GAAG0R,cAAc1R,GAAG4R;;QAG7BqE,oBAAoBe;QAEpBZ,4BAA4BH,qBAAqBjW,GAAGgN;QAEpDkJ,yBAAyBE,8BAA8BpW,GAAG+N;QAE1DoI,mBAAmBC,6BAA6B8B;QAEhD7B,qBAAqBF,oBAAoBkB;QAEzCf,mBAAmBF,6BAA6BpW,GAAG8N;QAEnDyI,iBAAiBH,6BAA6BE,oBAAoByB;QAElEvB,yBAAyBJ,6BAA6BkB;QAEtDb,qBAAqBR,sBAAsBhN,OAAOmP,gBAAgB9X,aAAa8V;QAE/EO,4BAA4BY;QAE5Bb,wBAAwBgB;QAExBd,yBAAyBgB;QAEzBf,0BAA0BgB;QAE1Bf,wBAAwBV,6BAA6BnN,OAAOgG,eAAe3O;QAE3EyW,yBAA0B;YACtB,IAAIX,2BAA2B;gBAC3B,QAAQpW,GAAG+N,mBAAmB/N,GAAGgS;;YAErC,OAAO;;QAGX;YACIqG,eAAejC;YACfkC,eAAepC;YACfqC,kBAAkBnC;YAClBoC,UAAUlC;YACVmC,gBAAgB7B;YAChB8B,mBAAmBhC;YACnBiC,mBAAmBhC;YACnBiC,iBAAiB3P,OAAO4P;YACxBC,UAAU3C;YACV4C,YAAY1C;YACZ2C,iBAAiBnC;YACjBoC,eAAenC;YACfoC,iBAAiBpC;YACjBqC,oBAAoB/C;YACpBgD,OAAO9C;YACP+C,aAAatC;YACbuC,QAAQ/C;YACRgD,SAASzC,yBAAyBZ;YAClCsD,cAAcxZ,GAAGmR;YACjBsI,2BAA2BzZ,GAAG4R;YAC9B8H,WAAWzD;YACX0D,YAAYlD;YACZmD,qBAAqBxD;YACrByD,oBAAoBzD;YACpB0D,gBAAgBtD;;;IChKxBxW,GAAG+Z,mBAAmB,SAASC;QAC3B;QACA,UAAUA,gBAAgBA,aAAaC,QAAQja,GAAGyK,WAAWuP,aAAaC;;IAG9Eja,GAAGmP,UAAU;QACT;QAEA,IAAI+K,aAAaC,aACbC,uBACAC,uBACAC,oBACAC,QAAQ;QAEZva,GAAGuG,OAAOtE;YACNgY,MAAM,SAASO,WAAWC;gBACtB,IAAIF,UAAU,GAAG;oBACb,IAAIC,WAAW;wBACXJ,iBAAiBtY,KAAK0Y;;oBAE1B,IAAIC,WAAW;wBACXJ,iBAAiBvY,KAAK2Y;;uBAGzB,IAAIF,WAAW,GAAG;oBACnBE,aAAaA,UAAUzY,MAAM,MAAMmY;uBAElC,IAAIK,WAAW;oBAChBA,UAAUxY,MAAM,MAAMkY;;gBAG1B,OAAOjY;;YAGXyY,MAAM,SAAS/H;gBACX,IAAI4H,UAAU,GAAG;oBACbD,cAAcxY,KAAK6Q;uBAElB;oBACDA,SAAS3Q,MAAM,MAAMmY,gBAAgB7Z,YAAY4Z,cAAcC;;gBAGnE,OAAOlY;;YAGXoN,SAAS;gBACLkL,QAAQ;gBACRL,cAAc1Y;gBAEd,IAAI4Y,iBAAiBhW,QAAQ;oBACzBpE,GAAGY,KAAKwZ,kBAAkB,SAASxY,KAAK+Q;wBACpCA,SAAS3Q,MAAM,MAAMkY;;;gBAI7B,IAAII,cAAclW,QAAQ;oBACtBpE,GAAGY,KAAK0Z,eAAe,SAAS1Y,KAAK+Q;wBACjCA,SAAS3Q,MAAM,MAAMkY;;;gBAI7B,OAAOjY;;YAGXsN,SAAS;gBACLgL,SAAS;gBACTJ,cAAc3Y;gBAEd,IAAI6Y,iBAAiBjW,QAAQ;oBACzBpE,GAAGY,KAAKyZ,kBAAkB,SAASzY,KAAK+Q;wBACpCA,SAAS3Q,MAAM,MAAMmY;;;gBAI7B,IAAIG,cAAclW,QAAQ;oBACtBpE,GAAGY,KAAK0Z,eAAe,SAAS1Y,KAAK+Q;wBACjCA,SAAS3Q,MAAM,MAAMmY;;;gBAI7B,OAAOlY;;;;IC3EnBjC,GAAG2a,YAAY,SAASC,eAAeC;QACnC;QAEA7a,GAAGuG,OAAOtE;YACN2Y,eAAeA;YAEfE,QAAQ;gBACJ,OAAOD,SAASD;;;;ICF5B5a,GAAG+a,eAAe,SAASC;QACvB;QAEA,IAAIjX,OAAO9B,MAEPgZ,iBAAiB,IAAIjb,GAAGoV,kBAExBnW;YAEIic,aAAa;YAGbxY,SAAS;YAETyY,YAAY;YAGZC,SAAS;YAGTC,YAAY;YAEZC,4BAA4B;YAG5BlO,UAAU;YAGVpM,MAAM;YAGNua,UAAU,SAAStO;YAEnBuO,OAAO;WAEXvO,OAAOwO;QAGXzb,GAAGuG,OAAOtH,SAAS+b;QAEnBS,WAAWzb,GAAGsQ;QAGd,SAASoL;YACL,IAAIzO,QAAQC,SAASC,cAAc;YAEnCF,MAAMoH,aAAarU,GAAG+a,aAAaY,qBAAqBF;YACxDxO,MAAMoH,aAAa,SAASpV,QAAQuc;YAEpCzX,KAAK6X,YAAY3c,QAAQmO,UAAUH;YAEnC,IAAIhO,QAAQmc,WAAWpb,GAAGgW,kBAAkBgD,iBAAiB;gBAEzD/L,MAAMoH,aAAa,mBAAmB;;YAG1C,IAAIpV,QAAQic,aAAa;gBACrBjO,MAAMoH,aAAa,UAAUpV,QAAQic;;YAGzCjO,MAAMoH,aAAa,QAAQ;YAC3BpH,MAAMoH,aAAa,QAAQpV,QAAQ+B;YAEnChB,GAAGiN,OAAOjH;gBACN6V,UAAU;gBAIVC,OAAO;gBACPC,KAAK;gBACLC,YAAY;gBASZC,UAAUjc,GAAG2Q,SAAS3Q,GAAG+Q,QAAQ,WAAW;gBAC5CmL,QAAQ;gBACRC,SAAS;gBACTC,QAAQ;gBACRjW,SAAS;;aAKZnG,GAAG8Q,SAAS9Q,GAAGiN,OAAOjH;gBAAKqW,QAAQ;;YAEpCpd,QAAQyD,QAAQ4R,YAAYrH;YAE5BgO,eAAe/V,OAAO+H,OAAO,UAAU;gBACnChO,QAAQsc,SAAStO;;YAIrBgO,eAAe/V,OAAO+H,OAAO,aAAa;gBACtCjN,GAAGf,QAAQyD,SAASoE,SAAS7H,QAAQoc;;YAEzCJ,eAAe/V,OAAO+H,OAAO,YAAY;gBACrCjN,GAAGf,QAAQyD,SAASqE,YAAY9H,QAAQoc;;YAG5CJ,eAAe/V,OAAO+H,OAAO,SAAS;gBAClCjN,GAAGf,QAAQyD,SAASoE,SAAS7H,QAAQkc;;YAEzCF,eAAe/V,OAAO+H,OAAO,QAAQ;gBACjCjN,GAAGf,QAAQyD,SAASqE,YAAY9H,QAAQkc;;YAG5C,OAAOlO;;QAIXjN,GAAGf,QAAQyD,SAASsD;YAChB6V,UAAU;YACVS,UAAU;YAEVC,WAAW;;QAIfvc,GAAGuG,OAAOtE;YACNua,UAAU;gBACN,OAAOvP;;YAGXwP,aAAa;gBACT,OAAOhB;;YAGXG,aAAa,SAASc,YAAYC;gBAC9B,IAAI1P,QAAQ0P,YAAY1a,KAAKua;gBAK7B,IAAIvd,QAAQqc,8BAA8Btb,GAAG8R,WAAW9R,GAAGgS,eAAehS,GAAGkS,qBAAqB;oBAC9FjF,MAAMoH,aAAa,YAAY;uBAG9B;oBACD,IAAIqI,YAAY;wBACZzP,MAAMoH,aAAa,YAAY;2BAE9B;wBACDpH,MAAM2P,gBAAgB;;;;YAKlCC,gBAAgB,SAAS3B;gBACrB,IAAIA,gBAAgBjc,QAAQic,aAAa;oBACrCjO,MAAMoH,aAAa,UAAU6G;;;YAIrC4B,OAAO;gBACH,IAAI7P,MAAMpH,YAAY;oBAClB7F,GAAGiN,OAAOnH;;gBAGd9F,GAAGf,QAAQyD,SAASqE,YAAY9H,QAAQkc;gBACxClO,QAAQ;gBACRA,QAAQyO;;;QAIhBzO,QAAQyO;;IAGZ1b,GAAG+a,aAAaY,sBAAsB;ICxLtC3b,GAAG+c,aAAa,SAASC;QACrB;QAEA,IAAI3c,WACA4c,aACAC,eACAC,qBACAC;QAEJ,SAASC,aAAaC;YAClB,IAAItd,GAAG6C,QAAQya,UAAU;gBACrB,IAAIC;gBAEJvd,GAAGY,KAAK0c,SAAS,SAAS1b,KAAK4b;oBAC3BD,QAAQzb,KAAKzB,KAAKmd;;gBAGtB,OAAOD;;YAGX,OAAOld,KAAKid;;QAGhB,SAASG,eAAeC;YACpB,IAAI1d,GAAG6C,QAAQ6a,QAAQ;gBACnB,IAAIH;gBAEJvd,GAAGY,KAAK8c,OAAO,SAAS9b,KAAK+b;oBACzBJ,QAAQzb,KAAKzB,KAAK4c,OAAOU;;gBAG7B,OAAOJ;;YAGX,OAAOld,KAAK4c,OAAOS;;QAGvB,SAASE,gBAAgBC;YACrB,IAAIC,oBACAC,cAAc5K,OAAO0K;YAEzB7d,GAAGY,KAAKmd,UAAU,SAAS7Z,OAAO8Z;gBAC9B,IAAIC,sBAAsBf,SAASc;gBAEnC,IAAIC,wBAAwB3d,WAAW;oBACnCN,GAAGY,KAAKqd,qBAAqB,SAASrK,GAAGsK;wBACrCJ,cAAchc,KAAKzB,KAAK6d;;;;YAKpC,OAAOJ;;QAGX9d,GAAGuG,OAAOtE;YAeNkc,SAAS,SAASC;gBACd,IAAIP,SAASO,KAAKP,UAAU7d,GAAG6d,OAAOQ,YAClCb,KAAKnd,KAAKyB;oBACNd,MAAMod,KAAKpd;oBACXsd,cAAcF,KAAKpd;oBACnB2c,MAAMS,KAAKT;oBACXY,MAAMH,KAAKG,QAAQ,QAAQ,IAAIH,KAAKG;oBACpCV,QAAQA;qBACP;gBAET,IAAIO,KAAKI,SAAS;oBACdne,KAAKmd,IAAIgB,UAAUJ,KAAKI;oBAExB,IAAIpB,UAAUgB,KAAKI,aAAale,WAAW;wBACvC8c,UAAUgB,KAAKI;;oBAEnBpB,UAAUgB,KAAKI,SAAS1c,KAAK0b;;gBAGjC,IAAIY,KAAKK,cAAc;oBACnBpe,KAAKmd,IAAIiB,eAAeL,KAAKK;oBAE7B,IAAItB,eAAeiB,KAAKK,kBAAkBne,WAAW;wBACjD6c,eAAeiB,KAAKK;;oBAExBtB,eAAeiB,KAAKK,cAAc3c,KAAK0b;;gBAG3Cnd,KAAKmd,IAAIA,KAAKA;gBACdP,OAAOmB,KAAKT,QAAQH;gBAEpB,IAAIN,SAASW,YAAYvd,WAAW;oBAChC4c,SAASW;;gBAEbX,SAASW,QAAQ/b,KAAK0b;gBAEtBR,cAAc0B,eAAelB,IAAI,MAAMK;gBAEvC,OAAOL;;YAGXmB,UAAU,SAASC;gBACf,IAAI5e,GAAGqK,SAASuU,mBAAmBve,KAAK+D,QAAS;oBAC7C,IAAIwa,eAAepB,OAAOld,WAAW;wBACjC,OAAO+c,aAAauB,eAAepB;2BAGlC,IAAIoB,eAAejB,SAASrd,WAAW;wBACxC,OAAOmd,eAAemB,eAAejB;2BAGpC,IAAIiB,eAAef,QAAQ;wBAC5B,OAAOD,gBAAgBgB,eAAef;;uBAGzC;oBACD,OAAO7d,GAAGuG,WAAWlG,MAAM;;;YAInCyc,OAAO;gBACHzc;gBACA4c;gBACAC;gBACAE;;YAGJyB,WAAW,SAASrB,IAAIsB;gBACpB,IAAIC,YAAY1e,KAAKmd,IAAIK,QACrBmB,yBAAyBhf,GAAG4J,QAAQsT,SAAS6B,YAAYvB;gBAE7DN,SAAS6B,WAAWE,OAAOD,wBAAwB;gBAEnD3e,KAAKmd,IAAIK,SAASiB;gBAElB,IAAI5B,SAAS4B,eAAexe,WAAW;oBACnC4c,SAAS4B;;gBAEb5B,SAAS4B,WAAWhd,KAAK0b;gBAEzBR,cAAc0B,eAAelB,IAAIuB,WAAWD;;YAGhDI,aAAa,SAAS1B,IAAI2B;gBACtB,IAAIC,UAAU/e,KAAKmd,IAAIG;gBAEvBtd,KAAKmd,IAAIG,OAAOwB;gBAChBlC,OAAOkC,WAAW3B;uBACXP,OAAOmC;;YAGlBC,YAAY,SAAS7B,IAAI8B;gBACrBjf,KAAKmd,IAAIxc,OAAOse;;YAGpBC,YAAY,SAAS/B,IAAIgC;gBACrBnf,KAAKmd,IAAIe,OAAOiB;;YAIpBC,aAAa,SAASC,UAAUC;gBAC5Btf,KAAKqf,UAAUC,WAAWA;;YAG9BC,oBAAoB,SAASpC;gBACzB,IAAIiB,eAAepe,KAAKmd,IAAIiB;gBAE5B,IAAIA,cAAc;oBACd,OAAOtB,eAAesB;;gBAE1B;;YAGJoB,eAAe,SAASrC;gBACpB,IAAIgB,UAAUne,KAAKmd,IAAIgB;gBAEvB,OAAOpB,UAAUoB;;;;IAK7Bxe,GAAG6d;QACCQ,YAAY;QACZyB,WAAW;QACXC,UAAU;QACVC,QAAQ;QACRC,UAAU;QACVC,QAAQ;QACRC,WAAW;QACXC,iBAAiB;QACjBC,mBAAmB;QACnBC,eAAe;QACfC,eAAe;QACfC,UAAU;QACVC,SAAS;;KCxMZ;QACG;QAEAzgB,GAAG0gB;YAECC,UAAU,SAASC,iBAAiBphB,QAAQqhB;gBACxC5e,KAAK6e,SAASF,iBAAiBphB,QAAQqhB;;YAG3CE,iBAAiB,SAASC;gBACtB,IAAIjd,OAAO9B;gBAEXjC,GAAGY,KAAKogB,gBAAgB,SAAS9c,OAAO+c;oBACpCld,KAAKmd,eAAeD;;;YAI5BH,UAAU,SAASzgB,MAAMb,QAAQqhB;gBAC7B5e,KAAKkf;gBAEL,IAAI3C,UAAUvc,KAAKmf,WAAWhd,WAAW,IAAIpE,GAAGsQ,gBAAgBrO,KAAKof,iBAEjEC,cAActhB,GAAG+S,KAAK,SAASlE;oBAC3B5M,KAAKsf;wBACD1S,MAAMA;wBACN7N,MAAMiB,KAAKpB,SAAS2gB,MAAMC;uBAC3BjD,SAASkD;mBACbzf,OAEH0f,kBAAkB3hB,GAAG+S,KAAK,SAAS6O;oBAC/B3f,KAAKsf,eAAeK,UAAUpD,SAASkD;mBACxCzf,OAEH4f,gBAAgB7hB,GAAG+S,KAAK,SAASxK;oBAC7B,IAAIsG,OAAO7O,GAAGsI,aAAaC;oBAE3BtG,KAAKsf;wBACD1S,MAAMA;wBACN7N,MAAMiB,KAAKpB,SAAS2gB,MAAMC,cAAc;uBACzCjD,SAASkD;mBACbzf,OAEH6f,oBAAoB9hB,GAAG+S,KAAK,SAASgP;oBACjC,IAAIC,oBAAoBD,WAAWtZ,WAAWsZ,WAAWtZ,UAAU,KAC/DoG,OAAO7O,GAAGsI,aAAayZ,WAAWxZ,QAAQwZ,WAAW5e,MAAM6e;oBAE/D/f,KAAKsf;wBACD1S,MAAMA;wBACN7N,MAAM+gB,WAAW/gB;uBAClBwd,SAASkD;mBACbzf,OAEHggB,qBAAqBjiB,GAAG+S,KAAK,SAASmP;oBAClC,IAAIliB,GAAGuM,QAAQ2V,gBAAgBliB,GAAGgW,kBAAkBqC,eAAe;wBAC/D,IAAI8J,QAAQ9gB,MAAMC,UAAUxB,MAAMyB,KAAK2gB,YAAYC,QAC/Cpe,OAAO9B;wBAEXjC,GAAGY,KAAKuhB,OAAO,SAASvgB,KAAKwgB;4BACzBre,KAAKwd,eAAea,MAAM5D,SAASkD;;2BAGtC;wBACDzf,KAAKsf,eAAeW,aAAa1D,SAASkD;;mBAE/Czf,OAEHogB,gBAAgB;oBACZ,IAAIriB,GAAGkM,WAAW7L,OAAO;wBACrBA,OAAOgB,MAAMC,UAAUxB,MAAMyB,KAAKlB;;oBAEtCA,UAAU8S,OAAO9S;mBAGrB0D,OAAO9B,MACPyf;gBAEJzf,KAAKof,kBAAkB7C;gBAEvB,IAAIne,MAAM;oBACNgiB;oBAEAriB,GAAGY,KAAKP,MAAM,SAASuB,KAAK0gB;wBACxB,IAAItiB,GAAGqM,cAAciW,gBAAgB;4BACjCL,mBAAmBK;+BAElB,IAAItiB,GAAG8M,OAAOwV,gBAAgB;4BAC/BhB,YAAYgB;+BAEX,IAAItiB,GAAGqK,SAASiY,gBAAgB;4BACjC,IAAIA,cAAczT,QAAQyT,cAActhB,MAAM;gCAC1C2gB,gBAAgBW;mCAEf,IAAIA,cAAc/Z,UAAU+Z,cAActhB,MAAM;gCACjD8gB,kBAAkBQ;;+BAGrB,IAAIA,cAAczV,WAAWyV,cAAczV,QAAQ9M,kBAAkB,UAAU;4BAChF8hB,cAAcS;+BAEb;4BACDve,KAAK3B,IAAIkgB,gBAAgB,8CAA8C;;;oBAI/ErgB,KAAKG,IAAI,cAAcsf,cAActd,SAAS;oBAC9CnC,KAAKsgB,uBAAuBb,eAAeliB,QAAQqhB;;;YAI3D2B,QAAQ,SAAShF;gBACbvb,KAAKwgB,SAASD,OAAOhF;;YAGzBkF,WAAW;gBACP,IAAIC,oBACA5e,OAAO9B;gBAEXjC,GAAGuG,OAAOoc,eAAe1gB,KAAKmf;gBAC9BphB,GAAGY,KAAK+hB,eAAe,SAAS/gB,KAAKghB;oBACjC7e,KAAKye,OAAOI;;gBAGhB3gB,KAAKwgB,SAASC;;YAGlBG,kBAAkB;gBACd5gB,KAAKmf;;YAGT0B,gBAAgB,SAAStF;gBACrB,IAAIuF,aAAa9gB,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;;gBAEhD,KAAKxd,GAAGgW,kBAAkBoD,UAAUnX,KAAKpB,SAAS2X,SAASyK,SAAS;oBAChE,OAAO;;gBAGX,IAAIF,WAAWlF,WAAW7d,GAAG6d,OAAOqC,QAAQ;oBACxCje,KAAKG,IAAIpC,GAAGyL,OAAO,0DAA0D+R,IAAIvb,KAAKihB,QAAQ1F;oBAC9Fvb,KAAKkhB,YAAY3F;oBACjB,OAAO;uBAEN;oBACDvb,KAAKG,IAAIpC,GAAGyL,OAAO,uDAAuD+R,IAAIvb,KAAKihB,QAAQ1F,MAAM;;gBAGrG,OAAO;;YAGX4F,YAAY,SAAS5F;gBACjB,OAAOvb,KAAKohB,gBAAgB7F;;YAIhC8F,WAAW,SAASC;gBAChB,OAAOthB,KAAKwgB,SAASe,QAAQD;;YAOjCE,eAAe,SAASC,QAAQC,aAAaC,SAASC,YAAYC;gBAC9D,IAAIC,kBAAkB,IAAI/jB,GAAGmP,WACzB6U,WAAW/kB;gBAEf,IAAIgD,KAAKgiB,iBAAiB;oBACtBD,YAAY/hB,KAAKiiB,eAAeR;oBAChCzkB;wBACI6kB,sBAAsBA;wBACtBF,SAASA,UAAU,IAAIA,UAAU;wBACjCO,OAAOP,UAAU;;oBAKrB,KAAKC,cAAc7jB,GAAGgW,kBAAkBiD,eAAe;wBACnD+K,YAAY/hB,KAAKmiB,QAAQV;;oBAI7B,IAAIM,aAAa,MAAM;wBACnBD,gBAAgBxU;4BAAS8U,WAAWV;4BAAaxhB,OAAO;;2BAEvD;wBACDF,KAAKgiB,gBAAgBK,SAASN,WAAWL,aAAa1kB,SAASgb,KAC3D,SAAS5K,QAAQkV;4BACbR,gBAAgB1U,QAAQkV;2BAG5B,SAAShV,QAAQ8U,WAAWG;4BACxBT,gBAAgBxU;gCAAS8U,WAAWA;gCAAWliB,OAAOqiB,UAAU;;;;uBAK3E;oBACDT,gBAAgBxU;wBAAS8U,WAAWV;wBAAaxhB,OAAO;;;gBAG5D,OAAO4hB;;YAGXU,WAAW,SAASf;gBAChB,OAAOzhB,KAAKyiB,WAAWziB,KAAK0iB,qBAAqBjB;;YAGrDkB,aAAa,SAASlB;gBAClB,OAAOzhB,KAAK4iB,eAAeC,IAAIpB;;YAGnCU,SAAS,SAASb;gBACd,OAAOthB,KAAKwgB,SAAS2B,QAAQb,iBAAiB;;YAGlDwB,eAAe;gBACX,OAAO9iB,KAAK+gB,YAAYrE;oBACpBd,UACI7d,GAAG6d,OAAOsC,WACVngB,GAAG6d,OAAOuC,iBACVpgB,GAAG6d,OAAOmC;mBAEf5b;;YAGP8e,SAAS,SAAS1F;gBACd,OAAOvb,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;mBAAKxc;;YAI/CgkB,aAAa,SAASxH;gBAClB,IAAIyH,kBAAkBhjB,KAAKijB;oBAAY1H,IAAIA;oBACvCmC,WAAW;gBAEf,IAAIsF,iBAAiB;oBACjB,IAAIA,gBAAgBtF,aAAarf,WAAW;wBACxCqf,WAAWsF,gBAAgBtF;;;gBAInC,OAAOA;;YAGXwF,uBAAuB;gBACnB,OAAOljB,KAAKwgB,SAAS0C;;YAGzBC,SAAS,SAAS5H;gBACd,OAAOvb,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;mBAAKe;;YAG/C8G,eAAe;gBACX,OAAOpjB,KAAKqjB;;YAGhBC,0BAA0B;gBACtB,IAAIC,eAAevjB,KAAKwjB;gBAExB,IAAID,eAAe,GAAG;oBAClB,OAAOA,eAAevjB,KAAKyjB;;gBAG/B,OAAO;;YAGXR,YAAY,SAAStG;gBACjB,OAAO3c,KAAK+gB,YAAYrE,SAASC;;YAGrC+G,SAAS,SAASnI;gBACd,OAAOvb,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;mBAAKG;;YAG/Cvb,KAAK,SAASsJ,KAAKvB;gBACf,IAAIlI,KAAKpB,SAAS+kB,WAAWzb,SAASA,UAAU,SAAS;oBACrDnK,GAAGoC,IAAI,oBAAoBpC,GAAG+V,UAAU,OAAOrK;uBAE9C,IAAIvB,SAASA,UAAU,QAAQ;oBAChCnK,GAAGoC,IAAI,oBAAoBpC,GAAG+V,UAAU,OAAOrK,KAAKvB;;;YAK5D0b,aAAa,SAASrI;gBAClB,IAAIuF,aAAa9gB,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;;gBAEhD,KAAKxd,GAAGgW,kBAAkBoD,UAAUnX,KAAKpB,SAAS2X,SAASyK,SAAS;oBAChE,OAAO;;gBAIX,IAAIjjB,GAAG4J,UAAS5J,GAAG6d,OAAOsC,WAAWngB,GAAG6d,OAAOuC,mBAAkB2C,WAAWlF,WAAW,GAAG;oBACtF,IAAI5b,KAAKwgB,SAASrJ,MAAMoE,KAAK;wBACzBvb,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOqC;wBACzC,OAAO;2BAEN;wBACDje,KAAKG,IAAIpC,GAAGyL,OAAO,oCAAoC+R,IAAIvb,KAAKihB,QAAQ1F,MAAM;;uBAGjF;oBACDvb,KAAKG,IAAIpC,GAAGyL,OAAO,yDAAyD+R,IAAIvb,KAAKihB,QAAQ1F,MAAM;;gBAGvG,OAAO;;YAGXV,OAAO;gBACH7a,KAAKG,IAAI;gBAETH,KAAKwgB,SAAS3F;gBACd7a,KAAKmf;gBACLnf,KAAK6jB;gBACL7jB,KAAK8jB;gBACL9jB,KAAK+jB;gBACL/jB,KAAKiiB;gBAELlkB,GAAGY,KAAKqB,KAAKgkB,UAAU,SAASrkB,KAAKskB;oBACjCA,OAAOpJ;;gBAGX7a,KAAKkkB,aAAarJ;gBAClB7a,KAAK4iB,eAAe/H;gBACpB7a,KAAKyjB,uBAAuB;gBAC5BzjB,KAAKqjB,eAAe;gBACpBrjB,KAAK+gB,YAAYlG;gBACjB7a,KAAK0iB;gBAEL1iB,KAAKmkB,iBAAiBnkB,KAAKmkB,cAActJ;gBACzC7a,KAAKpB,SAASwlB,QAAQC,kBAAkBrkB,KAAKskB;gBAE7CtkB,KAAKukB;gBACLvkB,KAAKwkB;gBAELxkB,KAAKykB,kBAAkBzkB,KAAKykB,eAAe5J;;YAG/C6J,OAAO,SAASnJ;gBACZ,OAAOvb,KAAK2kB,aAAapJ;;YAG7BqJ,YAAY,SAASrJ,IAAIsJ;gBACrB,IAAI/iB,OAAO9B;gBAEX,OAAOjC,GAAG+mB,OAAOzlB,UAAUulB,WAAWrJ,IAAIsJ;oBACtC1kB,KAAKpC,GAAG+S,KAAKhP,KAAK3B,KAAK2B;oBACvBqgB,SAASpkB,GAAG+S,KAAKhP,KAAKqgB,SAASrgB;oBAC/Bgf,YAAYhf,KAAKif;;;YAIzBgE,kBAAkB,SAASC,SAASzJ;gBAChCvb,KAAKilB,oBAAoBC,IAAIF,SAASzJ;;YAG1C4J,4BAA4B,SAASH,SAASzJ;gBAC1Cvb,KAAKolB,8BAA8BF,IAAIF,SAASzJ;;YAGpD8J,uBAAuB,SAASzG,UAAUrD;gBACtCvb,KAAKslB,yBAAyBJ,IAAItG,UAAUrD;;YAGhDgK,qBAAqB,SAAShoB,QAAQge;gBAClCvb,KAAKwlB,uBAAuBN,IAAI3nB,QAAQge;;YAI5CkK,aAAa,SAAS7G,UAAUrD;gBAC5Bvb,KAAK4iB,eAAesC,IAAItG,UAAUrD;;YAGtCmK,SAAS,SAASC;gBACd3lB,KAAK4lB,4BAA4BD;;YAGrCE,cAAc,SAASC;gBACnB9lB,KAAKwjB,oBAAoBsC;;YAG7BC,SAAS,SAASxK,IAAI8B;gBAClBrd,KAAK+gB,YAAY3D,WAAW7B,IAAI8B;;YAGpC2I,WAAW,SAASzoB,QAAQge;gBACxBvb,KAAKkkB,aAAagB,IAAI3nB,QAAQge;;YAGlC0K,SAAS,SAAS1K,IAAI2B;gBAClB,OAAOld,KAAK+gB,YAAY9D,YAAY1B,IAAI2B;;YAG5CgJ,mBAAmB;gBACf,IAAIlmB,KAAKmf,WAAWhd,WAAW,GAAG;oBAC9BnC,KAAKmmB,WAAW;uBAEf;oBACDnmB,KAAKomB;;;;QAQjBroB,GAAGsoB;YAECpH,gBAAgB,SAASqH;gBACrB,IAAI/K,KAAKvb,KAAK+gB,YAAY7E;oBACtBR,MAAM4K,YAAY5K;oBAClB3c,MAAMunB,YAAYvnB;oBAClBud,MAAMgK,YAAYhK;oBAClBV,QAAQ7d,GAAG6d,OAAOwC;;gBAGtBkI,YAAYC,sBAAsBvmB,KAAKqlB,sBAAsBiB,YAAYC,oBAAoBhL;gBAC7F+K,YAAYE,oBAAoBxmB,KAAKulB,oBAAoBe,YAAYE,kBAAkBjL;gBAEvF,IAAI+K,YAAYG,cAAc;oBAC1BzmB,KAAKiiB,eAAe1G,MAAM+K,YAAYG;;gBAG1CzmB,KAAKqjB;gBACLrjB,KAAKyjB;gBAEL,OAAOlI;;YAGXmL,uBAAuB,SAASvG,MAAMwG;gBAClC,IAAI5oB,GAAG+L,OAAOqW,OAAO;oBACjBA,KAAKyG,aAAa5mB,KAAK6mB,aAAaF;;;YAI5CG,aAAa,SAAS1mB;gBAClBJ,KAAKpB,SAASF,UAAUqoB,QAAQ,MAAM,MAAM3mB,SAAS/B;;YAGzD2oB,sBAAsB;gBAClB,IAAIllB,OAAO9B;gBAEX,OAAO,IAAIjC,GAAGkpB;oBACVC,QAAQlnB,KAAKpB,SAASuiB,WAAW+F,OAAOtpB;oBACxCupB,gBAAgBnnB,KAAKpB,SAASuoB;oBAC9BC,eAAepnB,KAAKpB,SAASyoB,QAAQC;oBACrCC,eAAevnB,KAAKolB;oBACpBoC,aAAaxnB,KAAKwlB;oBAClBiC,eAAeznB,KAAKslB;oBACpBoC,MAAM1nB,KAAKpB,SAAS8oB;oBACpBvnB,KAAKpC,GAAG+S,KAAKhP,KAAK3B,KAAK2B;oBACvB6lB,UAAU,SAASpM;wBACfzZ,KAAK8lB,UAAUrM;wBACfzZ,KAAKlD,SAASF,UAAUipB,SAASpM;;oBAErCsM,kBAAkB,SAAStM,IAAIuM,UAAUC;wBACrCjmB,KAAKkmB,kBAAkBzM,IAAIuM,UAAUC;wBACrCjmB,KAAKlD,SAASF,UAAUmpB,iBAAiBtM,IAAIuM,UAAUC;;;;YAMnEE,qBAAqB;gBACjB,IAAInmB,OAAO9B;gBAEX,OAAO,IAAIjC,GAAGmqB;oBACVC,eAAenoB,KAAKpB,SAASwpB,MAAMD;oBACnCzpB;wBACIyB,KAAKpC,GAAG+S,KAAKhP,KAAK3B,KAAK2B;wBACvBumB,eAAe,SAASzb;4BACpB9K,KAAKwmB;gCACDvpB,MAAM;gCACN2R,UAAU3S,GAAG+S,KAAKhP,KAAKlD,SAASF,UAAU6pB,iBAAiBzmB,MAAM8K;gCACjE2L,WAAWxa,GAAG+S,KAAKhP,KAAK0mB,qBAAqB1mB,MAAM8K;gCACnD6b,YAAY;;;;;;YAOhCC,cAAc,SAASC,cAAcC;gBACjC,IAAIC,YACAC,WAAWH,cACXI,0BACAC,iBAAiBJ,kBACjBK,OAAO,SAASC;oBACZ,IAAInrB,GAAGqK,SAAS8gB,OAAO;wBACnB,OAAOnrB,GAAGuG,WAAW4kB;;oBAEzB,OAAOA;mBAEXC,oBAAoB;oBAChB,IAAIprB,GAAGyK,WAAWwgB,iBAAiB;wBAC/B,OAAOA;;oBAEX,OAAOA;mBAEXI,wBAAwB,SAAS7N,IAAI8N;oBACjC,IAAIL,kBAAkBjrB,GAAGqK,SAASihB,WAAW;wBACzCtrB,GAAGuG,OAAO+kB,UAAUF;;oBAGxB,IAAIJ,oBAAoBxN,KAAK;wBACzBxd,GAAGuG,OAAO+kB,UAAUN,oBAAoBxN;;;gBAIpD;oBACI2J,KAAK,SAAS/mB,KAAKod;wBAEf,IAAIA,MAAM,MAAM;4BACZsN;4BACAC,WAAWG,KAAK9qB;+BAEf;4BACD0qB,MAAMtN,MAAM0N,KAAK9qB;;;oBAIzB0kB,KAAK,SAAStH;wBACV,IAAI+N;wBAGJ,IAAI/N,MAAM,QAAQsN,MAAMtN,KAAK;4BACzB+N,SAAST,MAAMtN;+BAEd;4BACD+N,SAASL,KAAKH;;wBAGlBM,sBAAsB7N,IAAI+N;wBAE1B,OAAOL,KAAKK;;oBAGhBC,aAAa,SAAShO,IAAI+N;wBAEtB,IAAIvrB,GAAGqK,SAASygB,QAAQ;4BAEpB,IAAItN,OAAO,MAAM;gCACb,IAAIxd,GAAGyK,WAAW8gB,SAAS;oCACvBN,iBAAiBM;uCAEhB;oCACDN,iBAAiBA;oCACjBjrB,GAAGuG,OAAO0kB,gBAAgBM;;mCAG7B;gCACDP,oBAAoBxN,MAAMwN,oBAAoBxN;gCAC9Cxd,GAAGuG,OAAOykB,oBAAoBxN,KAAK+N;;;;oBAK/CzlB,QAAQ,SAAS4d;wBACb,cAAcoH,MAAMpH;;oBAGxB5G,OAAO;wBACHgO;wBACAE;wBACAD,WAAWH;;;;YAKvBa,0BAA0B;gBACtB,IAAI1nB,OAAO9B;gBAEX,OAAO,IAAIjC,GAAG+c;oBACVmG,SAAS,SAAS1F;wBACd,OAAOzZ,KAAKmf,QAAQ1F;;oBAExBmI,SAAS,SAASnI;wBACd,OAAOzZ,KAAK4hB,QAAQnI;;oBAExB4H,SAAS,SAAS5H;wBACd,OAAOzZ,KAAKqhB,QAAQ5H;;oBAExBkB,gBAAgB,SAASlB,IAAIuB,WAAWD;wBACpC/a,KAAK2nB,sBAAsBlO,IAAIuB,WAAWD;wBAC1C/a,KAAKlD,SAASF,UAAU+d,eAAelB,IAAIuB,WAAWD;wBACtD/a,KAAK4nB,kBAAkBnO,IAAIsB;wBAE3B,IAAI/a,KAAK2iB,gBAAgB;4BACrBkF,WAAW;gCACP7nB,KAAK2iB,eAAehI,eAAelB,IAAIuB,WAAWD;+BACnD;;;;;YAcnB+M,qBAAqB,SAASzN;gBAC1B,IAAIra,OAAO9B,MACPiZ,cAAckD,KAAK0N,UAAU7pB,KAAKpB,SAASkrB,WAAW7Q,aACtD8Q,oBAAoB5N,KAAK4N,qBAAqB/pB,KAAKpB,SAASkrB,WAAWC,mBACvE9F;gBAEJ,SAAS+F;oBACL,IAAIjsB,GAAGgW,kBAAkBqC,eAAe;wBAEpC,IAAItU,KAAKlD,SAASqrB,YAAYC,kBAC1BnsB,GAAG4R,UACF5R,GAAG2R,UACJ5N,KAAKqoB,oBAAoBJ,mBAAmB,SAAS;4BAErD,OAAO;;wBAGX,IAAI5N,KAAKhR,aAAa9M,WAAW;4BAC7B,OAAOyD,KAAKlD,SAASuM;;wBAGzB,OAAOgR,KAAKhR;;oBAGhB,OAAO;;gBAGX8Y,SAAS,IAAIlmB,GAAG+a;oBACZG,aAAaA;oBACbxY,SAAS0b,KAAK1b;oBACdyY,YAAYlZ,KAAKpB,SAASwrB,QAAQC;oBAClClR,SAASgD,KAAKhD;oBACdC,YAAYpZ,KAAKpB,SAASwrB,QAAQE;oBAClCjR,4BAA4BrZ,KAAKpB,SAASqrB,YAAYM;oBACtDpf,UAAU6e;oBACVjrB,MAAMiB,KAAKpB,SAASyoB,QAAQmD;oBAC5BlR,UAAU,SAAStO;wBACflJ,KAAK2oB,eAAezf;;oBAExBuO,OAAO4C,KAAK5C,SAAS,OAAOvZ,KAAKpB,SAASiH,KAAK6kB,iBAAiBvO,KAAK5C;;gBAGzEvZ,KAAK2qB,gBAAgBnX,YAAY;oBAC7ByQ,OAAO5Q;;gBAGXvR,KAAKkiB,SAASnkB,KAAKokB;gBAEnB,OAAOA;;YAGX2G,sBAAsB,SAASC,mBAAmBntB;gBAC9C,IAAIoE,OAAO9B,MACP8qB,qBACA9tB;oBACI2mB,OAAO3jB,KAAKpB,SAAS+kB;oBACrBwD,gBAAgBnnB,KAAKpB,SAASuoB;oBAC9BO,MAAM1nB,KAAKpB,SAAS8oB;oBACpBF,aAAaxnB,KAAKkkB;oBAClBuD,eAAeznB,KAAK4iB;oBACpBrM,UAAUvW,KAAKpB,SAAS2X;oBACxBc,QAAQrX,KAAKpB,SAASyY;oBACtBkI,OAAOvf,KAAKpB,SAAS2gB;oBACrBpf,KAAKpC,GAAG+S,KAAKhP,KAAK3B,KAAK2B;oBACvBipB,mBAAmB/qB,KAAKpB,SAAS8lB,MAAMsG;oBACvCC,YAAY,SAAS1P,IAAIxc,MAAMmsB,QAAQC;wBACnC,IAAID,SAAS,KAAKC,QAAQ,GAAG;4BACzB;;wBAGJ,IAAIL,eAAevP,KAAK;4BACpB,IAAIuP,eAAevP,IAAI2P,WAAWA,UAAUJ,eAAevP,IAAI4P,UAAUA,OAAO;gCAC5ErpB,KAAKspB,YAAY7P,IAAIxc,MAAMmsB,QAAQC;gCACnCrpB,KAAKlD,SAASF,UAAUusB,WAAW1P,IAAIxc,MAAMmsB,QAAQC;;+BAGxD;4BACDrpB,KAAKspB,YAAY7P,IAAIxc,MAAMmsB,QAAQC;4BACnCrpB,KAAKlD,SAASF,UAAUusB,WAAW1P,IAAIxc,MAAMmsB,QAAQC;;wBAGzDL,eAAevP;4BAAO2P,QAAQA;4BAAQC,OAAOA;;;oBAGjDE,YAAY,SAAS9P,IAAIxc,MAAMoG,QAAQoQ;+BAC5BuV,eAAevP;wBAEtB,IAAIK,SAAS9Z,KAAKmhB;4BAAY1H,IAAIA;2BAAKK,QACnCra;wBAMJ,IAAIqa,WAAW7d,GAAG6d,OAAOwC,qBAAqBxC,WAAW7d,GAAG6d,OAAOyC,eAAe;4BAC9E;;wBAGJ9c,SAASO,KAAKwpB,YAAY/P,IAAIxc,MAAMoG,QAAQoQ;wBAI5C,IAAIhU,kBAAmBxD,GAAGmP,SAAS;4BAC/B3L,OAAOkX,KAAK;gCACR3W,KAAKlD,SAASF,UAAU2sB,WAAW9P,IAAIxc,MAAMoG,QAAQoQ;;+BAGxD;4BACDzT,KAAKlD,SAASF,UAAU2sB,WAAW9P,IAAIxc,MAAMoG,QAAQoQ;;;oBAG7DgW,UAAU,SAAShQ,IAAIxc,MAAMysB;wBACzB,IAAIve,UAAU,IAAIlP,GAAGmP;wBAErBpL,KAAKwmB;4BACDvpB,MAAM;4BACN2R,UAAU3S,GAAG+S,KAAKhP,KAAKlD,SAASF,UAAU6sB,UAAUzpB,MAAMyZ,IAAIxc;4BAC9DyZ,WAAWvL,QAAQK;4BACnBiL,WAAW;gCACPiT,yBAAyBxT,KAAK;oCAC1BlW,KAAK2pB,UAAUlQ,IAAIxc;;gCAGvBkO,QAAQG;;4BAEZqb,YAAYlN;;wBAGhB,OAAOtO;;oBAEXye,cAAc3tB,GAAG+S,KAAK9Q,KAAK2rB,eAAe3rB;oBAC1C4rB,UAAU,SAASrQ,IAAIxc;wBACnB+C,KAAK+pB,UAAUtQ,IAAIxc;wBACnB+C,KAAKlD,SAASF,UAAUktB,SAASrQ,IAAIxc;;oBAEzC+sB,eAAe,SAASvQ,IAAIxc,MAAMgtB;wBAC9BjqB,KAAKkqB,eAAezQ,IAAIwQ;wBACxBjqB,KAAKlD,SAASF,UAAUotB,cAAcvQ,IAAIxc,MAAMgtB;;oBAEpDE,sBAAsB,SAAS1Q,IAAIwQ,WAAW5mB,QAAQoQ;wBAClDzT,KAAKlD,SAASF,UAAUutB,qBAAqBlsB,MAAM+B,MAAMvC;;oBAE7D2sB,UAAU,SAAS3Q,IAAIxc,MAAMgtB;wBACzB,OAAOjqB,KAAKlD,SAASF,UAAUwtB,SAAS3Q,IAAIxc,MAAMgtB;;oBAEtDI,aAAa,SAAS5Q,IAAIxc,MAAMqtB,cAAc7W;wBAC1C,OAAOzT,KAAKuqB,aAAatsB,MAAM+B,MAAMvC;;oBAEzC+sB,eAAe,SAAS/Q,IAAI2B;wBACxBpb,KAAK3B,IAAI,wCAAwC2B,KAAK4hB,QAAQnI,MAAM,WAAW2B,UAAU;wBACzFpb,KAAKmkB,QAAQ1K,IAAI2B;;oBAErB+D,SAASljB,GAAG+S,KAAKhP,KAAKmf,SAASnf;oBAC/B4hB,SAAS3lB,GAAG+S,KAAKhP,KAAK4hB,SAAS5hB;oBAC/BqhB,SAASplB,GAAG+S,KAAKhP,KAAKqhB,SAASrhB;oBAC/ByqB,SAASxuB,GAAG+S,KAAKhP,KAAK0qB,UAAU1qB;oBAChC2qB,eAAe,SAAS/Q;wBACpB,OAAO5Z,KAAKmhB;4BAAYvH,MAAMA;;;oBAElCgR,UAAU,SAASnR;wBACf,IAAIK,SAAS9Z,KAAKmhB;4BAAY1H,IAAIA;2BAAKK;wBACvC,OAAOA,WAAW7d,GAAG6d,OAAOmC,UACxBnC,WAAW7d,GAAG6d,OAAOiC,aACrBjC,WAAW7d,GAAG6d,OAAOuC,mBACrBvC,WAAW7d,GAAG6d,OAAOqC;;oBAE7BN,oBAAoB7b,KAAKif,YAAYpD;oBACrCC,eAAe9b,KAAKif,YAAYnD;;gBAGxC7f,GAAGY,KAAKqB,KAAKpB,SAASyoB,SAAS,SAASxoB,MAAMV;oBAC1CnB,QAAQ6B,QAAQV;;gBAGpBnB,QAAQuqB,gBAAgBvnB,KAAKilB;gBAE7B,IAAI4F,mBAAmB;oBACnB9sB,GAAGY,KAAKksB,mBAAmB,SAAS3sB,KAAKC;wBACrCnB,QAAQkB,OAAOC;;;gBAIvB,OAAO,IAAIJ,GAAG4uB,wBAAwB3vB,SAASU;;YAGnDkvB,qBAAqB,SAASrR;gBAC1Bvb,KAAKyjB;gBACLzjB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOkC;;YAG7C+O,aAAa,SAASrgB;gBAClB,IAAIA,UAAU,GAAG;oBACb,OAAOA,QAAQxM,KAAKpB,SAASiH,KAAKinB,YAAY;;gBAElD,IAAInb,KAAK;gBACT,GAAG;oBACCnF,QAAQA,QAAQ;oBAChBmF;yBACKnF,QAAQ;gBAEjB,OAAOpI,KAAK2oB,IAAIvgB,OAAO,IAAKwgB,QAAQ,KAAKhtB,KAAKpB,SAASiH,KAAKinB,YAAYnb;;YAK5Esb,2BAA2B;gBACvB,IAAInrB,OAAO9B;gBAEXA,KAAKktB;gBAELnvB,GAAGY,KAAKqB,KAAKpB,SAASuuB,cAAc,SAASxtB,KAAKytB;oBAC9C,IAAIjiB,WAAWiiB,uBAAuBjiB,UAClC2e,aAAa/rB,GAAGuG,WAAWxC,KAAKlD,SAASkrB,YAAY,OACrDuD,kBAAkBtvB,GAAGuG,WAAW8oB;oBAEpC,IAAIjiB,aAAa9M,WAAW;wBACxB8M,WAAWrJ,KAAKlD,SAASuM;;oBAG7B,IAAIkiB,gBAAgBvD,YAAY;wBAC5B/rB,GAAGuG,OAAOwlB,YAAYsD,uBAAuBtD,YAAY;;oBAG7D/rB,GAAGuG,OAAO+oB;wBACNliB,UAAUA;wBACV2e,YAAYA;uBACb;oBAEHhoB,KAAKwrB,iBAAiBD;;;YAI9B5K,YAAY,SAASjJ;gBACjB,IAAI+T,mBAAmBvtB,KAAKktB,kBAAkB1T;gBAE9C,IAAI+T,kBAAkB;oBAClB,OAAOA,iBAAiB9sB;uBAEvB,IAAI+Y,aAAaxZ,KAAKwtB,kBAAkB;oBACzC,OAAOxtB,KAAKpB,SAASqlB;;;YAW7B4C,cAAc,SAAS4G;gBACnB,IAAIC,QAAQC,WACRC,kBAAkBH;gBAGtB,IAAIG,2BAA2B7vB,GAAG2a,WAAW;oBACzCkV,kBAAkBA,gBAAgBjV;;gBAItC,IAAIiV,oBAAoB7vB,GAAG8M,OAAO+iB,kBAAkB;oBAChD,IAAI7vB,GAAG+L,OAAO8jB,kBAAkB;wBAC5B,OAAOA,gBAAgBhH;2BAEtB,IAAIgH,gBAAgBhjB,QAAQ9M,kBAAkB,WAC/C8vB,gBAAgB1sB,KAAKpD,kBAAkB,QAAQ;wBAE/C,OAAO8vB,gBAAgBxnB,aAAarI,GAAG+a,aAAaY;;oBAGxDgU,SAASE,gBAAgBtoB,qBAAqB;oBAE9CvH,GAAGY,KAAK+uB,QAAQ,SAAS/tB,KAAKqL;wBAC1B,IAAIA,MAAM5E,aAAa,YAAY,QAAQ;4BACvCunB,YAAY3iB;4BACZ,OAAO;;;oBAIf,IAAI2iB,WAAW;wBACX,OAAOA,UAAUvnB,aAAarI,GAAG+a,aAAaY;;;;YAK1DmU,iBAAiB;gBACb,OAAO7tB,KAAK+gB,YAAYrE;oBACpBd,UACI7d,GAAG6d,OAAOsC,WACVngB,GAAG6d,OAAOuC,iBACVpgB,GAAG6d,OAAOmC,QACVhgB,GAAG6d,OAAOQ,YACVre,GAAG6d,OAAOiC,WACV9f,GAAG6d,OAAOqC;mBAEf9b;;YAKP2rB,oBAAoB,SAAStU;gBACzB,IAAI6T,kBAAkBrtB,KAAKktB,kBAAkB1T;gBAE7C,OAAO6T,kBAAkBA,gBAAgBvD,aAAa9pB,KAAKpB,SAASkrB;;YAGxEiE,0BAA0B,SAASC;gBAC/B,IAAIA,YAAY7N,gBAAgBpiB,GAAG2a,WAAW;oBAC1C;wBACI3Z,MAAMhB,GAAGiV,YAAYgb,YAAY7N,KAAKxH;wBACtC2D,MAAM0R,YAAY7N,KAAKxH,cAAc2D;;;gBAI7C;oBACIvd,MAAMiB,KAAKijB;wBAAY1H,IAAIyS,YAAYzS;uBAAKxc;oBAC5Cud,MAAMtc,KAAKijB;wBAAY1H,IAAIyS,YAAYzS;uBAAKe;;;YAIpD2R,2BAA2B,SAASC;gBAChC,IAAIpsB,OAAO9B,MACPmuB;gBAEJpwB,GAAGY,KAAKuvB,cAAc,SAASvuB,KAAKquB;oBAChCG,gBAAgBtuB,KAAKiC,KAAKisB,yBAAyBC;;gBAGvD,OAAOG;;YAIXC,qBAAqB;gBACjB,IAAIpuB,KAAKpB,SAASyvB,OAAO1e,OAAO5R,GAAG4R,OAAO;oBACtC,IAAI2e,kBAAkB,0BAClBrK,SAASjkB,KAAKpB,SAASyvB,OAAOpK,QAC9BzK,WAAWyK,SAASjkB,KAAK6mB,aAAa5C,UAAUjkB,KAAKwtB,kBACrDe,aAAavuB,KAAKpB;oBAGtB,IAAI4a,YAAYA,aAAaxZ,KAAKwtB,kBAAkB;wBAChDe,aAAavuB,KAAKktB,kBAAkB1T;;oBAIxC+U,WAAWpjB,WAAW;oBAGtB,IAAIojB,WAAWzE,WAAW7Q,gBAAgB,MAAM;wBAC5CsV,WAAWzE,WAAW7Q,cAAcqV;2BAEnC;wBACDC,WAAWzE,WAAW7Q,eAAe,MAAMqV;;oBAI/CvwB,GAAGY,KAAKqB,KAAKgkB,UAAU,SAASrkB,KAAKskB;wBACjC,IAAIA,OAAOzJ,kBAAkBhB,UAAU;4BACnCyK,OAAOtK,YAAY4U,WAAWpjB;4BAC9B8Y,OAAOrJ,eAAe2T,WAAWtV;4BAEjC,OAAO;;;;;YAMvBqP,wBAAwB,SAASkG;gBAC7B,IAAI1sB,OAAO9B,MACPyuB,iBAAiBD,QAAQ9d;gBAE7B,IAAI3S,GAAG+Z,iBAAiB2W,iBAAiB;oBACrCzuB,KAAKG,IAAIquB,QAAQzvB,OAAO,oBAAoByvB,QAAQzvB,OAAO,kCAAkCyvB,QAAQ/F;oBACrG,OAAOgG,eAAezW,KAClB,SAAS0W;wBACL5sB,KAAK3B,IAAIquB,QAAQzvB,OAAO,0BAA0ByvB,QAAQ/F;wBAC1D+F,QAAQjW,UAAUmW;uBAEtB;wBACI,IAAIF,QAAQhW,WAAW;4BACnB1W,KAAK3B,IAAIquB,QAAQzvB,OAAO,0BAA0ByvB,QAAQ/F;4BAC1D+F,QAAQhW;+BAEP;4BACD1W,KAAK3B,IAAIquB,QAAQzvB,OAAO,0BAA0ByvB,QAAQ/F;;;;gBAK1E,IAAIgG,mBAAmB,OAAO;oBAC1BD,QAAQjW,UAAUkW;uBAEjB;oBACD,IAAID,QAAQhW,WAAW;wBACnBxY,KAAKG,IAAIquB,QAAQzvB,OAAO,qCAAqCyvB,QAAQ/F,aAAa;wBAClF+F,QAAQhW;2BAEP;wBACDxY,KAAKG,IAAIquB,QAAQzvB,OAAO,qCAAqCyvB,QAAQ/F,aAAa;;;gBAI1F,OAAOgG;;YAIXnP,gBAAgB,SAASa,MAAM5D,SAASoS;gBACpC,IAAI7sB,OAAO9B,MACP0b,OAAO3d,GAAGsQ,eACViO,QAAQ,GACRvd,OAAOhB,GAAGiV,YAAYmN,OACtByO,aAAazO,KAAKvT,QAAQuT,MAC1B0O,UAAU7uB,KAAK8uB,wBACX9uB,KAAK8uB,wBACL/wB,GAAG+S,KAAKhP,KAAKitB,uBAAuBjtB;gBAE5C,KAAK/D,GAAGuM,QAAQskB,eAAeA,WAAWtS,QAAQ,GAAG;oBACjDA,OAAOsS,WAAWtS;;gBAGtBuS,QAAQD,YAAY7vB,MAAM2c,MAAMY,MAAMqS,oBAAoBpS,SAASvc,KAAKpB,SAASyoB,QAAQC;oBACrFxG,YAAYhf,KAAKif;oBACjByG,aAAa1lB,KAAKoiB;oBAClB8K,kBAAkB,SAASzT,IAAI4E;wBAC3Bre,KAAK0e,SAAS/O,IAAI8J,IAAI4E;wBACtBre,KAAK2hB;wBACL3hB,KAAKmtB,aAAa1T;;;;YAK9BwT,uBAAuB,SAAS5O,MAAMphB,MAAM2c,MAAMY,MAAM4S,UAAU3S;gBAC9D,IAAIhB,KAAKvb,KAAK+gB,YAAY7E;oBAASR,MAAMA;oBAAM3c,MAAMA;oBAAMud,MAAMA;oBAAMC,SAASA;;gBAEhFvc,KAAKwgB,SAAS/O,IAAI8J,IAAI4E;gBACtBngB,KAAKivB,aAAa1T;gBAElBvb,KAAKyjB;gBAELyL,SAASrvB;oBAAM0b,IAAIA;oBAAI4E,MAAMA;;;YAGjCqI,qBAAqB,SAAS5b,MAAMuiB;gBAChC,IAAIC,YAAYxiB,KAAK1L,KAAKwG,MAAM,KAAK,IACjC3I,OAAOowB;gBAGX,IAAIpwB,QAAQ,MAAM;oBACdA,OAAOiB,KAAKpB,SAASwpB,MAAM5I;;gBAG/BzgB,QAAQ,MAAMqwB;gBAEdpvB,KAAK6e;oBACD9f,MAAMA;oBACN6N,MAAMA;;;YAKd0gB,kBAAkB,SAASnR;gBACvB,IAAI8H,SAASjkB,KAAK4pB;oBACdC,QAAQ1N,KAAK2N,WAAW7Q;oBACxB8Q,mBAAmB5N,KAAK2N,WAAWC;oBACnCtpB,SAAS0b,KAAK1b;oBACd0Y,SAASgD,KAAKhD;oBACdhO,UAAUgR,KAAKhR;oBACfoO,OAAO4C,KAAKuO;;gBAGhB1qB,KAAKktB,kBAAkBjJ,OAAOzJ,iBAAiB2B;;YAGnDkT,2BAA2B;gBACvBrvB,KAAKsvB,eAAevxB,GAAGwxB,eAAe,IAAIxxB,GAAGwxB,YACzCvvB,KAAKpB,SAASuT,MAAMpU,GAAG+S,KAAK9Q,KAAKkmB,mBAAmBlmB,OAAOjC,GAAG+S,KAAK9Q,KAAKG,KAAKH;gBAGjF,IAAIA,KAAKsvB,gBAAgBtvB,KAAKsvB,aAAaE,gBAAgB;oBACvDxvB,KAAKkkB,eAAelkB,KAAK0oB,aACrB1oB,KAAKpB,SAASyoB,QAAQ9pB,QAASyC,KAAKsvB,aAAaG;oBAGrDzvB,KAAKpB,SAAS8wB,aAAa1vB,KAAKsvB,aAAaK;oBAC7C,IAAI3vB,KAAKsvB,aAAaM,aAAa;wBAC/B5vB,KAAKpB,SAASyoB,QAAQzI,WAAW5e,KAAKsvB,aAAaM;;uBAGtD;oBACD5vB,KAAKkkB,eAAelkB,KAAK0oB,aAAa1oB,KAAKpB,SAASyoB,QAAQ9pB;;;YAIpEsyB,mBAAmB;gBACf,KAAK9xB,GAAGkpB,4BAA4BjnB,KAAKpB,SAASuiB,WAAWH,SAAS;oBAClE,OAAO;;gBAGX,IAAIhhB,KAAKpB,SAAS8oB,KAAKoI,UAAU;oBAC7B,IAAI/xB,GAAGgW,kBAAkB2C,mBAAmB;wBACxC,OAAO;;oBAGX,IAAI3Y,GAAGgW,kBAAkB0C,qBAAqBzW,KAAKpB,SAAS8oB,KAAKqI,UAAU;wBACvE,OAAO;;oBAGX,OAAO;;gBAGX,OAAO;;YAGX5F,qBAAqB,SAAS6F,SAAS9c;gBACnC,IAAI+c,QAAQ;gBAEZ,KAAKD,QAAQ7tB,QAAQ;oBACjB,OAAO;;gBAGXpE,GAAGY,KAAKqxB,SAAS,SAASrwB,KAAKuwB;oBAK3B,IAAInyB,GAAGmL,SAASgnB,aAAa;wBAEzB,IAAIC,WAAW,IAAIzrB,OAAO,QAAQwrB,aAAa,KAAK;wBAEpD,IAAIhd,SAAS/R,MAAMgvB,aAAa,MAAM;4BAClCF,QAAQ;4BACR,OAAO;;;;gBAKnB,OAAOA;;YAWX9J,YAAY,SAASiK,MAAMC,kBAAkBrnB;gBACzC,IAAI5I,UAAUJ,KAAKpB,SAAS0xB,SAASF,OACjCrG,wBACAwG,WAAWrf,OAAOmf,mBAClBtxB,OAAOwxB,MAAM,IACb/W,WAAWxZ,KAAK6mB,aAAa7d,OAC7BwnB,iBAAiBxwB,KAAK8tB,mBAAmBtU,WACzCiX,sBAAsBC;gBAE1B,SAASniB,EAAExP,MAAM4xB;oBAAevwB,UAAUA,QAAQ2E,QAAQhG,MAAM4xB;;gBAEhE5yB,GAAGY,KAAK6xB,eAAezG,mBAAmB,SAASpqB,KAAKixB;oBAKpD,IAAI7yB,GAAGmL,SAAS0nB,mBAAmB;wBAC/B7G,kBAAkBlqB,KAAK+wB;;;gBAI/BH,uBAAuB1G,kBAAkBjY,KAAK,MAAMhU;gBAEpDyQ,EAAE,UAAUvO,KAAKpB,SAASiyB,eAAe9xB;gBACzCwP,EAAE,gBAAgBkiB;gBAClBliB,EAAE,eAAevO,KAAK6sB,YAAY2D,eAAeM;gBACjDviB,EAAE,kBAAkBvO,KAAK6sB,YAAY2D,eAAeO;gBAEpDL,mBAAmBtwB,QAAQe,MAAM;gBACjC,IAAIuvB,qBAAqB,MAAM;oBAC3B3yB,GAAGY,KAAK+xB,kBAAkB,SAAS/wB,KAAKqxB;wBACpCziB,EAAEyiB,aAAaT,MAAM5wB;;;gBAI7BK,KAAKpB,SAASF,UAAUqoB,QAAQ,MAAMhoB,MAAMqB,SAAS/B;gBAErD,OAAO+B;;YAYXukB,cAAc,SAASpJ,IAAI7K;gBACvB,IAAI1Q,KAAKixB,qBAAqB1V,KAAK;oBAC/Bvb,KAAKyjB;oBACLzjB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOuC;oBAEzC,IAAIzN,UAAU;wBACVA,SAAS6K;2BAER;wBACDvb,KAAKwgB,SAASkE,MAAMnJ;;oBAGxB,OAAO;;;YAIfmO,mBAAmB,SAASnO,IAAIK;gBAC5B,IAAI9Z,OAAO9B,MACPkxB,cAAclxB,KAAK6tB;gBAEvB,IAAIjS,WAAW7d,GAAG6d,OAAOwC,mBAAmB;oBACxCpe,KAAKukB,+BAA+B1kB,KAAK0b;uBAExC,IAAIK,WAAW7d,GAAG6d,OAAOyC,eAAe;oBACzCre,KAAKwkB,4BAA4B3kB,KAAK0b;;gBAG1C,IAAI2V,gBAAgB,MACflxB,KAAKukB,+BAA+BpiB,UAAUnC,KAAKwkB,4BAA4BriB,SAAS;oBAEzFwnB,WAAW;wBACP7nB,KAAKqvB,eAAervB,KAAKyiB,gCAAgCziB,KAAK0iB;uBAC/D;;;YAIXtF,kCAAkC;gBAC9B,IAAIpd,OAAO9B;gBAEX,IAAIA,KAAKpB,SAASqrB,YAAYmH,qBAAqBrzB,GAAG+R,YAAY/R,GAAGiS,aAAa;oBAC9E2Z,WAAW;wBACP3iB,OAAOqqB,MAAMvvB,KAAKlD,SAAS0xB,SAASgB;uBACrC;oBACH,MAAM,IAAIvzB,GAAGkG,MAAMjE,KAAKpB,SAAS0xB,SAASgB;;;YAIlDC,+BAA+B,SAAShW,IAAIxc,MAAMyyB,UAAUjc;gBAGxD,KAAKic,SAASpkB,SAAS;oBACnB,IAAImI,OAAOA,IAAIqG,WAAW,QAAQ4V,SAAStxB,OAAO;wBAC9CF,KAAKpB,SAASF,UAAUqoB,QAAQxL,IAAIxc,MAAM,gCAAgCwW,IAAIqG,QAAQrG;2BAErF;wBACD,IAAIkc,cAAcD,SAAStxB,QAAQsxB,SAAStxB,QAAQF,KAAKpB,SAASiH,KAAK6rB;wBACvE1xB,KAAKpB,SAASF,UAAUqoB,QAAQxL,IAAIxc,MAAM0yB,aAAalc;;;;YAKnEoc,8CAA8C,SAASC,WAAWjmB,OAAO1J,OAAO1E,QAAQqhB;gBACpF,IAAI9c,OAAO9B;gBAEX,IAAI2L,MAAMxJ,SAASF,OAAO;oBACtB,IAAI2vB,cAAc5xB,KAAKpB,SAASkrB,WAAW+H,wBAAwB;wBAE/DlI,WAAW;4BACP,IAAImI,uBAAuBhwB,KAAKisB,yBAAyBpiB,MAAM1J,SAC3DuX,WAAW1X,KAAK+kB,aAAalb,MAAM1J,OAAOke,OAC1C8D,SAASniB,KAAK2gB,WAAWjJ;4BAE7B1X,KAAKwmB;gCACDvpB,MAAM;gCACN2R,UAAU3S,GAAG+S,KAAKhP,KAAKlD,SAASF,UAAUqzB,YAAYjwB,MAAMgwB,sBAAsB7N;gCAClF1L,WAAWxa,GAAG+S,KAAKhP,KAAKkwB,4BAA4BlwB,MAAM6J,OAAO1J,OAAO1E,QAAQqhB;gCAChFpG,WAAWza,GAAG+S,KAAKhP,KAAKmwB,4BAA4BnwB,MAAM6J,OAAO1J,OAAO1E,QAAQqhB;gCAChF6J,YAAY,WAAWqJ,qBAAqB/yB,OAAO,cAAc+yB,qBAAqBxV;;2BAE3F;2BAEF,KAAKsV,WAAW;wBACjB,MAAO3vB,QAAQ0J,MAAMxJ,QAAQF,SAAS;4BAClCH,KAAK8qB,oBAAoBjhB,MAAM1J,OAAOsZ;;;;;YAMtD4V,gBAAgB,SAASe,YAAYC;gBACjCnyB,KAAKykB,kBAAkBzkB,KAAKykB,eAAe2N,cAAcF,YAAYC,QAAQnyB,KAAK+jB;gBAElF/jB,KAAKpB,SAASF,UAAU0zB,cAAcr0B,GAAGuG,WAAW4tB,aAAan0B,GAAGuG,WAAW6tB;gBAE/EnyB,KAAKukB;gBACLvkB,KAAKwkB;;YAeT6H,cAAc,SAAS9Q,IAAIxc,MAAMqtB,cAAc7W,KAAK7E;gBAChD,IAAI5O,OAAO9B;gBAEX8B,KAAKiiB,gBAAgBxI,MAAM6Q,aAAatqB,KAAKlD,SAAS8lB,MAAMsG;gBAE5D,IAAIlpB,KAAKuwB,iBAAiB9W,IAAIxc,MAAMqtB,eAAe;oBAC/C,IAAIkG,kBAAkBxwB,KAAKlD,SAAS8lB,MAAM6N,mBAAmB;oBAE7DzwB,KAAKyvB,8BAA8BxxB,MAAM+B,MAAMvC;oBAC/CuC,KAAKlD,SAASF,UAAUytB,YAAY5Q,IAAIxc,MAAM+C,KAAK+hB,aAAatI;oBAChEzZ,KAAK0wB,mBAAmBjX,IAAIxc;oBAE5B+C,KAAKif,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOuC;oBACzCrc,KAAKgiB,eAAevI,MAAMoO,WAAW;wBACjC7nB,KAAK3B,IAAI,wBAAwBpB,OAAO;wBAExC,IAAI2R,UAAU;4BACVA,SAAS6K;+BAER;4BACDzZ,KAAK0e,SAASkE,MAAMnJ;;uBAEzB+W;oBAEH,OAAO;;;YAIfE,oBAAoB,SAASjX,IAAIxc;gBAC7BiB,KAAKG,IAAI,aAAaH,KAAKpB,SAAS8lB,MAAM6N,mBAAmB,8BAA8BxzB,OAAO;;YAItGkyB,sBAAsB,SAAS1V;gBAC3B,IAAIkX,YAAYzyB,KAAKwjB,mBACjBtQ;gBAEJ,IAAIlT,KAAK+jB,gBAAgBxI,KAAK;oBAC1Bvb,KAAKG,IAAI,kCAAkCob,IAAI;oBAC/C,OAAO;uBAEN,IAAIvb,KAAKwgB,SAASe,QAAQhG,KAAK;oBAChCrI,WAAWlT,KAAKihB,QAAQ1F;oBAExB,IAAIvb,KAAKpB,SAASF,UAAUg0B,cAAcnX,IAAIrI,cAAc,OAAO;wBAC/D,OAAO;;oBAGX,IAAIuf,YAAY,KAAKzyB,KAAKyjB,uBAAuB,IAAIgP,WAAW;wBAC5DzyB,KAAKmmB,WAAW;wBAChB,OAAO;;oBAGXnmB,KAAKG,IAAI,0BAA0B+S,WAAW,YAAYqI,KAAK;oBAC/D,OAAO;uBAEN;oBACDvb,KAAKG,IAAI,MAAMob,KAAK,4BAA4B;oBAChD,OAAO;;;YAIfkQ,WAAW,SAASlQ,IAAIxc;gBACpBiB,KAAKyjB;gBAELkP,aAAa3yB,KAAK8jB,eAAevI;gBAEjC,IAAIqX,kBAAkB70B,GAAG4J,QAAQ3H,KAAKmf,YAAY5D;gBAClD,KAAKvb,KAAKpB,SAAS8wB,cAAckD,mBAAmB,GAAG;oBACnD5yB,KAAKmf,WAAWnC,OAAO4V,iBAAiB;;gBAG5C5yB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOoC;;YAG7CsN,aAAa,SAAS/P,IAAIxc,MAAMoG,QAAQoQ;gBACpC,KAAKpQ,OAAOiI,SAAS;oBACjBpN,KAAKyjB;oBACLzjB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOyC;oBAEzC,IAAIlZ,OAAOnF,KAAKpB,SAAS8lB,MAAMsG,kCAAkC,MAAM;wBACnEhrB,KAAK+jB,gBAAgBxI,MAAM;;uBAG9B;oBACD,IAAIpW,OAAOshB,cAAc;wBACrBzmB,KAAKiiB,eAAe1G,MAAMpW,OAAOshB;;oBAGrCzmB,KAAKqjB;oBACLrjB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOwC;;gBAG7Cpe,KAAKuxB,8BAA8BhW,IAAIxc,MAAMoG,QAAQoQ;gBAErD,OAAOpQ,OAAOiI,UAAU,OAAO;;YAGnCwa,WAAW,SAASrM;gBAChBvb,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAO2C;;YAG7CyJ,mBAAmB,SAASzM,IAAIuM,UAAUC;gBACtC,IAAIhpB,OAAOiB,KAAKihB,QAAQ1F;gBAExB,IAAIwM,SAAS;oBACT/nB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAO0C;oBACzCte,KAAKG,IAAI,yBAAyBpB,OAAO,iBAAiB;oBAI1D,IAAI+oB,SAAStS,oBAAoBnX,WAAW;wBACxC2B,KAAKpB,SAASF,UAAUqoB,QAAQxL,IAAIxc,MAAM,yBAAyB+oB;2BAElE;wBACD9nB,KAAKpB,SAASF,UAAUqoB,QAAQxL,IAAIxc,MAAM,8CAA8C+oB,SAASlM,QAAQkM;;uBAG5G;oBACD9nB,KAAKyjB;oBACLzjB,KAAKqjB;oBACLrjB,KAAKwgB,SAASqS,QAAQtX;oBACtBvb,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAO4C;oBACzCxe,KAAKG,IAAI,yBAAyBpB,OAAO;;;YAIjD0rB,gBAAgB,SAASzf;gBACrB,IAAI8nB;gBAEJ,IAAI/0B,GAAGgW,kBAAkBqC,eAAe;oBACpC,KAAK0c,YAAY,GAAGA,YAAY9nB,MAAMkV,MAAM/d,QAAQ2wB,aAAa;wBAC7D9yB,KAAK0mB,sBAAsB1b,MAAMkV,MAAM4S,YAAY9nB;;oBAGvDhL,KAAK6e,SAAS7T,MAAMkV;uBAGnB,IAAIlV,MAAMvC,MAAMtG,SAAS,GAAG;oBAC7BnC,KAAK6e,SAAS7T;;gBAGlBjN,GAAGY,KAAKqB,KAAKgkB,UAAU,SAASrkB,KAAKskB;oBACjCA,OAAOpJ;;;YAIfuQ,aAAa,SAAS7P,IAAIxc,MAAMmsB,QAAQC;gBACpCnrB,KAAKykB,kBAAkBzkB,KAAKykB,eAAesO,qBAAqBxX,IAAI2P,QAAQC;;YAGhF6H,WAAW,SAASzX,IAAIxc;YAIxBk0B,0BAA0B,SAAS1X,IAAIxc;gBACnCiB,KAAKgzB,UAAUjzB,MAAMC,MAAMT;gBAC3BS,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOiC;gBACzC7d,KAAKkzB,aAAanzB,MAAMC,MAAMT;gBAE9B,IAAIS,KAAKpB,SAAS8wB,YAAY;oBAC1B1vB,KAAKpB,SAASF,UAAUy0B,YAAYpzB,MAAMC,MAAMT;oBAChDS,KAAKkhB,YAAY3F;uBAEhB;oBACDvb,KAAKozB,eAAe7X;oBACpBvb,KAAKpB,SAASF,UAAUy0B,YAAYpzB,MAAMC,MAAMT;;;YAIxD6hB,iBAAiB,SAAS7F,IAAI8X,mBAAmBC;gBAC7C,IAAI5X,OAAO1b,KAAK0jB,QAAQnI,KACpBgY;gBAEJ,IAAIF,mBAAmB;oBACnBE,4BAA4Bx1B,GAAG+S,KAAKuiB,mBAAmBrzB,MAAMub,IAAIG,MAAM4X;;gBAG3E,IAAItzB,KAAK6vB,qBAAqB;oBAC1B7vB,KAAKsoB;wBACDvpB,MAAM;wBACN2R,UAAU3S,GAAG+S,KAAK9Q,KAAKpB,SAASF,UAAU80B,gBAAgBxzB,MAAMub;wBAChEhD,WAAWgb,6BACPx1B,GAAG+S,KAAK9Q,KAAKyzB,eAAeC,YAAY1zB,MAAMub,IAAIG,MAAM4X;wBAC5D7K,YAAYlN;;oBAEhB,OAAO;uBAEN;oBACDvb,KAAKG,IAAI,mCAAmCob,KAAK,0DAC7C,oEAAoE;oBACxE,OAAO;;;YAIf2X,cAAc,SAAS3X;YAIvBoY,kBAAkB,SAASzI,QAAQC;gBAC/BnrB,KAAKpB,SAASF,UAAUk1B,gBAAgB1I,QAAQC;;YAGpDQ,eAAe,SAASpQ;YAIxBsQ,WAAW,SAAStQ,IAAIxc;gBACpBiB,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOsC;;YAG7C8N,gBAAgB,SAASzQ,IAAIwQ;YAI7BtC,uBAAuB,SAASlO,IAAIuB,WAAWD;gBAE3C,IAAIA,cAAc9e,GAAG6d,OAAOqC,QAAQ;oBAChC0U,aAAa3yB,KAAK8jB,eAAevI;;;YAIzCsY,iCAAiC,SAAS3F;gBACtC,IAAIpsB,OAAO9B;gBAEXjC,GAAGY,KAAKuvB,cAAc,SAASvuB,KAAKquB;oBAChClsB,KAAK8qB,oBAAoBoB,YAAYzS;;;YAI7CuY,iCAAiC,SAASC,uBAAuBpoB,OAAOpO,QAAQqhB,UAAUqF;gBACtF,IAAI+P,cACAvB,YAAYzyB,KAAKwjB,mBACjByQ,mCAAmCj0B,KAAKyjB;gBAE5C,IAAIgP,cAAc,KAAKwB,oCAAoCxB,WAAW;oBAClE,IAAI9mB,MAAMxJ,SAAS,GAAG;wBAClBnC,KAAKsoB;4BACDvpB,MAAM;4BACN2R,UAAU3S,GAAG+S,KAAK9Q,KAAKpB,SAASF,UAAUqzB,YAAY/xB,MAAM+zB,sBAAsB,IAAI9P;4BACtF1L,WAAWxa,GAAG+S,KAAK9Q,KAAKgyB,4BAA4BhyB,MAAM2L,OAAO,GAAGpO,QAAQqhB;4BAC5EpG,WAAWza,GAAG+S,KAAK9Q,KAAKiyB,4BAA4BjyB,MAAM2L,OAAO,GAAGpO,QAAQqhB;4BAC5E6J,YAAY,WAAW9c,MAAM,GAAGwU,KAAKphB,OAAO,cAAc4M,MAAM,GAAGwU,KAAK7D;;2BAG3E;wBACDtc,KAAKmmB,WAAW;;uBAGnB;oBACDnmB,KAAK6zB,gCAAgCloB;oBACrCqoB,eAAeh0B,KAAKpB,SAAS0xB,SAAS4D,kBACjCnvB,QAAQ,iBAAiBkvB,kCACzBlvB,QAAQ,kBAAkB0tB;oBAC/BzyB,KAAK8mB,YAAYkN;;;YAIzB/B,4BAA4B,SAAStmB,OAAO1J,OAAO1E,QAAQqhB;gBACvD,IAAIuV,YAAYlyB,QAAQ;gBAExBjC,KAAK4sB,oBAAoBjhB,MAAM1J,OAAOsZ,IAAI5P,MAAM1J,OAAOke,KAAKphB;gBAE5DiB,KAAK2xB,6CAA6C,OAAOhmB,OAAOwoB,WAAW52B,QAAQqhB;;YAGvFoT,4BAA4B,SAASrmB,OAAO1J,OAAO1E,QAAQqhB;gBACvD,IAAI9c,OAAO9B,MACPm0B,YAAYlyB,QAAQ,GACpB6vB,uBAAuB9xB,KAAK+tB,yBAAyBpiB,MAAM1J;gBAE/DjC,KAAKo0B,wBAAwBzoB,MAAM1J,QAAQ6vB,sBACtC9Z,KACD;oBACIlW,KAAKuyB,QAAQ1oB,MAAM1J,OAAOsZ,IAAIhe,QAAQqhB;oBACtC9c,KAAK6vB,6CAA6C,MAAMhmB,OAAOwoB,WAAW52B,QAAQqhB;mBAEtF;oBACI9c,KAAK6vB,6CAA6C,OAAOhmB,OAAOwoB,WAAW52B,QAAQqhB;;;YAK/F0B,wBAAwB,SAAS3U,OAAOpO,QAAQqhB;gBAC5C,IAAIjT,MAAMxJ,WAAW,GAAG;oBACpBnC,KAAKmmB,WAAW;oBAChB;;gBAGJ,IAAI4N,wBAAwB/zB,KAAKiuB,0BAA0BtiB,QACvD6N,WAAWxZ,KAAK6mB,aAAalb,MAAM,GAAGwU,OACtC8D,SAASjkB,KAAKyiB,WAAWjJ;gBAE7BxZ,KAAKsoB;oBACDvpB,MAAM;oBACN2R,UAAU3S,GAAG+S,KAAK9Q,KAAKpB,SAASF,UAAU41B,iBAAiBt0B,MAAM+zB,uBAAuB9P;oBACxF1L,WAAWxa,GAAG+S,KAAK9Q,KAAK8zB,iCAAiC9zB,MAAM+zB,uBAAuBpoB,OAAOpO,QAAQqhB,UAAUqF;oBAC/GzL,WAAWza,GAAG+S,KAAK9Q,KAAK6zB,iCAAiC7zB,MAAM2L;oBAC/D8c,YAAY;;;YAIpB8L,yBAAyB;gBACrB,IAAIzyB,OAAO9B;gBAEXA,KAAK2qB,gBAAgB1nB,OAAO+D,QAAQ,gBAAgB,SAASmJ;oBACzD,IAAIrO,KAAKghB,iBAAiB;wBACtB3S,IAAIA,KAAKnJ,OAAOwtB;wBAEhBrkB,EAAEC,cAActO,KAAKlD,SAAS0xB,SAASmE;wBAEvC,OAAO3yB,KAAKlD,SAAS0xB,SAASmE;;;;YAQ1CnQ,qBAAqB;gBACjB,IAAIxiB,OAAO9B,MACPhD,UAAUgD,KAAKpB,SAASwlB;gBAG5B,IAAIrmB,GAAG22B,WAAW10B,KAAKpB,SAASwlB,QAAQxF,YAAY,MAAM;oBACtD,KAAK5e,KAAK20B,UAAU;wBAChB52B,GAAGuG,OAAOtH;4BAAU0qB,MAAM1nB,KAAKpB,SAAS8oB;;wBAExC1qB,QAAQmD,MAAMpC,GAAG+S,KAAK9Q,KAAKG,KAAKH;wBAChChD,QAAQ43B,gBAAgB72B,GAAG+S,KAAK9Q,KAAKif,gBAAgBjf;wBAErDA,KAAK20B,WAAW,IAAI52B,GAAG22B,QAAQ13B;;oBAGnC2sB,WAAW;wBACP7nB,KAAK6yB,SAASE,UAAU7c,KAAK,SAASwZ,UAAU1J;4BAC5ChmB,KAAKgzB;4BACLhzB,KAAKlD,SAASF,UAAUq2B,yBAAyBvD,UAAU,MAAM1J;2BAElE,SAAS0J,UAAU1J;4BAElBhmB,KAAKlD,SAASF,UAAUq2B,yBAAyBvD,UAAU,OAAO1J;;uBAEvE;;;YAIXgN,yBAAyB;YAEzBtI,UAAU,SAASjR,IAAIgC;gBACnBvd,KAAK+gB,YAAYzD,WAAW/B,IAAIgC;gBAChCvd,KAAKykB,kBAAkBzkB,KAAKykB,eAAeuQ,UAAUzZ;;YAGzD8W,kBAAkB,SAAS9W,IAAIxc,MAAMqtB;gBACjC,IAAItL,aAAa9gB,KAAK+gB,YAAYrE;oBAAUnB,IAAIA;;gBAGhD,KAAKvb,KAAK+jB,gBAAgBxI,OACnBvb,KAAKpB,SAAS8lB,MAAMuQ,cACpBnU,WAAWlF,WAAW7d,GAAG6d,OAAOqC,QAAQ;oBAE3C,IAAIje,KAAK6jB,aAAatI,QAAQld,WAAW;wBACrC2B,KAAK6jB,aAAatI,MAAM;;oBAG5B,IAAIvb,KAAK6jB,aAAatI,MAAMvb,KAAKpB,SAAS8lB,MAAMwQ,iBAAiB;wBAC7Dl1B,KAAK6jB,aAAatI,OAAO;wBACzB,OAAO;;;gBAIf,OAAO;;YAGX6X,gBAAgB,SAAS7X;gBACrBvb,KAAKmf,WAAWtf,KAAK0b;;YAIzB0T,cAAc,SAAS1T;gBACnB,IAAI/B;gBAEJ,IAAIzb,GAAGgW,kBAAkBqC,eAAe;oBACpCoD,WAAWxZ,KAAKwgB,SAAS2B,QAAQ5G,IAAIqL;uBAEpC;oBACDpN,WAAWxZ,KAAK6mB,aAAa7mB,KAAKwgB,SAASjG,SAASgB;;gBAGxD,IAAI/B,UAAU;oBACVxZ,KAAK0iB,qBAAqBnH,MAAM/B;;;YAIxCoM,6BAA6B,SAASuP;gBAClCn1B,KAAKpB,SAASuT,KAAK1R,UAAU00B;gBAE7Bn1B,KAAKsvB,eAAevxB,GAAGwxB,eAAe,IAAIxxB,GAAGwxB,YACrCvvB,KAAKpB,SAASuT,MAAMpU,GAAG+S,KAAK9Q,KAAKkmB,mBAAmBlmB,OAAOjC,GAAG+S,KAAK9Q,KAAKG,KAAKH;gBAGrF,IAAIA,KAAKsvB,gBAAgBtvB,KAAKsvB,aAAaE,gBAAgB;oBACvDxvB,KAAKkkB,aAAaqF,YAAY,MAAMvpB,KAAKsvB,aAAaG;oBAEtDzvB,KAAKpB,SAAS8wB,aAAa1vB,KAAKsvB,aAAaK;oBAC7C,IAAI3vB,KAAKsvB,aAAaM,aAAa;wBAC/B5vB,KAAKylB,YAAYzlB,KAAKsvB,aAAaM;;;;YAK/CyE,SAAS,SAAS9Y,IAAIhe,QAAQqhB;gBAC1B,IAAI7f,OAAOiB,KAAKihB,QAAQ1F;gBAExB,IAAIhe,QAAQ;oBACRyC,KAAKgmB,UAAUzoB,QAAQge;;gBAG3B,IAAIqD,UAAU;oBACV5e,KAAKylB,YAAY7G,UAAUrD;;gBAG/Bvb,KAAKsoB;oBACDvpB,MAAM;oBACN2R,UAAU3S,GAAG+S,KAAK9Q,KAAKpB,SAASF,UAAU02B,UAAUp1B,MAAMub,IAAIxc;oBAC9DwZ,WAAWxa,GAAG+S,KAAK9Q,KAAKizB,0BAA0BjzB,MAAMub,IAAIxc;oBAC5DyZ,WAAWza,GAAG+S,KAAK9Q,KAAK4sB,qBAAqB5sB,MAAMub,IAAIxc;oBACvD0pB,YAAYlN;;;YAIpB2F,aAAa,SAAS3F;gBAClB,KAAKvb,KAAKwgB,SAASlV,OAAOiQ,KAAK;oBAC3Bvb,KAAK+gB,YAAYnE,UAAUrB,IAAIxd,GAAG6d,OAAOmC;;;YAIjDqI,oBAAoB;gBAChB,IAAIiP,YAAYC,iBACZxzB,OAAO9B;gBAEX,OAAOA,KAAKmf,WAAWhd,QAAQ;oBAC3BkzB,aAAar1B,KAAKmf,WAAW5L;oBAC7BvT,KAAKkhB,YAAYmU;;gBAIrBC,kBAAkBt1B,KAAKijB;oBAAYrH,QAAQ7d,GAAG6d,OAAOQ;mBAAaja;gBAClE,IAAImzB,iBAAiB;oBACjBv3B,GAAGoC,IAAI,uBAAuBm1B,kBAAkB;oBAChD3L,WAAW;wBACP7nB,KAAKskB;uBACN;;;YAYXgO,yBAAyB,SAASpG,aAAa8D;gBAC3C,IAAIhwB,OAAO9B,MACPmgB,OAAQ;oBACJ,IAAI6N,YAAY7N,gBAAgBpiB,GAAG2a,WAAW;wBAC1C,OAAOsV,YAAY7N,KAAKxH;;oBAE5B,OAAOqV,YAAY7N;qBAEvBphB,OAAO+yB,qBAAqB/yB,MAC5Bud,OAAOwV,qBAAqBxV,MAC5B9C,WAAWxZ,KAAK6mB,aAAamH,YAAY7N,OACzCqQ,iBAAiBxwB,KAAK8tB,mBAAmBtU,WACzC+b,kBAAkB,IAAIx3B,GAAGmP;gBAE7BqoB,gBAAgBvd,KACZ,eACA;oBACIlW,KAAK8qB,oBAAoBoB,YAAYzS,IAAIxc;;gBAGjD,IAAIhB,GAAGqM,cAAc+V,UAAUngB,KAAKmqB,oBAAoBqG,eAAezG,mBAAmBhrB,OAAO;oBAC7FiB,KAAKmmB,WAAW,aAAapnB,MAAMohB;oBACnC,OAAOoV,gBAAgBjoB;;gBAG3B,KAAKtN,KAAKpB,SAASkrB,WAAW0L,cAAclZ,SAAS,GAAG;oBACpDtc,KAAKmmB,WAAW,cAAcpnB,MAAMohB;oBACpC,OAAOoV,gBAAgBjoB;;gBAG3B,IAAIgP,OAAO,KAAKkU,eAAeM,aAAaxU,OAAOkU,eAAeM,WAAW;oBACzE9wB,KAAKmmB,WAAW,aAAapnB,MAAMohB;oBACnC,OAAOoV,gBAAgBjoB;;gBAG3B,IAAIgP,OAAO,KAAKA,OAAOkU,eAAeO,cAAc;oBAChD/wB,KAAKmmB,WAAW,gBAAgBpnB,MAAMohB;oBACtC,OAAOoV,gBAAgBjoB;;gBAG3B,IAAIvP,GAAG03B,mBAAmB13B,GAAGgW,kBAAkBiD,iBAAiBjZ,GAAG+L,OAAOqW,OAAO;oBAC7E,IAAIpiB,GAAG03B,gBAAgBtV,MAAMpiB,GAAG+S,KAAKhP,KAAK3B,KAAK2B,OAAO4zB,SAASlF,eAAemF,OAAO3d,KACjFud,gBAAgBnoB,SAChB,SAASwoB;wBACL9zB,KAAKqkB,WAAWyP,YAAY,cAAc72B,MAAMohB;wBAChDoV,gBAAgBjoB;;uBAIvB;oBACDioB,gBAAgBnoB;;gBAGpB,OAAOmoB;;YAGXM,gBAAgB;gBACZ,IAAI/zB,MAAMg0B,cAAcj3B;gBAExBiD,OAAO9B;gBAEP81B,eAAe,SAAS/2B,MAAM2R,UAAU/N;oBACpC,IAAIozB;oBAEJ;wBACI,OAAOrlB,SAAS3Q,MAAM+B,MAAMa;sBAEhC,OAAOqzB;wBACHD,WAAWC,UAAU51B,WAAW41B,UAAUztB;wBAC1CzG,KAAK3B,IAAI,0BAA0BpB,OAAO,kBAAkBg3B,UAAU;;;gBAK9E,KAAKl3B,QAAQmB,KAAKpB,SAASF,WAAW;qBACjC;wBACG,IAAIu3B,cAAcC;wBAClBD,eAAep3B;wBACfq3B,eAAep0B,KAAKlD,SAASF,UAAUu3B;wBACvCn0B,KAAKlD,SAASF,UAAUu3B,gBAAgB;4BACpC,OAAOH,aAAaG,cAAcC,cAAc32B;;;;;;;KCh0DvE;QACG;QAEAxB,GAAGo4B,oBAAoB,SAASpd;YAC5B,IAAIjX,OAAO9B;YAGXA,KAAKpB;gBACD+kB,OAAO;gBACPM,QAAQ;gBACR9Y,UAAU;gBACVgc,gBAAgB;gBAChBiP,6BAA6B;gBAC7B1G,YAAY;gBAEZrI;oBACIE;oBACA3I,UAAU;oBACVyX,eAAe;oBACfC,gBAAgB;oBAChB9L,WAAW;oBACXtD,QAAQ;oBACR3pB;oBACAg5B,cAAc;oBACdC,mBAAmB;oBACnBlP,UAAU;;gBAGdwC;oBACIC;oBACA+G,WAAW;oBACXC,cAAc;oBACd0B,WAAW;oBACXZ,wBAAwB;oBACxB5Y,aAAa;oBACb0c;wBACIc,WAAW;wBACXC,UAAU;wBACVC,WAAW;wBACXC,UAAU;;oBAEdpB,YAAY;;gBAGhB92B;oBACI02B,UAAU,SAAS7Z,IAAIxc;oBACvBo0B,aAAa,SAAS5X,IAAIxc;oBAC1BssB,YAAY,SAAS9P,IAAIxc,MAAMqtB,cAAcyK;oBAC7CzE,eAAe,SAASF,YAAYC;oBACpC5G,UAAU,SAAShQ,IAAIxc;oBACvB6sB,UAAU,SAASrQ,IAAIxc;oBACvB+sB,eAAe,SAASvQ,IAAIxc,MAAMgtB;oBAClCE,sBAAsB,SAAS1Q,IAAIwQ,WAAWK,cAAc7W;oBAC5D2W,UAAU,SAAS3Q,IAAIrI,UAAU6Y;oBACjCd,YAAY,SAAS1P,IAAIxc,MAAMmsB,QAAQC;oBACvCyI,iBAAiB,SAAS1I,QAAQC;oBAClCpE,SAAS,SAASxL,IAAIxc,MAAMwjB,QAAQuU;oBACpC3K,aAAa,SAAS5Q,IAAIxc,MAAMg4B;oBAChCrE,eAAe,SAASnX,IAAIxc;oBAC5Bu1B,iBAAiB,SAAS0C;oBAC1BjF,YAAY,SAASiF;oBACrBxD,gBAAgB,SAASjY;oBACzBoM,UAAU,SAASpM;oBACnBsM,kBAAkB,SAAStM,IAAIuM,UAAUC;oBACzCQ,iBAAiB,SAAS3b;oBAC1B6P,gBAAgB,SAASlB,IAAIuB,WAAWD;oBACxCkY,0BAA0B,SAASvD,UAAUpkB,SAAS0a;;gBAG1DwI;oBACI2G,WAAW;oBACXC,WAAW;oBACXC,cAAc;oBACdC,YAAY;oBACZC,cAAc;oBACdnD,mBAAmB;oBACnBoD,qBAAqB;oBACrBC,oBAAoB;oBACpBC,qBAAqB;oBACrBC,oBAAoB;oBACpBC,uBAAuB;oBACvBjD,SAAS;oBACTnD,8BAA8B;;gBAGlC5M;oBACIuQ,YAAY;oBACZC,iBAAiB;oBACjB3C,kBAAkB;oBAClBvH,8BAA8B;;gBAGlCZ;oBACIE,aAAa;oBACbD,aAAa;;gBAGjB9T;oBACIyK,SAAS;oBACT2W;wBACI3W,SAAS;;oBAEb4W,WAAW;oBACXC;wBACIC,WAAW;wBACXC,gBAAgB;wBAChBC,WAAW;wBACXC,eAAe;wBACfC,YAAY;;oBAEhBC,UAAU;oBAEV/qB;wBACIwR,UAAU;;;gBAIlBvH;oBACI2J,SAAS;oBACToX,iBAAiB;oBACjBP;wBACIQ,UAAU;;;gBAIlBxH,gBAAgB,SAASyH;oBACrB,OAAOA;;gBAGXzyB;oBACI6rB,sBAAsB;oBACtBhH,gBAAgB;oBAChBoC,eAAc,MAAM,MAAM,MAAM,MAAM,MAAM;;gBAGhD3L;oBACIH,SAAS;oBACTkG,QAAQ;oBACRtI,UAAU;oBACV2I;oBACAhqB;;gBAGJmqB;oBACIoI,UAAU;oBACVyI,iBAAiB;oBACjBxI,UAAU;;gBAGdxQ;oBACIC,aAAa;;gBAGjB4I;oBACID,eAAe;oBACf3I,aAAa;;gBAGjB6O;oBACI1e,KAAK;oBAGLsU,QAAQ;;gBASZkJ;gBAIA/I;oBACIxF,UAAU;oBACVrhB;oBACAgqB;oBACAlD,gBAAgB;;gBAIpBlS;oBAEI1R,SAAS;oBAGTivB,YAAY;oBAGZ8I,iBAAiB;;gBAIrBlhB;oBACImhB,eAAe;oBAGfC,cAAc;oBAGdC,QAAQ;oBAIRC,aAAa;oBAEbC,gBAAgB;oBAEhBC,aAAa;oBAEbC,aAAa;oBAGbC;;gBAGJ/O;oBACIC,gBAAgB;oBAChBkH,mBAAmB;oBACnB7G,kBAAkB;;;YAK1BxsB,GAAGuG,OAAOtE,KAAKpB,UAAUma,GAAG;YAE5B/Y,KAAKgkB;YACLhkB,KAAKktB;YACLltB,KAAK0iB;YAEL1iB,KAAK61B;YACL71B,KAAK2qB,kBAAmB,IAAI5sB,GAAGoV;YAE/BnT,KAAKmf;YACLnf,KAAK6jB;YACL7jB,KAAK8jB;YACL9jB,KAAK+jB;YACL/jB,KAAKiiB;YAELjiB,KAAKyjB,uBAAuB;YAC5BzjB,KAAKqjB,eAAe;YACpBrjB,KAAK+gB,cAAc/gB,KAAKwpB;YAExBxpB,KAAKqvB;YAELrvB,KAAKilB,sBAAsBjlB,KAAK0oB,aAAa1oB,KAAKpB,SAASyoB,QAAQE;YACnEvnB,KAAKolB,gCAAgCplB,KAAK0oB,aAAa1oB,KAAKpB,SAASuiB,WAAWoG;YAEhFvnB,KAAKwlB,yBAAyBxlB,KAAK0oB,aAAa1oB,KAAKpB,SAASuiB,WAAW5jB;YAEzEyC,KAAK4iB,iBAAiB5iB,KAAK0oB,aAAa1oB,KAAKpB,SAASyoB,QAAQzI;YAC9D5e,KAAKslB,2BAA2BtlB,KAAK0oB,aAAa1oB,KAAKpB,SAASuiB,WAAWvC;YAE3E5e,KAAKwgB,WAAWxgB,KAAK4qB;YAErB5qB,KAAKyzB,iBAAiB11B,GAAGkpB,2BAA2BjnB,KAAKgnB;YAEzD,IAAIhnB,KAAKpB,SAASqlB,QAAQ;gBACtBjkB,KAAKwtB,mBAAmBxtB,KAAK4pB;oBACzBnpB,SAAST,KAAKpB,SAASqlB;oBACvB1K,OAAOvZ,KAAKpB,SAASiH,KAAK6kB;mBAC3BlQ;;YAGPxa,KAAKitB;YAELjtB,KAAKouB;YAEL,IAAIpuB,KAAKpB,SAASwpB,MAAMD,eAAe;gBACnC,IAAIpqB,GAAGmqB,cAAc;oBACjBloB,KAAKmkB,gBAAgBnkB,KAAKioB;uBAEzB;oBACDjoB,KAAKG,IAAI,kCAAkC;;;YAInDH,KAAKu0B;YAELv0B,KAAKgiB,kBAAkBjkB,GAAGk7B,kBAAkB,IAAIl7B,GAAGk7B,eAAel7B,GAAG+S,KAAK9Q,KAAKG,KAAKH;YACpFA,KAAKskB;YAELtkB,KAAKukB;YACLvkB,KAAKwkB;YAELxkB,KAAKk5B,UAAWn7B,GAAG+mB,UAAU,IAAI/mB,GAAG+mB,OAAO9kB,KAAKpB,SAAS0Y,SAASvZ,GAAG+S,KAAK9Q,KAAKG,KAAKH;YACpF,IAAIA,KAAKk5B,QAAQlY,SAAS;gBACtBhhB,KAAK8uB,wBAAwB/wB,GAAG+S,KAAK9Q,KAAKk5B,QAAQC,eAAen5B,KAAKk5B;;YAG1E,IAAIn7B,GAAGq7B,iBAAiBr7B,GAAGgW,kBAAkBqD,aAAa;gBACtDpX,KAAKykB,iBAAiB,IAAI1mB,GAAGq7B,cACzBr7B,GAAG+S,KAAK9Q,KAAK2zB,kBAAkB3zB,OAE/B,SAASub;oBACL,IAAI8d,QAAQv3B,KAAKif,YAAYrE;wBAAUnB,IAAIA;;oBAC3C,OAAQ8d,SAASA,MAAM/c,QAAS;;;YAK5Ctc,KAAKwjB,oBAAoBxjB,KAAKpB,SAASkrB,WAAW2I;;QAItD10B,GAAGo4B,kBAAkB92B,YAAYtB,GAAG0gB;QACpC1gB,GAAGuG,OAAOvG,GAAGo4B,kBAAkB92B,WAAWtB,GAAGsoB;;ICnTjDtoB,GAAGu7B,gBAAgB,SAASvgB;QACxB;QAEA,IAAI5Y,KAAKo5B,6BACLC,YACAC,kBACAz8B;YACI08B,cAAc;YACdC,gBAAe,SAAS,QAAQ;YAChCzS,QAAQ;YACR0S,aAAa;YACbzS,gBAAgB;YAChBI;YACAE;YACAD;YACAqS;YACAC,oCAAoC;YACpCC;gBACIC,UAAS,KAAK,KAAK;gBACnBC,SAAQ,KAAK,KAAK,KAAK,KAAK;gBAC5BC,QAAO,KAAK,KAAK,KAAK,KAAK;gBAC3BC,OAAM,KAAK,KAAK,KAAK,KAAK;gBAC1BC,OAAM;;YAEV1S;gBACIoI,UAAU;gBACVyI,iBAAiB;;YAErBp4B,KAAK,SAASsJ,KAAKvB;YACnBmyB,QAAQ,SAAS9e;YACjB8P,YAAY,SAAS9P,IAAIuM,UAAUC;YACnCkD,YAAY;;QAGpBltB,GAAGuG,OAAOtH,SAAS+b;QACnB5Y,MAAMnD,QAAQmD;QAEd,IAAIpC,GAAG4J,QAAQ3K,QAAQ28B,cAAc38B,QAAQkqB,UAAU,GAAG;YACtD,MAAM,IAAIjjB,MAAM,MAAMjH,QAAQkqB,SAAS;;QAM3C,SAASoT;YACL,OAAOv8B,GAAG4J,UAAS,OAAO,QAAQ,UAAS3K,QAAQkqB,WAAW;;QAMlE,SAASqT,yBAAyBvV;YAC9B,IAAIwV,oBAAoB;YAExBz8B,GAAGY,KAAK67B,mBAAmB,SAAS76B,KAAK86B;gBACrC,IAAI18B,GAAG4J,UAAS,UAAU,mBAAmB,oBAAoB,kBAAiB8yB,UAAU,GAAG;oBAC3FD,oBAAoB;oBACpB,OAAO;;;YAIf,OAAOA;;QAGX,SAASE,MAAMnlB;YAEX,OAAOvY,QAAQ0qB,KAAKoI,YAAYva,IAAIC,oBAAoBnX;;QAI5D,SAASs8B;YACL,IAAI7S;YAEJ,IAAI9gB,OAAOuE,kBAAkBvE,OAAOwE,eAAe;gBAC/Csc,WAAW/pB,GAAGsN;gBAEd,IAAIyc,SAAStS,oBAAoBnX,WAAW;oBACxCypB,WAAW,IAAIpS;oBAEfoS,SAAS3a,SAAS;oBAClB2a,SAASza,UAAU;oBACnBya,SAAS8S,YAAY;oBACrB9S,SAAS+S,aAAa;;;YAI9B,OAAO/S;;QAIX,SAASgT,YAAYvf,IAAIwf;YACrB,IAAIjT,WAAW2R,YAAYle,IAAIhG;YAE/B,KAAKuS,UAAU;gBACX,IAAIiT,aAAa;oBACbjT,WAAWiT;uBAEV;oBACD,IAAI/9B,QAAQ0qB,KAAKoI,UAAU;wBACvBhI,WAAW6S;2BAEV;wBACD7S,WAAW/pB,GAAGsN;;;gBAItBouB,YAAYle,IAAIhG,MAAMuS;;YAG1B,OAAOA;;QAIX,SAASkT,QAAQzf;YACb,IAAI5J,IAAI5T,GAAG4J,QAAQ6xB,OAAOje,KACtBwR,MAAM/vB,QAAQmqB,gBACd8T;mBAEGxB,YAAYle;YACnBie,MAAMxc,OAAOrL,GAAG;YAEhB,IAAI6nB,MAAMr3B,UAAU4qB,OAAOpb,IAAIob,KAAK;gBAChCkO,SAASzB,MAAMzM,MAAM;gBACrBmO,YAAYD;;;QAIpB,SAAS5P,WAAW9P,IAAI4f;YACpB,IAAI5lB,MAAMulB,YAAYvf,KAClB2L,SAASlqB,QAAQkqB,QACjBa,UAAUoT,aAAa;YAE3BH,QAAQzf;YAER,IAAIwM,SAAS;gBACT5nB,IAAI+mB,SAAS,kBAAkB3L,KAAK,eAAe;mBAElD,KAAKmf,MAAMnlB,SAAS6lB,qBAAqB7lB,IAAIqG,SAAS;gBACvDmM,UAAU;gBACV5nB,IAAI+mB,SAAS,kBAAkB3L,KAAK,iCAAiChG,IAAIqG,QAAQ;;YAGrF5e,QAAQquB,WAAW9P,IAAIhG,KAAKwS;;QAGhC,SAASsT,UAAU9f;YACf,IAAI+f,iBAAiB7B,YAAYle,IAAIggB,kBACjC1B,iBAAiB78B,QAAQ68B,gBACzBt8B;YAEJ,IAAIP,QAAQwqB,YAAY3E,KAAK;gBACzBtlB,SAASP,QAAQwqB,YAAY3E,IAAItH;;YAGrC,IAAI+f,gBAAgB;gBAChBv9B,GAAGY,KAAK28B,gBAAgB,SAASv8B,MAAMZ;oBACnCZ,SAASA;oBACTA,OAAOwB,QAAQZ;;;YAIvB,IAAI07B,gBAAgB;gBAChB97B,GAAGY,KAAKk7B,gBAAgB,SAAS96B,MAAMZ;oBACnCZ,SAASA;oBACTA,OAAOwB,QAAQZ;;;YAIvB,OAAOZ;;QAGX,SAAS29B,YAAY3f,IAAIigB;YACrB,IAAIjmB,MAAMulB,YAAYvf,IAAIigB,SACtBtU,SAASlqB,QAAQkqB,QACjB3pB,SAAS89B,UAAU9f,KACnBkgB,UAAUhC,YAAYle,IAAIkgB,SAC1BC;YAEJ1+B,QAAQq9B,OAAO9e;YAEfmgB,MAAMC,UAAUpgB,IAAIhe,QAAQk8B,YAAYle,IAAIqgB;YAG5C,IAAIlB,MAAMnlB,MAAM;gBACZA,IAAIpI,SAAS0uB,kBAAkBtgB;gBAC/BhG,IAAIlI,UAAUyuB,mBAAmBvgB;mBAEhC;gBACDhG,IAAIwmB,qBAAqBC,8BAA8BzgB;;YAG3D0gB,0BAA0B1gB;YAG1BhG,IAAI2mB,KAAKhV,QAAQwU,KAAK;YAItB,IAAI1+B,QAAQ0qB,KAAKoI,YAAY9yB,QAAQ0qB,KAAK6Q,oBAAoBmC,MAAMnlB,MAAM;gBACtEA,IAAIC,kBAAkB;;YAG1B2mB,WAAW5gB;YAEXpb,IAAI,aAAa+mB,SAAS,kBAAkB3L;YAE5C,IAAIkgB,SAAS;gBACTlmB,IAAI6mB,KAAKX;mBAER,IAAIlC,gCAAgCh8B,QAAQ;gBAC7CgY,IAAI6mB;mBAEH,IAAI7+B,UAAUP,QAAQ48B,eAAe58B,QAAQ48B,YAAY97B,cAAc6J,QAAQ,wCAAwC,GAAG;gBAC3H4N,IAAI6mB,KAAKr+B,GAAGoT,QAAQ5T,QAAQ;mBAE3B,IAAIA,UAAUP,QAAQ48B,eAAe58B,QAAQ48B,YAAY97B,cAAc6J,QAAQ,uBAAuB,GAAG;gBAC1G4N,IAAI6mB,KAAK5pB,KAAK6pB,UAAU9+B;mBAEvB;gBACDgY,IAAI6mB,KAAK7+B;;YAGb,OAAOgY;;QAGX,SAASomB,UAAUpgB,IAAIhe,QAAQq+B;YAC3B,IAAIhd,WAAW5hB,QAAQyqB,cAAc5E,IAAItH,KACrC+gB,YAAY7C,YAAYle,IAAI+gB;YAGhC,IAAIA,aAAaj+B,WAAW;gBACxBugB,YAAY,MAAM0d;;YAGtB,IAAI/C,+BAA+Bh8B,QAAQ;gBACvCqhB,WAAW7gB,GAAGoT,QAAQ5T,QAAQqhB;;YAGlC,IAAIgd,uBAAuB;gBACvBhd,WAAW7gB,GAAGoT,QAAQyqB,uBAAuBhd;;YAGjD,OAAOA;;QAKX,SAASod,8BAA8BzgB;YACnC,OAAO;gBACH,IAAIuf,YAAYvf,IAAIghB,eAAe,GAAG;oBAClClR,WAAW9P;;;;QAKvB,SAAS0gB,0BAA0B1gB;YAC/B,IAAI0P,aAAajuB,QAAQiuB;YAEzB,IAAIA,YAAY;gBACZ6P,YAAYvf,IAAIjQ,OAAOuvB,aAAa,SAAS1qB;oBACzC,IAAIA,EAAEqsB,kBAAkB;wBACpBvR,WAAW1P,IAAIpL,EAAE+a,QAAQ/a,EAAEgb;;;;;QAQ3C,SAAS0Q,kBAAkBtgB;YACvB,OAAO;gBACH8P,WAAW9P;;;QAMnB,SAASugB,mBAAmBvgB;YACxB,OAAO;gBACH8P,WAAW9P,IAAI;;;QAIvB,SAAS4gB,WAAW5gB;YAChB,IAAIhG,MAAMulB,YAAYvf,KAClBgM,gBAAgBvqB,QAAQuqB,eACxBkV,kBAAkBhD,YAAYle,IAAImhB,yBAClCxV,SAASlqB,QAAQkqB,QACjByV;YAGJ,KAAKjC,MAAMnlB,MAAM;gBACbvY,QAAQ08B,gBAAgBnkB,IAAIqnB,iBAAiB,UAAU5/B,QAAQ08B;gBAG/D,IAAI18B,QAAQ88B,oCAAoC;oBAK5C,KAAK98B,QAAQ0qB,KAAKoI,cAAcwK,oBAAoBC,yBAAyBhT,iBAAiB;wBAC1FhS,IAAIqnB,iBAAiB,oBAAoB;wBACzCrnB,IAAIqnB,iBAAiB,iBAAiB;;;gBAI9C,IAAI5/B,QAAQ48B,gBAAgB1S,WAAW,UAAUA,WAAW,QAAQ;oBAChE3R,IAAIqnB,iBAAiB,gBAAgB5/B,QAAQ48B;;gBAGjD77B,GAAGuG,OAAOq4B,YAAY5+B,GAAGyK,WAAW+e,iBAAiBA,cAAchM,MAAMgM;gBACzExpB,GAAGuG,OAAOq4B,YAAYF;gBAEtB1+B,GAAGY,KAAKg+B,YAAY,SAAS59B,MAAMZ;oBAC/BoX,IAAIqnB,iBAAiB79B,MAAMZ;;;;QAKvC,SAASi9B,qBAAqByB;YAC1B,OAAO9+B,GAAG4J,QAAQ3K,QAAQ+8B,wBAAwB/8B,QAAQkqB,SAAS2V,iBAAiB;;QAGxF,SAASC,cAAcvhB,IAAIigB,QAAQc,WAAWf,kBAAkBK,uBAAuBc,mBAAmBjB;YACtGhC,YAAYle;gBACR+gB,WAAWA;gBACXf,kBAAkBA;gBAClBK,uBAAuBA;gBACvBc,mBAAmBA;gBACnBjB,SAASA;;YAGb,IAAIttB,MAAMqrB,MAAM35B,KAAK0b;YAGrB,IAAIpN,OAAOnR,QAAQmqB,gBAAgB;gBAC/B,OAAO+T,YAAY3f,IAAIigB;;;QAI/BjC,8BAA8Bv8B,QAAQkqB,WAAW,SAASlqB,QAAQkqB,WAAW;QAE7EnpB,GAAGuG,OAAOtE;YAEN+8B,eAAe,SAASxhB;gBACpB,IAAIyhB,MAAMz/B,QAAQynB,SAASyW,SAASwB,aAAarB;gBAEjD;oBAEIsB,UAAU,SAASC;wBACfH,OAAOG;wBACP,OAAOn9B;;oBAOXo9B,YAAY,SAAS7B;wBACjBh+B,SAASg+B;wBACT,OAAOv7B;;oBAGXq9B,iBAAiB,SAASC;wBACtB1B,wBAAwB0B;wBACxB,OAAOt9B;;oBAIXu9B,aAAa,SAASb;wBAClB1X,UAAU0X;wBACV,OAAO18B;;oBAIXw9B,aAAa,SAASC;wBAClBhC,UAAUgC;wBACV,OAAOz9B;;oBAIX09B,iBAAiB;wBACbT,cAAc;wBACd,OAAOj9B;;oBAIXo8B,MAAM,SAASZ;wBACX,IAAIyB,eAAel/B,GAAG4J,UAAS,OAAO,YAAW3K,QAAQkqB,WAAW,GAAG;4BACnE3pB,OAAOogC,cAAc,IAAIC,OAAOC;;wBAGpC,OAAOf,cAAcvhB,IAAIigB,QAAQwB,MAAMz/B,QAAQq+B,uBAAuB5W,SAASyW;;;;YAK3FqC,UAAU,SAASviB;gBACfyf,QAAQzf;;;;IC1YpBxd,GAAGggC,gBAAgB,SAAS5hB;QACxB;QAEA,IAAI6hB,QAAQ7hB,KAAK6hB,OACbC,gBACA1S,WAAWyS,MAAMzS,UACjBtK,UAAU+c,MAAM/c;QAEpBljB,GAAGuG,OAAOtE;YACNyR,KAAK,SAAS8J,IAAI2iB;gBACdD,UAAU1iB,MAAM2iB;gBAChBD,UAAU1iB,IAAIlK;;YAGlBkP,QAAQ,SAAShF;gBACb,IAAIzZ,OAAO9B,MACPwrB,2BAA2B,IAAIztB,GAAGmP,WAClCixB,iBAAiB5S,SAAShQ,IAAI0F,QAAQ1F,KAAKiQ;gBAE/C2S,eAAenmB,KAAK;oBAChB,IAAIlW,KAAKyf,QAAQhG,KAAK;wBAClB0iB,UAAU1iB,IAAIuiB,WAAW;wBACzBh8B,KAAK+wB,QAAQtX;;oBAEjBiQ,yBAAyBpe;;;YAIjCylB,SAAS,SAAStX;uBACP0iB,UAAU1iB;;YAGrB6iB,qBAAqB,SAAS7iB;gBAC1B,OAAO0iB,UAAU1iB,IAAIrd;;YAGzBqjB,SAAS,SAAShG;gBACd,OAAO0iB,UAAU1iB,QAAQld;;YAG7Bwc,OAAO;gBACHojB;;YAGJI,eAAe,SAAS9iB;gBACpB,OAAO0iB,UAAU1iB;;YAGrB+iB,sBAAsB,SAAS/iB,IAAIgjB;gBAC/BN,UAAU1iB,IAAIrd,MAAMqgC;;YAGxBC,cAAc,SAASjjB;gBACnB,SAAS0iB,UAAU1iB,IAAIuiB;;;;ICpDnC//B,GAAG4uB,0BAA0B,SAAS5T,GAAGrb;QACrC;QAEA,IAAI+gC,aAAaz+B,MACb0+B,mBAAmB,OACnBC,6BAA6B,OAC7BpoB,UAAUqoB,sBAAsBz+B,KAAK0uB,SAEzC7xB;YACIwqB;YACAL,gBAAgB;YAChB5Q;gBACIyK,SAAS;gBACT7V;oBACI6V,SAAS;;;YAGjB7gB,KAAK,SAASsJ,KAAKvB;YACnB+iB,YAAY,SAAS1P,IAAIrI,UAAUgY,QAAQC;YAC3CE,YAAY,SAAS9P,IAAIrI,UAAUse,UAAUjc;YAC7CgW,UAAU,SAAShQ,IAAIrI;YACvBwY,cAAc,SAASnQ;YACvBqQ,UAAU,SAASrQ,IAAIrI;YACvB4Y,eAAe,SAASvQ,IAAIrI,UAAU6Y;YACtCE,sBAAsB,SAAS1Q,IAAIwQ,WAAWyF,UAAUjc;YACxD4W,aAAa,SAAS5Q,IAAIrI,UAAUse,UAAUjc;YAC9C2W,UAAU,SAAS3Q,IAAIrI,UAAU6Y;YACjCO,eAAe,SAAS/Q,IAAI2B;YAC5B+D,SAAS,SAAS1F;YAClBgR,SAAS,SAAShR,IAAIgC;YACtBmP,UAAU,SAASnR;YACnBoC,oBAAoB,SAASpC;YAC7BqC,eAAe,SAASrC;WAG5BsjB;YAEIpmB,MAAM,SAAS8C,IAAIujB,UAAUtN,UAAUjc;gBACnC,IAAIwW,YAAY8C,QAAQkQ,cAAcxjB,IAAIujB;gBAE1CjQ,QAAQwP,cAAc9iB,IAAIyjB,mBAAmB;uBAEtCnQ,QAAQwP,cAAc9iB,IAAIlK,KAAK4tB,cAAcH;gBACpDjQ,QAAQwP,cAAc9iB,IAAI2P,UAAUa,UAAUzP;gBAE9Ctf,QAAQivB,qBAAqB1Q,IAAIsT,QAAQqQ,yBAAyBnT,YAAYyF,UAAUjc;;YAK5F4pB,UAAU,SAAS5jB;gBACf,IAAIe,OAAOtf,QAAQmmB,QAAQ5H,KACvBxc,OAAO/B,QAAQikB,QAAQ1F;gBAE3Bpb,IAAI,uCAAuCob,KAAK;gBAChDsT,QAAQuQ,eAAe7jB,IAAIvD,KACvB,SAASwZ,UAAUjc;oBACfpV,IAAI,6BAA6Bob;oBAEjC,IAAI8jB,oBAAoB/zB,OAAOg0B,kBAAkB9N,UAAU;oBAE3Dx0B,QAAQiuB,WAAW1P,IAAIxc,MAAMud,MAAMA;oBACnCuS,QAAQ0Q,+BAA+BhkB;oBACvCjQ,OAAOk0B,QAAQjkB,IAAI8jB,mBAAmB9pB;mBAE1C,SAASic,UAAUjc;oBACf,IAAI8pB,oBAAoB/zB,OAAOg0B,kBAAkB9N,UAAU;oBAE3DrxB,IAAI,2CAA2Cob,KAAK,QAAQ8jB,kBAAkBn/B,OAAO;oBAErF,IAAIm/B,kBAAkBxkB,OAAO;wBACzBgkB,QAAQhkB,MAAMU;;oBAGlB,KAAKve,QAAQmvB,YAAY5Q,IAAIxc,MAAMsgC,mBAAmB9pB,MAAM;wBACxDjK,OAAOk0B,QAAQjkB,IAAI8jB,mBAAmB9pB;;;;YAMtDkqB,eAAe,SAASX,UAAUvjB,IAAIiW,UAAUjc;gBAC5C,IAAIxW,OAAO/B,QAAQikB,QAAQ1F;gBAE3Bpb,IAAI,uCAAuCob,KAAK,aAAaujB;gBAE7DjQ,QAAQ6Q,iBAAiBnkB,IAAIujB;gBAE7B,IAAIa,mBAAmBr0B,OAAOg0B,kBAAkB9N,UAAU,QACtDoO;gBAEJ,IAAID,iBAAiB9kB,OAAO;oBACxBgkB,QAAQhkB,MAAMU;uBAEb;oBACDqkB,gBAAgB7hC,GAAG4J,QAAQknB,QAAQwP,cAAc9iB,IAAIhF,SAASspB,YAAYf;oBAC1E,IAAIc,iBAAiB,GAAG;wBACpB/Q,QAAQwP,cAAc9iB,IAAIhF,SAASspB,WAAW7iB,OAAO4iB,eAAe;wBACpE/Q,QAAQwP,cAAc9iB,IAAIhF,SAASupB,UAAUC,QAAQjB;;;gBAM7D,KAAKjQ,QAAQwP,cAAc9iB,IAAIlK,KAAK2uB,eAAe;oBAG/C,IAAIrB,4BAA4B;wBAC5B9P,QAAQwP,cAAc9iB,IAAIlK,KAAK2uB,gBAAgB;wBAE/C7/B,IAAIpC,GAAGyL,OAAO,oFAAoFgJ,KAAK6pB,UAAU/zB,OAAO23B,KAAKpR,QAAQqR,SAAS3kB,OAAO/I,KAAK6pB,UAAUxN,QAAQwP,cAAc9iB,IAAIhF,SAASspB;wBACvM9hC,GAAGY,KAAKkwB,QAAQqR,SAAS3kB,KAAK,SAAS4kB,MAAMC;4BACzCjgC,IAAIpC,GAAGyL,OAAO,uDAAuD+R,IAAI4kB,MAAMC,MAAM7D;4BACrF6D,MAAMC;4BAGND,MAAME,aAAa;;wBAIvBzR,QAAQ0R,0BAA0BhlB;wBAIlCilB,kBAAkBC,KAAKllB,IAAI;;oBAG/B,KAAKve,QAAQmvB,YAAY5Q,IAAIxc,MAAM4gC,kBAAkBpqB,MAAM;wBAIvDjK,OAAOk0B,QAAQjkB,IAAIokB,kBAAkBpqB;;;;YAKjDmrB,cAAc,SAASnlB;gBACnB,SAASsT,QAAQwP,cAAc9iB,IAAIhF,SAASupB,UAAU39B;;YAG1Dw+B,UAAU,SAASplB;gBACf,IAAIqlB,UAAU/R,QAAQwP,cAAc9iB,IAAIhF,SAASupB,UAAUvsB;gBAE3D,IAAIqtB,WAAW/R,QAAQgS,gBAAgBtlB,KAAK;oBACxCqlB,UAAU;;gBAGd,OAAOA;;YAGX/lB,OAAO,SAASU;gBACZpb,IAAI,gGAAgGob,IAAI;gBAExGsT,QAAQ0Q,+BAA+BhkB;gBACvCsT,QAAQiS,mBAAmBvlB;gBAC3BsT,QAAQwP,cAAc9iB,IAAI2P,SAAS;;YAGvC6V,UAAU,SAASxlB;gBACf,IAAIe,OAAOtf,QAAQmmB,QAAQ5H,KACvBxc,OAAO/B,QAAQikB,QAAQ1F,KACvBujB,WAAWD,QAAQ8B,SAASplB,KAC5BwQ,YAAY8C,QAAQkQ,cAAcxjB,IAAIujB,WACtCzG,WAAWxJ,QAAQwP,cAAc9iB,IAAIyjB,kBACrCgC,mBAAmBnS,QAAQwP,cAAc9iB,IAAIhF,SAASspB;gBAE1D,IAAIhR,QAAQwP,cAAc9iB,IAAI2P,UAAU,MAAM;oBAC1C2D,QAAQwP,cAAc9iB,IAAI2P,SAAS;;gBAIvC,IAAImN,YAAYr7B,QAAQkvB,SAAS3Q,IAAIxc,MAAMgtB,eAAe,OAAO;oBAC7D8S,QAAQhkB,MAAMU;oBACdujB,WAAWD,QAAQ8B,SAASplB;oBAC5BwQ,YAAY8C,QAAQkQ,cAAcxjB,IAAIujB;oBACtCzG,WAAW;;gBAIf,IAAIyG,YAAY,QAAQkC,iBAAiB7+B,WAAW,GAAG;oBACnD08B,QAAQM,SAAS5jB;uBAIhB;oBACDpb,IAAIpC,GAAGyL,OAAO,qEAAqE+R,IAAIujB,UAAU/S,UAAU5f,QAAQ,GAAG4f,UAAU3f,KAAKkQ;oBACrItf,QAAQ8uB,cAAcvQ,IAAIxc,MAAM8vB,QAAQqQ,yBAAyBnT;oBACjEiV,iBAAiBnhC,KAAKi/B;oBACtBjQ,QAAQwP,cAAc9iB,IAAIhF,SAASspB,aAAamB;oBAEhD,IAAIrC,4BAA4B;wBAC5B6B,kBAAkBtE,KAAK3gB,IAAIujB;;oBAG/B,IAAIH,8BAA8B6B,kBAAkBS,eAAepS,QAAQwP,cAAc9iB,IAAIhF,SAASupB,UAAU39B,QAAQ;wBACpH08B,QAAQkC,SAASxlB;;oBAGrB,IAAIwQ,UAAUnf,KAAK0P,SAAS,GAAG;wBAC3Bnc,IAAIpC,GAAGyL,OAAO,gEAAgEs1B,UAAUvjB,KAAK;wBAC7FsjB,QAAQY,cAAcX,UAAUvjB,IAAI,+BAA+B;2BAElE;wBACDsT,QAAQqS,YAAY3lB,IAAIujB,UAAUzG,UAAUrgB,KAExC,SAAS5K,QAAQokB,UAAUjc;4BACvBpV,IAAI,0CAA0Cob,KAAK,aAAaujB;4BAEhEjQ,QAAQ6Q,iBAAiBnkB,IAAIujB;4BAE7B,IAAIkC,mBAAmBnS,QAAQwP,cAAc9iB,IAAIhF,SAASspB,kBACtDF,mBAAmBr0B,OAAOg0B,kBAAkB9N,UAAU,OACtD2P,qBAAqBpjC,GAAG4J,QAAQq5B,kBAAkBlC;4BAEtD3+B,IAAIpC,GAAGyL,OAAO,+CAA+Cs1B,UAAUvjB;4BAEvEsjB,QAAQpmB,KAAK8C,IAAIujB,UAAUa,kBAAkBpqB;4BAE7C,IAAI4rB,sBAAsB,GAAG;gCACzBH,iBAAiBhkB,OAAOmkB,oBAAoB;;4BAGhDtS,QAAQuS,0BAA0B7lB;4BAElC,KAAKsjB,QAAQ6B,aAAanlB,OAAOylB,iBAAiB7+B,WAAW,GAAG;gCAC5D08B,QAAQM,SAAS5jB;mCAEhB,IAAIsjB,QAAQ6B,aAAanlB,KAAK;gCAC/BsjB,QAAQkC,SAASxlB;mCAEhB;gCACDpb,IAAIpC,GAAGyL,OAAO,qGAAqG+R,IAAI/I,KAAK6pB,UAAU2E;;2BAK9I,SAAS1zB,QAAQkkB,UAAUjc;4BACvBspB,QAAQY,cAAcX,UAAUvjB,IAAIiW,UAAUjc;2BAGjDkD,KAAK;4BACFoW,QAAQwS,SAAS9lB,IAAIujB;;;;;WAO7C0B;YACIc;YACAC;YACAC;YAEAP,WAAW;gBACP,IAAIlU,MAAM/vB,QAAQmqB,gBACdsa,wBAAwB,GACxBC,kBAAkB;gBAEtB3jC,GAAGY,KAAK6hC,kBAAkBe,aAAa,SAAS9f,QAAQkgB;oBACpDF;oBACAC,mBAAmBC,iBAAiBx/B;;gBAGxC,OAAO4qB,OAAOyT,kBAAkBc,MAAMn/B,SAASs/B,wBAAwBC;;YAM3EjB,MAAM,SAASllB,IAAIqmB;gBACf,IAAIC,aAAaD,eACbE,eAAe/jC,GAAG4J,QAAQ64B,kBAAkBgB,UAAUjmB,KACtDwmB,mBAAmBhkC,GAAG4J,QAAQ64B,kBAAkBc,OAAO/lB,KACvD0f;uBAEGuF,kBAAkBe,YAAYhmB;gBAErC,IAAIjQ,OAAO02B,eAAezmB,eAAexd,GAAG2a,WAAW;oBACnDvY,IAAI,yCAAyCob,KAAK;2BAC3CsT,QAAQwP,cAAc9iB,IAAI4E;;gBAIrC,IAAI2hB,gBAAgB,GAAG;oBACnBtB,kBAAkBgB,SAASxkB,OAAO8kB,cAAc;uBAG/C,IAAID,aAAaE,oBAAoB,GAAG;oBACzCvB,kBAAkBc,MAAMtkB,OAAO+kB,kBAAkB;oBAEjD9G,SAASuF,kBAAkBgB,SAASjuB;oBACpC,IAAI0nB,UAAU,GAAG;wBACbuF,kBAAkBc,MAAMzhC,KAAKo7B;wBAC7B3vB,OAAOa,MAAM8uB;;;;YAKzBgH,uBAAuB;gBACnB,IAAIC;gBAIJnkC,GAAGY,KAAK6hC,kBAAkBe,aAAa,SAAS9f,QAAQ0gB;oBACpD,IAAIA,UAAUA,OAAOhgC,QAAQ;wBACzB+/B,mBAAmBriC,KAAKuiC,SAAS3gB;;;gBAMzC1jB,GAAGY,KAAK6hC,kBAAkBc,OAAO,SAAS3hC,KAAK8hB;oBAC3C,KAAK+e,kBAAkBe,YAAY9f,SAAS;wBACxCygB,mBAAmBriC,KAAKuiC,SAAS3gB;;;gBAKzCygB,qBAAqBA,mBAAmBhxB,OAAOsvB,kBAAkBgB;gBAEjE,OAAOU;;YAGXG,mBAAmB,SAAS9mB;gBACxB,OAAOxd,GAAG4J,QAAQ64B,kBAAkBc,OAAO/lB,OAAO;;YAGtD2gB,MAAM,SAAS3gB,IAAIujB;gBACf,IAAIA,YAAY,MAAM;oBAClB0B,kBAAkBgB,SAAS3hC,KAAK0b;;gBAGpC,IAAIilB,kBAAkBS,aAAa;oBAC/B,IAAInC,YAAY,MAAM;wBAClB0B,kBAAkBgB,SAASc;wBAC3B9B,kBAAkBc,MAAMzhC,KAAK0b;2BAE5B;yBACA;4BACG,IAAIgnB,kBAAkB/B,kBAAkBe,YAAYhmB;4BACpDgnB,gBAAgB1iC,KAAKi/B;4BACrB0B,kBAAkBe,YAAYhmB,MAAMgnB;;;oBAI5C,OAAO;;gBAGX,OAAO;;YAGX1nB,OAAO;gBACH2lB,kBAAkBgB;gBAClBhB,kBAAkBc;;WAI1BkB;YACIpG,MAAM,SAAS7gB,IAAIxc;gBACf8vB,QAAQwP,cAAc9iB,IAAI2P,SAAS;gBAEnC/qB,IAAI,uCAAuCob;gBAC3CsT,QAAQ4T,WAAWlnB,IAAIvD,KACnB,SAASwZ,UAAUgK;oBACfr7B,IAAI,yCAAyCob;oBAE7C,IAAIokB,mBAAmBr0B,OAAOg0B,kBAAkB9N,UAAU,OACtDlV,OAAOtf,QAAQmmB,QAAQ5H;oBAE3Bve,QAAQiuB,WAAW1P,IAAIxc,MAAMud,MAAMA;oBACnChR,OAAOo3B,aAAannB,IAAIokB;oBACxBr0B,OAAOk0B,QAAQjkB,IAAIokB,kBAAkBnE;mBAGzC,SAAShK,UAAUgK;oBACfr7B,IAAI,sCAAsCob;oBAE1C,IAAIokB,mBAAmBr0B,OAAOg0B,kBAAkB9N,UAAU;oBAE1D,KAAKx0B,QAAQmvB,YAAY5Q,IAAIxc,MAAM4gC,kBAAkBnE,SAAS;wBAC1DlwB,OAAOk0B,QAAQjkB,IAAIokB,kBAAkBnE;;;;WAOzDlwB;YACIiV,QAAQ,SAAShF;gBACbpb,IAAI,gBAAgBob;gBACpBve,QAAQwqB,YAAY3jB,OAAO0X;gBAC3BilB,kBAAkBC,KAAKllB;;YAG3BikB,SAAS,SAASjkB,IAAIiW,UAAUgK;gBAC5B,IAAIz8B,OAAO/B,QAAQikB,QAAQ1F;gBAE3Bve,QAAQquB,WAAW9P,IAAIxc,MAAMyyB,UAAUgK;gBAEvC,IAAI3M,QAAQwP,cAAc9iB,KAAK;oBAC3BsT,QAAQ8T,cAAc9T,QAAQ8T,WAAWpnB;;gBAG7CilB,kBAAkBC,KAAKllB;;YAK3BymB,gBAAgB,SAASzmB;gBACrB,OAAQsT,QAAQ+T,YAAY/T,QAAQ+T,SAASrnB,OACxCsT,QAAQ1M,WAAW0M,QAAQ1M,QAAQ5G;;YAG5CsnB,aAAa;gBACT,IAAIC,cAAcplC,YAAYK,GAAGL,aAAaK,GAAGglC,aAC7CC,uBAAuBjlC,GAAGgW,kBAAkBqC,gBAAgB,QAAQ;gBAExEyY,UAAU,IAAIiU,YAAYE,uBAAuB,iBAC7ChmC;oBAEIyvB,eAAezvB,QAAQyvB;oBACvBxL,SAASjkB,QAAQikB;oBACjBkC,SAASnmB,QAAQmmB;oBACjBO,SAAS1mB,QAAQ0mB;oBACjBvjB,KAAKA;oBACLorB,UAAUvuB,QAAQuuB;oBAClBN,YAAYjuB,QAAQiuB;oBACpBqB,eAAetvB,QAAQsvB;;gBAI/B,IAAIuC,QAAQoU,+BAA+B;oBACvCpU,QAAQoU;;;YAIhBC,6BAA6B,SAAS3nB;gBAClC,OAAOve,QAAQ0vB,SAASnR;;YAM5B4nB,YAAY,SAAS5nB,IAAI3O;gBAIrB,IAAIA,SAASiiB,QAAQ1M,QAAQ5G,OAAO3O,gBAAgB7O,GAAG2a,WAAW;oBAK9D1b,QAAQ0uB,aAAanQ;oBAErBpb,IAAI,iDAAiDob;oBACrD3O,KAAKiM,SAASb,KAAK,SAASorB;wBACxBjjC,IAAI,qCAAqCob;wBAGzCsT,QAAQwU,WAAW9nB,IAAI6nB;wBAGvBpmC,QAAQuvB,QAAQhR,IAAI6nB,cAAc9mB;wBAGlCuS,QAAQiS,mBAAmBvlB;wBAE3BjQ,OAAOg4B,uBAAuB/nB;uBAIlC,SAASyY;wBACL,IAAIuP;wBAEJ,IAAIvP,cAAc;4BACduP,cAAcrjC,QAAQ8zB;;wBAG1B7zB,IAAIpC,GAAGyL,OAAO,0DAA0D+R,IAAIyY,eAAe;wBAE3Fh3B,QAAQquB,WAAW9P,IAAIve,QAAQikB,QAAQ1F,KAAKxd,GAAGuG,OAAOi/B,eAAe3E,uBAAuB;wBAC5FtzB,OAAOg4B,uBAAuB/nB;wBAC9BilB,kBAAkBC,KAAKllB;;uBAG1B;oBACD,OAAOjQ,OAAOg4B,uBAAuB/nB;;gBAGzC,OAAO;;YAIX+nB,wBAAwB,SAAS/nB;gBAC7B,IAAIioB,aAAaxmC,QAAQ2gB,mBAAmBpC,KACxCkoB,iBAAiB;gBAErB,IAAID,cAAcA,WAAWrhC,QAAQ;oBACjChC,IAAI,4CAA4Cob;oBAEhDxd,GAAGY,KAAK6kC,YAAY,SAAS7jC,KAAK+jC;wBAC9B,IAAIp4B,OAAO43B,4BAA4BQ,gBAAgB7U,QAAQ1M,QAAQuhB,YAAY;4BAC/ED,iBAAiBC,cAAcnoB;4BAC/BjQ,OAAOq4B,IAAID;+BAEV,IAAIp4B,OAAO43B,4BAA4BQ,YAAY;4BACpD,OAAO;;;uBAId;oBACDD,iBAAiB;oBACjBn4B,OAAOq4B,IAAIpoB;;gBAGf,OAAOkoB;;YAGXf,cAAc,SAASnnB,IAAIiW;gBACvB,IAAIA,SAAStU,YAAY7e,WAAW;oBAChCrB,QAAQsvB,cAAc/Q,IAAIiW,SAAStU;;;YAO3CoiB,mBAAmB,SAASsE,kBAAkB1R;gBAC1C,IAAIV,WAAWoS;gBAIf,KAAK7lC,GAAGqK,SAASw7B,mBAAmB;oBAChCpS;oBAEA,IAAIzzB,GAAGmL,SAAS06B,sBAAsB1R,YAAY;wBAC9CV,SAAStxB,QAAQ0jC;;;gBAIzBpS,SAASpkB,UAAU8kB;gBAEnB,OAAOV;;YAGXmS,KAAK,SAASpoB;gBACV,IAAIxc,OAAO/B,QAAQikB,QAAQ1F;gBAE3B,KAAKkjB,WAAWld,QAAQhG,KAAK;oBACzB,MAAM,IAAIxd,GAAGkG,MAAMsX,KAAK;;gBAG5Bve,QAAQ4uB,SAASrQ,IAAIxc;gBAErB,IAAI2/B,oBAAoB7P,QAAQgV,qBAAqBtoB,KAAK;oBACtDsjB,QAAQkC,SAASxlB;uBAEhB;oBACDinB,OAAOpG,KAAK7gB,IAAIxc;;;YAIxBoN,OAAO,SAASoP;gBACZ,IAAIuoB,eAAex4B,OAAO02B,eAAezmB;gBAEzC,IAAIuoB,cAAc;oBACd,OAAOx4B,OAAO63B,WAAW5nB,IAAIuoB;uBAE5B;oBACDx4B,OAAOq4B,IAAIpoB;oBACX,OAAO;;;;QAKnBxd,GAAGuG,OAAOtE;YAINyR,KAAK,SAAS8J,IAAI4E;gBACd0O,QAAQpd,IAAI1R,MAAMC,MAAMT;;YAM5B+L,QAAQ,SAASiQ;gBACb,IAAIilB,kBAAkBtE,KAAK3gB,KAAK;oBAC5B,OAAOjQ,OAAOa,MAAMoP;;gBAExB,OAAO;;YAGXmJ,OAAO,SAASnJ;gBAKZ,IAAIojB,4BAA4B;oBAC5B9P,QAAQwP,cAAc9iB,IAAIlK,KAAK2uB,gBAAgB;;gBAKnD,IAAIQ,kBAAkB6B,kBAAkB9mB,KAAK;oBACzC,OAAOjQ,OAAOa,MAAMoP;uBAMnB;oBACD,OAAOkjB,WAAWnzB,OAAOiQ;;;YAOjCgF,QAAQ,SAAShF;gBACb,IAAIwoB,eAAelV,QAAQtO,OAAOhF;gBAElC,IAAIxd,GAAG+Z,iBAAiBisB,eAAe;oBACnCA,aAAa/rB,KAAK;wBACd1M,OAAOiV,OAAOhF;;uBAGjB,IAAIwoB,iBAAiB,OAAO;oBAC7Bz4B,OAAOiV,OAAOhF;;;YAOtBkF,WAAW;gBACP,IAAIyhB,qBAAqB1B,kBAAkByB,yBACvCtwB;gBAIJ,IAAIuwB,mBAAmB//B,QAAQ;oBAC3B,KAAKwP,IAAIuwB,mBAAmB//B,SAAS,GAAGwP,KAAK,GAAGA,KAAK;wBACjD8sB,WAAWle,OAAO2hB,mBAAmBvwB;;;gBAI7C6uB,kBAAkB3lB;;YAKtBsH,SAAS,SAAS5G;gBACd,IAAIsT,QAAQ+T,YAAY/T,QAAQ+T,SAASrnB,KAAK;oBAC1C,OAAOsT,QAAQ+T,SAASrnB,IAAI5C;;gBAGhC,OAAOkW,QAAQ1M,WAAW0M,QAAQ1M,QAAQ5G;;YAI9CyoB,WAAW,SAASzoB;gBAChB,UAAUsT,QAAQ+T,YAAY/T,QAAQ+T,SAASrnB;;YAGnDhB,UAAU,SAASgB;gBACf,IAAIsT,QAAQtU,UAAU;oBAClB,OAAOsU,QAAQtU,SAASgB;;;YAIhCV,OAAO;gBACH1a,IAAI;gBACJs+B,WAAWhe;gBACX+f,kBAAkB3lB;gBAClBgU,QAAQhU;;YAGZgY,SAAS,SAAStX;gBACd,IAAIkjB,WAAWld,QAAQhG,KAAK;oBACxB,OAAOsT,QAAQgE,QAAQtX;;;YAO/BgG,SAAS,SAAShG;gBACd,OAAOsT,QAAQtN,QAAQhG;;YAG3B2H,uBAAuB;gBACnB,IAAI2L,QAAQ3L,uBAAuB;oBAC/B,OAAO2L,QAAQ3L;;gBAEnB;;YAWJkb,qBAAqB,SAAS7iB;gBAC1B,IAAIkjB,WAAWld,QAAQhG,KAAK;oBACxB,OAAOsT,QAAQuP,oBAAoB7iB;;;YAS3CpE,OAAO,SAASoE;gBACZ,IAAIkjB,WAAWwF,YAAY1oB,OAAOsT,QAAQ1X,SAASsnB,WAAWld,QAAQhG,OAAOsT,QAAQ1X,MAAMoE,KAAK;oBAC5FilB,kBAAkBC,KAAKllB;oBACvBsT,QAAQ0R,0BAA0BhlB;oBAClC,OAAO;;gBAEX,OAAO;;YAIX0oB,aAAa,SAAS1oB;gBAClB,SAASsT,QAAQoV,eAAepV,QAAQoV,YAAY1oB;;;QAI5Dxd,GAAGuG,OAAOtH,SAAS+b;QACnB5Y,MAAMnD,QAAQmD;QACdu+B,mBAAmB1hC,QAAQuZ,SAASyK,WAAWjjB,GAAGgW,kBAAkBwC;QACpEooB,6BAA6BD,oBAAoB1hC,QAAQuZ,SAASohB,WAAW3W;QAE7E4d,uBAAwB;YACpB,IAAIpN;YAEJA,SAASx0B,QAAQ+tB,qBAAqB;YAEtC,OAAOyG;;QAGXlmB,OAAOu3B;;IC9uBX9kC,GAAGmmC,uBAAuB,SAASnrB;QAC/B;QAEA,IAAI/b;YACImD,KAAK,SAASC,SAAS8H;WAE3Bi8B;QAEJpmC,GAAGuG,OAAOtH,SAAS+b;QAEnBhb,GAAGuG,OAAOtE;YACNokC,gBAAgB,SAAS7oB,IAAI7K;gBACzB,IAAI2zB,2BAA2B,SAAS7P;oBAChC9jB,SAAS8jB,MAAMp2B;;gBAGvB,IAAI4I,OAAOmP,aAAa;oBACpBguB,yBAAyB5oB,MAAMxd,GAAGiJ,QAAQ/D,OAAO,WAAWohC;uBAE3D;oBACDlkC,IAAI,yDAAyD;;;YAIrEmkC,uBAAuB,SAAS/oB;gBAC5B,IAAIvU,OAAOmP,aAAa;oBACpB,IAAIouB,WAAWJ,yBAAyB5oB;oBACxC,IAAIgpB,UAAU;wBACVA;;;;;;ICvBpBxmC,GAAGymC,oBAAoB,SAASroB;QAC5B;QAEA,IAAInf,UAAUmf,KAAKnf,SACf6xB,UAAU7uB,MACVg+B,QAAQ7hB,KAAK6hB,OACbyG,wBAAwB1mC,GAAGsQ,eAC3Bq2B,sBACAC,uBACAC,gCACAC,SAAS7nC,QAAQ6nC,QACjBra,YAAYxtB,QAAQwtB,WACpB9G,UAAUsa,MAAMta,SAChBvjB,MAAM69B,MAAM79B,KACZ2kC,sBAAsB,IAAI/mC,GAAGmmC;YAAsB/jC,KAAKA;;QAO5D,SAAS4kC,YAAYxpB;mBACVopB,iBAAiBppB;YAKxB,IAAIspB,QAAQ;gBACRlS,aAAaiS,0BAA0BrpB;uBAChCqpB,0BAA0BrpB;gBACjCupB,oBAAoBR,sBAAsB/oB;;YAG9C,IAAIypB,SAAS/5B,SAASg6B,eAAepW,QAAQqW,eAAe3pB;YAC5D,IAAIypB,QAAQ;gBAIRA,OAAO5yB,aAAa,OAAO;gBAE3BrU,GAAGinC,QAAQnhC;;;QAQnB,SAASshC,uBAAuBC;YAC5B,OAAOA,WAAW19B,MAAM,KAAK;;QAUjC,SAAS29B,oBAAoBtmC;YACzB,IAAIimC,SAASjnC,GAAGsS,UAAU,2CAA2CtR,OAAO;YAE5EimC,OAAO5yB,aAAa,MAAMrT;YAE1BimC,OAAOjiC,MAAMC,UAAU;YACvBiI,SAASq6B,KAAKjzB,YAAY2yB;YAE1B,OAAOA;;QAUX,SAASO,4BAA4BP,QAAQt0B;YACzC,IAAI00B,aAAaJ,OAAOzpB,IACpBkG,SAAS0jB,uBAAuBC,aAChC1pB,OAAOgI,QAAQjC;YAEnBijB,gBAAgBhpB,QAAQhL;YAIxBi0B,iBAAiBljB,UAAU1jB,GAAGinC,QAAQ/hC,OAAO,QAAQ;gBACjD,IAAI4rB,QAAQtU,SAASkH,SAAS;oBAC1BthB,IAAI,qEAAqEilC,aAAa;oBAEtFR,0BAA0BQ,cAAczb,WAAW;wBAC/C,IAAIqK,eAAe,kEAAkEoR;wBACrFjlC,IAAI6zB,cAAc;wBAClBtjB;4BACIxQ,OAAO8zB;;uBAEZ;;;YAMX8Q,oBAAoBV,eAAegB,YAAY,SAAShlC;gBACpDD,IAAI,6CAA6CC,UAAU;gBAC3D,IAAIqhB,SAAS0jB,uBAAuBC,aAChC5T,WAAW3C,QAAQ2W,mBAAmBplC,UACtCsb,OAAO8V,SAAS9V,MAChB+pB;gBAEJ,IAAI/pB,QAAQgpB,gBAAgBhpB,OAAO;oBAC/Bvb,IAAI,uCAAuCilC;oBAC3CzS,aAAaiS,0BAA0BQ;2BAChCR,0BAA0BQ;oBAEjCvW,QAAQ6W,iBAAiBN;oBAEzBK,iBAAiBf,gBAAgBhpB;2BAE1BgpB,gBAAgBhpB;oBACvBopB,oBAAoBR,sBAAsBc;oBAC1CK,eAAejU;uBAEd,KAAK9V,MAAM;oBACZvb,IAAI,MAAMC,UAAU;;;;QAKhCrC,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGggC,cAAc5hB;QAErCpe,GAAG2P,SAAS1N,MAAM,SAAS6N;YACvB;gBAII4D,KAAK,SAAS8J,IAAIoS;oBACd9f,OAAO4D,IAAI8J;wBAAKvQ,OAAO2iB;;oBAEvBA,UAAUvb,aAAa,QAAQoY;oBAG/B,IAAImD,UAAU/pB,YAAY;wBACtB7F,GAAG4vB,WAAW9pB;;;gBAItBgvB,SAAS,SAAStX;oBACdwpB,YAAYxpB;oBACZ1N,OAAOglB,QAAQtX;;gBAGnBgG,SAAS,SAAShG;oBACd,OAAO1N,OAAO0T,QAAQhG,OAClBsT,QAAQwP,cAAc9iB,IAAIvQ,UAAU3M;;;;QAKpDN,GAAGuG,OAAOtE;YACNua,UAAU,SAASgB;gBACf,OAAOsT,QAAQwP,cAAc9iB,IAAIvQ;;YAWrC26B,kBAAkB,SAASX,QAAQt0B;gBAE/B,IAAIk1B;gBAEJ,IAAIf,QAAQ;oBACRU,4BAA4BP,QAAQt0B;uBAEnC;oBACDi0B,iBAAiBK,OAAOzpB,MAAMxd,GAAGinC,QAAQ/hC,OAAO,QAAQ;wBACpD9C,IAAI,2BAA2B6kC,OAAOzpB;wBAKtC,KAAKypB,OAAOphC,YAAY;4BACpB;;wBAGJ;4BAEI,IAAIohC,OAAOa,mBACPb,OAAOa,gBAAgBP,QACvBN,OAAOa,gBAAgBP,KAAK90B,aAAa,SAAS;gCAKlD;;0BAGR,OAAOtQ;4BAEHC,IAAI,gFAAgFD,MAAME,UAAU,KAAK;4BACzGwlC;gCAAsBx4B,SAAS;;;wBAGnCsD,SAASk1B;;;;YAWrBE,eAAe,SAASvqB;gBACpB,IAAI6pB,aAAavW,QAAQqW,eAAe3pB;gBAExC,OAAO8pB,oBAAoBD;;YAQ/BM,kBAAkB,SAASnqB;gBACvB,IAAIopB,iBAAiBppB,QAAQld,WAAW;oBACpCsmC,iBAAiBppB;2BACVopB,iBAAiBppB;;;YAQhC2pB,gBAAgB,SAASzjB;gBACrB,OAAOA,SAAS,MAAMgjB;;YAY1BsB,oBAAoB,SAAS5pB;gBACzB,IAAI+K,SAAS/K,KAAK+K,QACdtI,WAAWzC,KAAKyC,UAChBrhB,SAAS4e,KAAK5e,QACdg5B,eAAepa,KAAKoa,cACpByP,aAAa7pB,KAAK6pB,YAClB7zB,OAAOpU,GAAGsS,UAAU,mBAAmB6W,SAAS,4CAChDwU,MAAM9c;gBAEV,IAAI2X,cAAc;oBACdx4B,GAAGmU,WAAW3U,QAAQ4U;uBAErB;oBACDupB,MAAM39B,GAAGoT,QAAQ5T,QAAQqhB;;gBAG7BzM,KAAKC,aAAa,UAAUspB;gBAC5BvpB,KAAKC,aAAa,UAAU4zB;gBAC5B7zB,KAAKpP,MAAMC,UAAU;gBACrBiI,SAASq6B,KAAKjzB,YAAYF;gBAE1B,OAAOA;;YAOXqzB,oBAAoB,SAASS;gBACzB,IAAIzU;gBAEJ;oBACIA,WAAWzzB,GAAGuU,UAAU2zB;kBAE5B,OAAO/lC;oBACHC,IAAI,4DAA4DD,MAAME,UAAU,KAAK;;gBAGzF,OAAOoxB;;;;ICnSnBzzB,GAAGmoC,mBAAmB,SAAS/pB;QAC3B;QAEA,IAAI0S,UAAU7uB,MACVtC,YAAYye,KAAKnf,QAAQU,WACzBsgC,QAAQ7hB,KAAK6hB,OACbznB,WAAW4F,KAAKnf,QAAQuZ,UACxBc,SAAS8E,KAAKnf,QAAQqa,QACtB8uB,aAAa5vB,YAAY4F,KAAKnf,QAAQuZ,SAASyK,WAAWjjB,GAAGgW,kBAAkBwC,UAC/E6vB,gBAAgB/uB,UAAU8E,KAAKnf,QAAQqa,OAAO2J,WAAWmlB,cAAcpoC,GAAGgW,kBAAkBsD,QAC5F4J,UAAU+c,MAAM/c,SAChBkC,UAAU6a,MAAM7a,SAChBO,UAAUsa,MAAMta,SAChBf,cAAcqb,MAAMrb,aACpB8J,gBAAgBuR,MAAMvR,eACtBH,gBAAgB0R,MAAM1R,eACtBrB,aAAa+S,MAAM/S,YACnB9qB,MAAM69B,MAAM79B;QAEhB,SAASkgC,MAAM9kB;YACXxd,GAAGY,KAAKkwB,QAAQqR,SAAS3kB,KAAK,SAAS8qB,OAAO9wB;gBAC1C,IAAI+wB,gBAAgBzX,QAAQ0X,kBAAkBhrB,IAAI8qB;gBAElD9wB,IAAIwmB,qBAAqB;gBACzBxmB,IAAIjK,OAAOuvB,aAAa;gBACxBtlB,IAAI8qB;gBACJiG,iBAAiBA,cAAcxI,YAAYwI,cAAcxI,SAASviB;;;QAI1Exd,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGggC,cAAc5hB;QAErCpe,GAAG2P,SAAS1N,MAAM,SAAS6N;YACvB;gBAII4D,KAAK,SAAS8J,IAAIirB;oBACd,IAAIzoC,GAAG+L,OAAO08B,gBAAgBzoC,GAAG8M,OAAO27B,cAAc;wBAClD34B,OAAO4D,IAAI8J;4BAAK4E,MAAMqmB;;2BAErB,IAAIA,uBAAuBzoC,GAAG2a,WAAW;wBAC1C7K,OAAO4D,IAAI8J;4BAAKyiB,OAAOwI;;2BAEtB;wBACD,MAAM,IAAIviC,MAAM;;oBAGpB4qB,QAAQ4X,eAAelrB;oBACvB6qB,iBAAiBvX,QAAQ6X,uBAAuBnrB;;gBAGpDsX,SAAS,SAAStX;oBACd8kB,MAAM9kB;oBACNsT,QAAQ0Q,+BAA+BhkB;oBACvCsT,QAAQ8T,WAAWpnB;oBACnB1N,OAAOglB,QAAQtX;;;;QAK3Bxd,GAAGuG,OAAOtE;YAEN0/B,kBAAkB,SAASnkB,IAAIujB;uBACpBjQ,QAAQwP,cAAc9iB,IAAIlK,KAAKs1B,aAAa7H;;YAGvDuC,UAAU,SAAS9lB,IAAIujB;gBACnB,IAAI8H,YAAY/X,QAAQwP,cAAc9iB,IAAIlK;gBAE1C,IAAIu1B,UAAUC,MAAM;2BACTD,UAAUC,KAAK/H;;gBAE1B,IAAI8H,UAAUE,gBAAgB;2BACnBF,UAAUE,eAAehI;;;YAMxCM,gBAAgB,SAAS7jB,IAAIwrB;gBACzB,IAAIC,eAAenY,QAAQgS,gBAAgBtlB,MAAM,GAC7ChG,MAAMsZ,QAAQoY,QAAQ1rB,IAAIyrB;gBAE9B,IAAID,gBAAgB;oBAChB,OAAO,IAAIhpC,GAAGmP,UAAUE,QAAQ25B,eAAexxB,MAAMA;;gBAGzD,OAAO,IAAIxX,GAAGmP,UAAUE,YAAYmI;;YAGxC4M,SAAS,SAAS5G;gBACd,OAAOsT,QAAQtN,QAAQhG,OAAOsT,QAAQwP,cAAc9iB,IAAI4E;;YAG5DyiB,UAAU,SAASrnB;gBACf,OAAOsT,QAAQtN,QAAQhG,OAAOsT,QAAQwP,cAAc9iB,IAAIyiB;;YAO5D9a,uBAAuB;gBACnB,IAAIgkB;gBAEJrY,QAAQsY,sBAAsB,SAASjpC,KAAK4iB;oBACxC+N,QAAQ0R,0BAA0B,MAAMzf,WAAWvK,SAASspB,YAAa/e,WAAWvK,SAASupB;oBAE7F,IAAI1hC;wBACAW,MAAM+hB,WAAW/hB;wBACjB+gC,WAAWhf,WAAWvK,SAASupB;wBAC/BxjB,MAAMwE,WAAWxE;wBACjBZ,MAAMoF,WAAWpF;;oBAGrB,IAAIoF,WAAW5iB,KAAK;wBAChBE,KAAKF,MAAM4iB,WAAW5iB;;oBAG1BgpC,mBAAmBrnC,KAAKzB;;gBAG5B,OAAO8oC;;YAGXjD,aAAa,SAAS1oB;gBAClB,SAAShF,YAAYsY,QAAQtN,QAAQhG,QAAQsT,QAAQwP,cAAc9iB,IAAI6rB;;YAG3E7G,2BAA2B,SAAShlB,IAAI8rB,eAAeC;gBACnD,IAAIzH,aAAawH,iBAAiBxY,QAAQwP,cAAc9iB,IAAIhF,SAASspB,YACjEC,YAAYwH,gBAAgBzY,QAAQwP,cAAc9iB,IAAIhF,SAASupB;gBAEnE,IAAID,YAAY;oBACZ1/B,IAAIpC,GAAGyL,OAAO,0DAA0DgJ,KAAK6pB,UAAUwD;oBACvFA,WAAW0H;oBACXxpC,GAAGY,KAAKkhC,YAAY,SAASlgC,KAAKm/B;wBAC9BgB,UAAUC,QAAQjB;;oBAEtBe,WAAW19B,SAAS;;;YAI5BgV,OAAO,SAASoE;gBACZ,IAAIsT,QAAQtN,QAAQhG,KAAK;oBACrBpb,IAAIpC,GAAGyL,OAAO,6DAA6D+R,IAAI0F,QAAQ1F;oBACvFsT,QAAQwP,cAAc9iB,IAAIisB,SAAS;oBACnCnH,MAAM9kB;oBACN,OAAO;;;YAIfulB,oBAAoB,SAASvlB;gBACzB,IAAIhF,YAAYsY,QAAQtN,QAAQhG,KAAK;oBACjC,IAAIjD,QAAQuW,QAAQwP,cAAc9iB,KAC9BksB,aACA91B;2BAEG2G,MAAM/B;oBAEb+B,MAAM/B;oBACNkxB,cAAc5Y,QAAQgS,gBAAgBtlB;oBACtC,IAAIksB,cAAc,KAAKlxB,SAASqhB,WAAW;wBACvCtf,MAAM/B,SAASyK,UAAU;wBACzB1I,MAAM/B,SAASmxB,QAAQD;wBACvBnvB,MAAM/B,SAASupB;wBAEf,KAAKnuB,IAAI,GAAGA,IAAI81B,aAAa91B,KAAK;4BAC9B2G,MAAM/B,SAASupB,UAAUjgC,KAAK8R;;wBAGlCkd,QAAQ4X,eAAelrB;2BAEtB;wBACDjD,MAAM/B,SAASyK,UAAU;;;;YAKrCqiB,YAAY,SAAS9nB,IAAIosB;gBACrB,IAAI9Y,QAAQtN,QAAQhG,KAAK;oBACrBsT,QAAQwP,cAAc9iB,IAAI4E,OAAOwnB;;;YAIzChF,YAAY,SAASpnB;gBACjB,IAAIqrB,YAAY/X,QAAQwP,cAAc9iB,IAAIlK;gBAE1CtT,GAAGY,KAAKioC,UAAUE,gBAAgB,SAASc;2BAChChB,UAAUE,eAAec;;gBAGpC7pC,GAAGY,KAAKioC,UAAUC,MAAM,SAASe;2BACtBhB,UAAUC,KAAKe;;;YAW9BC,YAAY,SAAStsB,IAAIusB;gBACrB,OAAOjZ,QAAQkZ,aAAaxsB,IAAIusB,aAAa/pC,GAAGsN;;YAGpDk7B,mBAAmB,SAAShrB,IAAIusB;gBAC5B,IAAIhJ,WAAWgJ,eAAe,QAAQ,IAAIA;gBAC1C,OAAOjZ,QAAQwP,cAAc9iB,IAAIlK,KAAKy1B,eAAehI;;YAGzDC,eAAe,SAASxjB,IAAIysB;gBACxB,IAAIhQ,YAAYzhB,SAAS4hB,UACrB8P,WAAW9kB,QAAQ5H,KACnBrP,aAAa2iB,QAAQ1M,QAAQ5G,KAC7B2sB,aAAalQ,YAAYgQ,YACzBG,WAAWD,aAAalQ,aAAaiQ,WAAWA,WAAWC,aAAalQ,WACxEyP,cAAc5Y,QAAQgS,gBAAgBtlB,KACtCorB,eAAe3mC,KAAKq+B,cAAc9iB,IAAIlK,KAAKs1B,cAI3C/5B,OAAO+5B,aAAaqB,eAAejqC,GAAGkO,UAAUC,YAAYg8B,YAAYC;gBAE5ExB,aAAaqB,cAAcp7B;gBAE3B;oBACIw7B,MAAMJ;oBACN77B,OAAO+7B;oBACP97B,KAAK+7B;oBACLE,OAAOZ;oBACP76B,MAAMA;oBACN0P,MAAM6rB,WAAWD;;;YAIzBhJ,0BAA0B,SAASnT;gBAC/B;oBACI+L,WAAW/L,UAAUqc;oBACrBE,WAAWvc,UAAU5f,QAAQ;oBAC7Bo8B,SAASxc,UAAU3f;oBACnB8rB,YAAYnM,UAAUsc;;;YAQ9BG,oBAAoB,SAASjtB;gBACzB,IAAIktB,gBAAgB,OAChB1pC,OAAOkiB,QAAQ1F,KACfe,OAAO6G,QAAQ5H,KACfyc,YAAYzhB,SAAS4hB,UACrBvZ,WAAW+D,YAAYpH;gBAE3B,OAAOxd,GAAGyL,OAAO,4BAA4B9L,WAAW+qC,eAAe1pC,MAAMud,MAAM0b,WAAWpZ;;YAGlG8pB,cAAc,SAASntB;gBACnB,OAAOsT,QAAQ1M,QAAQ5G,IAAIra;;YAG/BynC,qBAAqB,SAASptB;gBAC1B,OAAOsT,QAAQwP,cAAc9iB,IAAIhF;;YAOrCsqB,iBAAiB,SAAStlB;gBACtB,IAAIhF,UAAU;oBACV,IAAI0xB,WAAW9kB,QAAQ5H,KACnByc,YAAYzhB,SAAS4hB;oBAEzB,OAAO/zB,KAAKwkC,KAAKX,WAAWjQ;;;YAIpCiP,SAAS,SAAS1rB,IAAIusB;gBAClB,IAAIhJ,WAAWgJ,eAAe,QAAQ,IAAIA;gBAC1C,OAAOjZ,QAAQwP,cAAc9iB,IAAIlK,KAAKw1B,KAAK/H;;YAG/CoB,UAAU,SAAS3kB;gBACf,OAAOsT,QAAQwP,cAAc9iB,IAAIlK,KAAKw1B;;YAK1CM,uBAAuB,SAASz2B;gBAC5B,IAAI01B,eAAe;oBACfroC,GAAGY,KAAKoX,cAAc,SAAS7X,KAAK8K;wBAChC,IAAI9K,IAAIyJ,QAAQ5J,GAAGyL,OAAO,cAAc9L,gBAAgB,GAAG;4BACvD,IAAIojB,aAAatO,KAAKC,MAAMzJ;4BAC5B0H,SAASxS,KAAK4iB;;;;;YAM9B2lB,gBAAgB,SAASlrB;gBACrBsT,QAAQwP,cAAc9iB,IAAIlK;oBACtBy1B;oBACA7H;oBACA4H;oBACAF;;;YAIRkC,mBAAmB,SAASttB;gBACxBsT,QAAQwP,cAAc9iB,IAAI6rB,eAAe;;YAK7C7H,gCAAgC,SAAShkB;gBACrC,IAAIutB;gBAEJ,IAAI1C,iBAAiBvX,QAAQoV,YAAY1oB,KAAK;oBAC1CutB,iBAAiBja,QAAQ2Z,mBAAmBjtB;oBAE5C,IAAIutB,kBAAkB/yB,aAAalF,QAAQi4B,iBAAiB;wBACxD/yB,aAAagzB,WAAWD;wBACxB,OAAO;;;gBAIf,OAAO;;YAKXpC,wBAAwB,SAASnrB;gBAC7B,IAAIjD,QAAQuW,QAAQwP,cAAc9iB,KAC9ButB,gBAAgBE;gBAIpB,IAAI5C,iBAAiB9tB,MAAMpa,QAAQG,WAAW;oBAC1CyqC,iBAAiBja,QAAQ2Z,mBAAmBjtB;oBAC5CytB,gBAAgBjzB,aAAalF,QAAQi4B;oBAGrC,IAAIE,eAAe;wBACfA,gBAAgBx2B,KAAKC,MAAMu2B;wBAI3B,IAAIvc,cAAcuc,cAActtB,OAAO;4BACnCmT,QAAQga,kBAAkBttB;+BAEzB;4BACDpb,IAAIpC,GAAGyL,OAAO,2DAA2D+R,IAAI0F,QAAQ1F;4BAErF+Q,cAAc/Q,IAAIytB,cAActtB;4BAEhCpD,MAAMpa,MAAM8qC,cAAc9qC;4BAC1Boa,MAAM/B,WAAWyyB,cAAczyB;4BAC/B+B,MAAM4S,SAAS8d,cAAc9d;4BAC7B5S,MAAM0mB,mBAAmB;4BAEzBnQ,QAAQ0R,0BAA0BhlB;;;;;YAOlD6lB,2BAA2B,SAAS7lB;gBAChC,IAAIjD,QAAQuW,QAAQwP,cAAc9iB,KAC9ButB,gBAAgBE;gBAGpB,IAAI5C,iBAAiBvX,QAAQoV,YAAY1oB,KAAK;oBAC1CutB,iBAAiBja,QAAQ2Z,mBAAmBjtB;oBAE5CytB;wBACIjqC,MAAMkiB,QAAQ1F;wBACde,MAAM6G,QAAQ5H;wBACdG,MAAMgI,QAAQnI;wBACdrd,KAAKoa,MAAMpa;wBACXqY,UAAU+B,MAAM/B;wBAChB2U,QAAQ5S,MAAM4S;wBACd+d,aAAarL,KAAK+F;;oBAGtB;wBACI5tB,aAAaC,QAAQ8yB,gBAAgBt2B,KAAK6pB,UAAU2M;sBAExD,OAAO9oC;wBACHC,IAAIpC,GAAGyL,OAAO,2DAA2D+R,IAAIrb,MAAMqI,aAAa;;;;YAK5G2gC,0BAA0B,SAAS3tB,IAAIujB,UAAU9G;gBAC7C,IAAIziB,MAAMsZ,QAAQoY,QAAQ1rB,IAAIujB,WAC1B//B,OAAOkiB,QAAQ1F,KACf4tB;oBACI3G,QAAQ,SAAStX,QAAQC;wBACrB,IAAI8c,WAAW9kB,QAAQ5H;wBAEvB,IAAI2P,WAAWC,OAAO;4BAClBF,WAAW1P,IAAIxc,MAAMkpC,UAAUA;+BAE9B;4BACDhd,WAAW1P,IAAIxc,MAAOmsB,UAAU+c,WAAWA,WAAW,IAAI/c,QAAS+c;;;oBAI3EpJ,SAAS,SAAS3T,QAAQC;wBACtB,IAAI8T,gBAAgBpQ,QAAQwP,cAAc9iB,IAAIlK,KAAK4tB,eAC/CmK,iCAAiCva,QAAQwP,cAAc9iB,IAAI2P,QAC3Dme,mBAAmBne,QACnBoe,kBAAkBne,OAClB8M,gBAAgB9U,QAAQ5H,KACxBguB,uBAAuBF,oBAAoBC,kBAAkBtR,YAC7DwR,qBAAqBJ;wBAEzBnK,cAAcH,YAAYyK;wBAE1BxrC,GAAGY,KAAKsgC,eAAe,SAASH,UAAU2K;4BACtCD,sBAAsBC;;wBAG1Bxe,WAAW1P,IAAIxc,MAAMyqC,oBAAoBvR;;;gBAIrD1iB,IAAIjK,OAAOuvB,aAAa,SAAS1qB;oBAC7B,IAAIA,EAAEqsB,kBAAkB;wBAEpB,IAAIt7B,OAAO82B,aAAa,OAAO,WAAW;wBAC1CmR,mBAAmBjoC,MAAMiP,EAAE+a,QAAQ/a,EAAEgb;;;;YAcjD4c,cAAc,SAASxsB,IAAIusB,aAAavyB,KAAKm0B;gBACzC,IAAIC,SAAS7B,eAAe,QAAQ,IAAIA,aACpClB,YAAY/X,QAAQwP,cAAc9iB,IAAIlK;gBAE1Cu1B,UAAUC,OAAOD,UAAUC;gBAC3BD,UAAUE,iBAAiBF,UAAUE;gBAErCF,UAAUC,KAAK8C,UAAUp0B;gBAEzB,IAAIm0B,kBAAkB;oBAClB9C,UAAUE,eAAe6C,UAAUD;;gBAGvC,OAAOn0B;;YAIX0tB,+BAA+B;gBAC3B,IAAI2G,iBAAiBvyB,OAAO+gB;gBAE5BvJ,QAAQsY,sBAAsB,SAASjpC,KAAK4iB;oBACxC,IAAI+oB,iBAAiB,IAAIjM,KAAK9c,WAAWmoB;oBAGzCY,eAAeC,QAAQD,eAAeE,YAAYH;oBAElD,IAAIC,eAAehM,aAAaD,KAAK+F,OAAO;wBACxCxjC,IAAI,6CAA6CjC;wBACjD6X,aAAagzB,WAAW7qC;;;;YAWpC2lC,sBAAsB,SAAStoB;gBAC3B,IAAIjD,QAAQuW,QAAQwP,cAAc9iB;gBAElC,KAAKjD,MAAM/B,UAAU;oBACjBsY,QAAQiS,mBAAmBvlB;;gBAG/B,OAAOjD,MAAM/B,SAASyK;;;;ICxflCjjB,GAAGkpB,0BAA0B,SAASlO;QAClC;QAEA,IAAIixB,WACAhtC;YACIkqB,QAAQ;YACRE,eAAe;YACfK;YACAN,gBAAgB;YAChBI,eAAe,SAAShM;gBAAK;;YAC7BiM;YACAE;gBACIoI,UAAU;gBACVyI,iBAAiB;;YAErBp4B,KAAK,SAASsJ,KAAKvB;YACnByf,UAAU,SAASpM;YACnBsM,kBAAkB,SAAStM,IAAIuM,UAAUC;;QAGjDhqB,GAAGuG,OAAOtH,SAAS+b;QAEnB,SAASkxB;YACL,IAAIjtC,QAAQkqB,OAAOtpB,kBAAkB,QAAQ;gBACzC;oBACIssC,SAAS;;;YAIjB;;QAGJF,YAAYjsC,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7B;YAC/BI,cAAc;YACdC,gBAAe,QAAQ;YACvBzS,QAAQlqB,QAAQkqB;YAChBO,eAAezqB,QAAQyqB;YACvBD,aAAaxqB,QAAQwqB;YACrBqS,gBAAgBoQ;YAChB9iB,gBAAgBnqB,QAAQmqB;YACxBI,eAAe,SAAShM;gBACpB,OAAOve,QAAQuqB,cAAc1E,IAAItH;;YAErCpb,KAAKnD,QAAQmD;YACbk6B,QAAQr9B,QAAQ2qB;YAChB0D,YAAYruB,QAAQ6qB;YACpBH,MAAM1qB,QAAQ0qB;;QAGlB3pB,GAAGuG,OAAOtE;YACN0zB,YAAY,SAASnY,IAAIG,MAAM4X;gBAC3B,IAAIzI,oBAAoByI;gBAExBt2B,QAAQmD,IAAI,wCAAwCob;gBAEpD,IAAIve,QAAQkqB,WAAW,UAAU;oBAC7B8iB,UAAUjN,cAAcxhB,IACnB2hB,SAASxhB,MACT0hB,WAAWvS,mBACXuR;uBAEJ;oBACDvR,kBAAkB7tB,QAAQoqB,iBAAiB1L;oBAC3CsuB,UAAUjN,cAAcxhB,IACnB6hB,WAAWvS,mBACXuR;;;;;KCpDrB;QAMI,SAAS+N,kBAAkBC;YACvB,IAAIC,KAAKD,IAAIE,cACTC,KAAKH,IAAII,eACTlkC,SAAS2E,SAASC,cAAc,WAChCu/B;YAEJ,IAAIJ,KAAKE,KAAK,OAAO,MAAM;gBACvBjkC,OAAOokC,QAAQpkC,OAAO8T,SAAS;gBAC/BqwB,MAAMnkC,OAAOqkC,WAAW;gBACxBF,IAAIG,UAAUR,MAAMC,KAAK,GAAG;gBAI5B,OAAOI,IAAII,aAAa,GAAG,GAAG,GAAG,GAAGzsC,KAAK,OAAO;mBAC7C;gBACH,OAAO;;;QAQf,SAAS0sC,qBAAqBV,KAAKC,IAAIE;YACnC,IAAIjkC,SAAS2E,SAASC,cAAc,WAChC6/B,KAAK,GACLC,KAAKT,IACLU,KAAKV,IACLE,KAAKrsC,MAAM8sC,OAAOC;YAEtB7kC,OAAOokC,QAAQ;YACfpkC,OAAO8T,SAASmwB;YAChBE,MAAMnkC,OAAOqkC,WAAW;YACxBF,IAAIG,UAAUR,KAAK,GAAG;YACtBhsC,OAAOqsC,IAAII,aAAa,GAAG,GAAG,GAAGN,IAAInsC;YAGrC,OAAO6sC,KAAKF,IAAI;gBACZG,QAAQ9sC,MAAM6sC,KAAK,KAAK,IAAI;gBAC5B,IAAIC,UAAU,GAAG;oBACbF,KAAKC;uBACF;oBACHF,KAAKE;;gBAETA,KAAMD,KAAKD,MAAO;;YAGtBI,QAASF,KAAKV;YACd,OAAQY,UAAU,IAAK,IAAIA;;QAM/B,SAASC,qBAAqBhB,KAAKx9B,MAAM5P,SAASquC;YAC9C,IAAI/kC,SAAS2E,SAASC,cAAc,WAChC3E,OAAOvJ,QAAQuJ,QAAQ,cACvB0G,UAAU,IAAIlP,GAAGmP;YAErBo+B,oBAAoBlB,KAAKx9B,MAAMtG,QAAQtJ,SAASquC,UAC3CrzB,KAAK;gBACF/K,QAAQG,QACJ9G,OAAOI,UAAUH,MAAMvJ,QAAQwJ,WAAW;;YAItD,OAAOyG;;QAGX,SAASs+B,oCAAoCpvB;YACzC,IAAIqvB,YAAY;YAEhB,KAAKztC,GAAG4R,OAAO;gBACX,MAAM,IAAI5R,GAAGkG,MAAM;;YAGvB,IAAIkY,KAAKsvB,aAAatvB,KAAKuvB,YAAYF,WAAW;gBAC9C;oBACIG,WAAWvnC,KAAKC,MAAMD,KAAKwnC,KAAKJ,aAAarvB,KAAKsvB,aAAatvB,KAAKuvB;oBACpEG,UAAUznC,KAAKC,MAAMD,KAAKwnC,KAAKJ,aAAarvB,KAAKuvB,YAAYvvB,KAAKsvB;;;;QAQ9E,SAASH,oBAAoBlB,KAAKx9B,MAAMtG,QAAQtJ,SAASquC;YACrD,IAAIhB,KAAKD,IAAIE,cACTC,KAAKH,IAAII,eACTE,QAAQ1tC,QAAQ0tC,OAChBtwB,SAASpd,QAAQod,QACjBqwB,MAAMnkC,OAAOqkC,WAAW,OACxB19B,UAAU,IAAIlP,GAAGmP,WACjB4+B;YAEJrB,IAAIsB;YAEJ,IAAI/uC,QAAQgvC,QAAQ;gBAChB,OAAOC;oBACHr/B,MAAMA;oBACNtG,QAAQA;oBACRqvB,OAAOyU;oBACP8B,aAAa3B;oBACb4B,YAAY9B;oBACZ+B,aAAapvC,QAAQovC;oBACrBJ,QAAQhvC,QAAQgvC;oBAChBK,cAAcjyB;oBACdkyB,aAAa5B;;;YAIrB,KAAK3sC,GAAGgW,kBAAkByD,0BAA0B;gBAChDs0B,qBAAqBP;oBACjBG,WAAWhB;oBACXe,YAAYrxB;;gBAGhB,IAAI0xB,oBAAoB;oBACpB/tC,GAAGoC,IAAIpC,GAAGyL,OAAO,kFACbkhC,OAAOtwB,QAAQ0xB,mBAAmBD,UAAUC,mBAAmBH,YAC/D;oBAEJjB,QAAQoB,mBAAmBD;oBAC3BzxB,SAAS0xB,mBAAmBH;;;YAIpCY,oBAAoBjmC,QAAQokC,OAAOtwB,QAAQpd,QAAQovC;YAInD,IAAIruC,GAAG4R,OAAO;iBACT;oBACG,IAAIw6B,kBAAkBC,MAAM;wBACxBC,MAAM;wBACNE,MAAM;;oBAGV,IAAIiC,IAAI,MACJC,YAAYxhC,SAASC,cAAc,WACnCwhC,kBAAkBrB,WAAWP,qBAAqBV,KAAKC,IAAIE,MAAM,GACjEoC,KAAKvoC,KAAKwkC,KAAK4D,IAAI9B,QAAQL,KAC3BuC,KAAKxoC,KAAKwkC,KAAK4D,IAAIpyB,SAASmwB,KAAKmC,kBACjC3B,KAAK,GACL8B,KAAK,GACLC,QAAQC,IAAIC;oBAEhBP,UAAU/B,QAAQ+B,UAAUryB,SAASoyB;oBACrCM,SAASL,UAAU9B,WAAW;oBAE9B,OAAOI,KAAKR,IAAI;wBACZwC,KAAK;wBACLC,KAAK;wBACL,OAAOD,KAAK1C,IAAI;4BACZyC,OAAOG,UAAU,GAAG,GAAGT,GAAGA;4BAC1BM,OAAOlC,UAAUR,MAAM2C,KAAKhC;4BAC5BN,IAAIG,UAAU6B,WAAW,GAAG,GAAGD,GAAGA,GAAGQ,IAAIH,IAAIF,IAAIC;4BACjDG,MAAMP;4BACNQ,MAAML;;wBAEV5B,MAAMyB;wBACNK,MAAMD;;oBAEVnC,IAAIyC;oBACJT,YAAYK,SAAS;;mBAGxB;gBACDrC,IAAIG,UAAUR,KAAK,GAAG,GAAGM,OAAOtwB;;YAGpC9T,OAAO6mC,mBAAmB7mC,OAAO6mC;YACjClgC,QAAQG;YAER,OAAOH;;QAGX,SAASg/B,qCAAqCmB;YAC1C,IAAIxgC,OAAOwgC,WAAWxgC,MAClB+oB,QAAQyX,WAAWzX,OACnBuW,cAAckB,WAAWlB,aACzBC,aAAaiB,WAAWjB,YACxBC,cAAcgB,WAAWhB,aACzBn/B,UAAU,IAAIlP,GAAGmP,WACjB8+B,SAASoB,WAAWpB,QACpBqB,eAAepiC,SAASC,cAAc,WACtCoiC,sBAAsBD,aAAa1C,WAAW,OAC9C4C,eAAeH,WAAW9mC,QAC1B+lC,eAAee,WAAWf,cAC1BC,cAAcc,WAAWd;YAE7BC,oBAAoBc,cAAclB,YAAYD,aAAaE;YAE3DmB,aAAanzB,SAASiyB;YACtBkB,aAAa7C,QAAQ4B;YAErBgB,oBAAoB1C,UAAUjV,OAAO,GAAG;YAExCqW;gBACIp/B,MAAMA;gBACNwN,QAAQiyB;gBACR1W,OAAOA;gBACP0X,cAAcA;gBACdE,cAAcA;gBACd7C,OAAO4B;eAENt0B,KACG,SAAS5K;gBACLmgC,aAAaJ,mBAAmBI,aAAaJ;gBAC7ClgC,QAAQG;eAEZH,QAAQK;YAGhB,OAAOL;;QAOX,SAASs/B,oBAAoBjmC,QAAQokC,OAAOtwB,QAAQgyB;YAChD,QAAQA;cACJ,KAAK;cACL,KAAK;cACL,KAAK;cACL,KAAK;gBACD9lC,OAAOokC,QAAQtwB;gBACf9T,OAAO8T,SAASswB;gBAChB;;cACJ;gBACIpkC,OAAOokC,QAAQA;gBACfpkC,OAAO8T,SAASA;;YAExB,IAAIqwB,MAAMnkC,OAAOqkC,WAAW;YAC5B,QAAQyB;cACJ,KAAK;gBAED3B,IAAI+C,UAAU9C,OAAO;gBACrBD,IAAIvoB,OAAO,GAAG;gBACd;;cACJ,KAAK;gBAEDuoB,IAAI+C,UAAU9C,OAAOtwB;gBACrBqwB,IAAIgD,OAAOrpC,KAAKspC;gBAChB;;cACJ,KAAK;gBAEDjD,IAAI+C,UAAU,GAAGpzB;gBACjBqwB,IAAIvoB,MAAM,IAAI;gBACd;;cACJ,KAAK;gBAEDuoB,IAAIgD,OAAO,KAAMrpC,KAAKspC;gBACtBjD,IAAIvoB,MAAM,IAAI;gBACd;;cACJ,KAAK;gBAEDuoB,IAAIgD,OAAO,KAAMrpC,KAAKspC;gBACtBjD,IAAI+C,UAAU,IAAIpzB;gBAClB;;cACJ,KAAK;gBAEDqwB,IAAIgD,OAAO,KAAMrpC,KAAKspC;gBACtBjD,IAAI+C,UAAU9C,QAAQtwB;gBACtBqwB,IAAIvoB,OAAO,GAAG;gBACd;;cACJ,KAAK;gBAEDuoB,IAAIgD,QAAQ,KAAMrpC,KAAKspC;gBACvBjD,IAAI+C,WAAW9C,OAAO;gBACtB;;cACJ;gBACI;;;QAOZ,SAASiD,aAAaC,UAAUC;YAC5B,IAAI/rC,OAAO9B;YAEX,IAAIgH,OAAOO,QAAQqmC,oBAAoBrmC,MAAM;iBACxC;oBACG,IAAI6iC,MAAM,IAAI0D,SACVC,MAAM/mC,OAAO+mC,OAAO/mC,OAAO+mC,IAAIC,kBAAkBhnC,OAAO+mC,MACpD/mC,OAAOinC,aAAajnC,OAAOinC,UAAUD,kBAAkBhnC,OAAOinC,YAAY;oBAClF,KAAKF,KAAK;wBAAE,MAAM9pC,MAAM;;oBACxBmmC,IAAI8D,MAAMH,IAAIC,gBAAgBJ;oBAC9B9rC,KAAK8K,OAAOghC;oBACZA,WAAWxD;;;YAGnB,KAAKwD,SAAStD,iBAAiBsD,SAASpD,eAAe;gBACnDoD,SAASzgC,SAAS;oBACd,IAAIghC,YAAYrsC,KAAKssC;oBACrB,IAAID,WAAW;wBACXrsC,KAAKssC,qBAAqB;wBAG1BzkB,WAAW;4BACP,KAAK,IAAIhY,IAAI,GAAGxD,MAAMggC,UAAUhsC,QAAQwP,IAAIxD,KAAKwD,KAAK;gCAClDw8B,UAAUx8B;;2BAEf;;;gBAGXi8B,SAASvgC,UAAUwgC;gBACnB7tC,KAAKouC;;YAETpuC,KAAK4tC,WAAWA;;QAMpBD,aAAatuC,UAAUgvC,SAAS,SAAS1gC,QAAQ3Q;YAC7CA,UAAUA;YAEV,IAAI8E,OAAO9B,MACPsuC,WAAWtuC,KAAK4tC,SAAStD,cACzBiE,YAAYvuC,KAAK4tC,SAASpD,eAC1BE,QAAQ1tC,QAAQ0tC,OAChBtwB,SAASpd,QAAQod,QACjBsc,WAAW15B,QAAQ05B,UACnBD,YAAYz5B,QAAQy5B,WACpB4U,YAAYrrC,KAAK4M,QAAQ5M,KAAK4M,KAAK1L,SAAS,cAC5C0J,UAAU+C,OAAO/C,QAAQ9M,eACzB0wC;YAEJ,IAAIxuC,KAAKouC,oBAAoB;gBACzBpuC,KAAKouC,mBAAmBvuC,KAAK;oBAAaiC,KAAKusC,OAAO1gC,QAAQ3Q;;gBAC9D;;YAGJ,IAAI0tC,UAAUtwB,QAAQ;gBAClBA,SAAUm0B,YAAY7D,QAAQ4D,YAAa;mBACxC,IAAIl0B,WAAWswB,OAAO;gBACzBA,QAAS4D,WAAWl0B,SAASm0B,aAAc;mBACxC;gBACH7D,QAAQ4D;gBACRl0B,SAASm0B;;YAEb,IAAI7X,YAAYgU,QAAQhU,UAAU;gBAC9BgU,QAAQhU;gBACRtc,SAAUm0B,YAAY7D,QAAQ4D,YAAa;;YAE/C,IAAI7X,aAAarc,SAASqc,WAAW;gBACjCrc,SAASqc;gBACTiU,QAAS4D,WAAWl0B,SAASm0B,aAAc;;YAG/CC;gBAAQ9D,OAAOA;gBAAOtwB,QAAQA;eAC9Brc,GAAGY,KAAK3B,SAAS,SAASyxC,YAAYC;gBAClCF,IAAIC,cAAcC;;YAGtB,IAAI9jC,YAAY,OAAO;iBAClB;oBACG,IAAI+jC,eAAehhC,OAAOugC;oBAC1B9C,qBAAqBtpC,KAAK8rC,UAAU9rC,KAAK8K,MAAM4hC,KAAKnD,UAC/CrzB,KAAK,SAASrR;wBACXgH,OAAOugC,MAAMvnC;wBACbgoC,iBAAiBhhC,OAAOugC,OAAOvgC,OAAOR;;;mBAG/C,IAAIvC,YAAY,UAAU;gBAC7B0gC,oBAAoBtrC,KAAK4tC,UAAU5tC,KAAK4M,MAAMe,QAAQ6gC,KAAKnD;;YAE/D,WAAWrrC,KAAK4uC,aAAa,YAAY;gBACrC5uC,KAAK4uC,SAASjhC;;;QAItB5P,GAAG4vC,eAAeA;;ICtYtB5vC,GAAGk7B,iBAAiB,SAAS94B;QACzB;QAEA,SAAS0uC,MAAM3sC;YACX,OAAOA,GAAG0I,QAAQ9M,kBAAkB;;QAGxC,SAASgxC,SAAS5sC;YACd,OAAOA,GAAG0I,QAAQ9M,kBAAkB;;QAGxC,SAASixC;YACL,OAAO,IAAIjB,QAAQkB,gBAAgB3wC;;QAGvC,SAAS4wC;YACL,IAAI3oC,SAAS2E,SAASC,cAAc;YAEpC,OAAO5E,OAAOqkC,cAAcrkC,OAAOqkC,WAAW;;QAMlD,SAASuE,wBAAwBC;YAE7B,IAAIC,eAAeD,aAAaznC,MAAM,MAClC3I,OAAOqwC,aAAaA,aAAajtC,SAAS,GAAGuF,MAAM,KAAK,IACxD0nB,YAAYrxB,GAAG4U,aAAa5T;YAEhCqwB,YAAYA,aAAaA,UAAUtxB;YAEnC,QAAQsxB;cACJ,KAAK;cACL,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;gBACD,OAAO;;cACX,KAAK;cACL,KAAK;gBACD,OAAO;;;QASnB,SAASigB,cAAc3T;YACnB,IAAI4T,eAAerkC,SAASC,cAAc,MACtCqkC,gBAAgBC,gBAAgBC;YAEpCH,aAAaI,OAAOhU;YAEpB6T,iBAAiBD,aAAaK;YAC9BF,aAAaH,aAAaM;YAC1BJ,iBAAiBF,aAAaO;YAE9B,IAAIN,eAAezxC,kBAAkBkJ,OAAO8oC,SAASH,SAAS7xC,eAAe;gBACzE,OAAO;;YAGX,IAAI0xC,eAAe1xC,kBAAkBkJ,OAAO8oC,SAASD,SAAS/xC,eAAe;gBACzE,OAAO;;YAIX,IAAI2xC,eAAezoC,OAAO8oC,SAASF,SAAS7xC,GAAG2Q,MAAM;gBACjD,OAAO;;YAGX,OAAO;;QAGX,SAASqhC,yBAAyB3F,KAAKn9B;YACnCm9B,IAAIj9B,SAAS;gBACTi9B,IAAIj9B,SAAS;gBACbi9B,IAAI/8B,UAAU;gBACdJ,QAAQG,QAAQg9B;;YAGpBA,IAAI/8B,UAAU;gBACV+8B,IAAIj9B,SAAS;gBACbi9B,IAAI/8B,UAAU;gBACdlN,IAAI,8BAA8B;gBAClC8M,QAAQK,QAAQ88B,KAAK;;;QAI7B,SAAS4F,gCAAgC1pC,QAAQ2G;YAO7C3G,OAAO6mC,kBAAkB;gBACrBlgC,QAAQG,QAAQ9G;;;QAQxB,SAAS2pC,kCAAkCvuB,aAAazU;YACpD,IAAIijC,aAAarB,MAAMntB,gBAAgBotB,SAASptB;YAEhD,IAAImtB,MAAMntB,cAAc;gBACpBquB,yBAAyBruB,aAAazU;mBAErC,IAAI6hC,SAASptB,cAAc;gBAC5BsuB,gCAAgCtuB,aAAazU;mBAE5C;gBACDA,QAAQK,QAAQoU;gBAChBvhB,IAAIpC,GAAGyL,OAAO,kDAAkDkY,YAAY9W,UAAU;;YAG1F,OAAOslC;;QAKX,SAASC,KAAKjkC,YAAYkW,WAAWplB;YACjC,IAAIozC,cAAc,IAAIryC,GAAGmP,WACrBub,aAAa,IAAI1qB,GAAGsyC,SAASnkC,YAAY/L,MACzCwhB,UAAU3kB,QAAQ2kB,SAElBgX,SAAS37B,QAAQ27B,UAAU,OAAO,OAAO37B,QAAQ27B,QACjD2X,sBAAsB;gBAClBluB,UAAU/U,UAAU;gBACpB+U,UAAUjV,SAAS;gBACnBhN,IAAI,oDAAoD;gBACxDiwC,YAAY9iC,QAAQ8U,WAAW;;YAGvCqG,WAAW8nB,gBAAgBv4B,KACvB,SAASzR;gBAGL,IAAIiqC;oBACI/9B,OAAO;wBACH,OAAO,IAAI1U,GAAGmP,UAAUE;;mBAGhCqjC,OAAO9X,SAAS,IAAI56B,GAAG2yC,KAAKxkC,YAAY/L,OAAOqwC,WAC/CG,QAAQ,IAAI5yC,GAAG4vC,aAAazhC,YAAYokC;gBAE5C,IAAIL,kCAAkC7tB,WAAWguB,cAAc;oBAC3DK,KAAKh+B,QAAQuF,KACT,SAASy4B;wBACL,IAAIrE,cAAcqE,QAAQA,KAAKG;wBAE/BD,MAAMtC,OAAOjsB;4BACTsU,UAAU/U;4BACV8U,WAAW9U;4BACXyqB,aAAaA;4BACb7lC,MAAMA;4BACNylC,QAAQhvC,QAAQ6kB;;uBAIxB,SAASgvB;wBACL1wC,IAAIpC,GAAGyL,OAAO,kEAAkEqnC;wBAEhFF,MAAMtC,OAAOjsB;4BACTsU,UAAU/U;4BACV8U,WAAW9U;4BACXpb,MAAMA;4BACNylC,QAAQhvC,QAAQ6kB;;;;eAOpC;gBACI1hB,IAAI;gBACJiwC,YAAY9iC,QAAQ8U,WAAW;;YAIvC,OAAOguB;;QAGX,SAASU,yBAAyBpV,KAAKqV,aAAaZ,MAAMxuB,SAASE;YAC/D,IAAImvB,UAAU,IAAIlD,SACdmD,gBAAgB,IAAIlzC,GAAGmP;YAE3B+iC,kCAAkCe,SAASC;YAE3C,IAAI5B,cAAc3T,MAAM;gBACpBsV,QAAQhC,cAAc;;YAG1BgC,QAAQ9C,MAAMxS;YAEduV,cAAcj5B,KACV,SAASk5B;gBACLjB,kCAAkCc,aAAaZ;gBAE/C,IAAIQ,QAAQ,IAAI5yC,GAAG4vC,aAAaqD;gBAChCL,MAAMtC,OAAO0C;oBACTra,UAAU/U;oBACV8U,WAAW9U;oBACXpb,MAAM2oC,wBAAwBxT;oBAC9BsQ,QAAQnqB;;eAIhBsuB,KAAK7iC;;QAIb,SAAS6jC,+BAA+BzV,KAAK0O,KAAK+F,MAAMxuB;YACpDsuB,kCAAkC7F,KAAK+F;YAKvCpyC,GAAGqsC,KAAKrmC;gBACJ2yB,UAAU/U,UAAU;gBACpB8U,WAAW9U,UAAU;;YAGzByoB,IAAI8D,MAAMxS;;QAWd,SAAS0V,YAAY1V,KAAKtZ,WAAWplB;YACjC,IAAImzC,OAAO,IAAIpyC,GAAGmP,WACdgV,QAAQllB,QAAQklB,OAChBP,UAAUO,QAAQllB,QAAQ2kB,UAAU;YAGxC,IAAIO,SAAS2sB,MAAMzsB,YAAY;gBAG3B,IAAI6sB,qBAAqB;oBAIrB,IAAII,cAAc3T,SAASqT,sBAAsB;wBAC7CoC,+BAA+BzV,KAAKtZ,WAAW+tB,MAAMxuB;2BAEpD;wBACDmvB,yBAAyBpV,KAAKtZ,WAAW+tB,MAAMxuB;;uBAGlD;oBACDwvB,+BAA+BzV,KAAKtZ,WAAW+tB,MAAMxuB;;mBAIxD,IAAImtB,SAAS1sB,YAAY;gBAC1B0uB,yBAAyBpV,KAAKtZ,WAAW+tB,MAAMxuB;mBAG9C,IAAIsuB,kCAAkC7tB,WAAW+tB,OAAO;gBACzD/tB,UAAU8rB,MAAMxS;;YAGpB,OAAOyU;;QAGXpyC,GAAGuG,OAAOtE;YAWNqiB,UAAU,SAASgvB,eAAejvB,WAAWplB;gBACzC,IAAIe,GAAGmL,SAASmoC,gBAAgB;oBAC5BlxC,IAAI;oBACJ,OAAOixC,YAAYC,eAAejvB,WAAWplB;uBAE5C;oBACDmD,IAAI;oBACJ,OAAOgwC,KAAKkB,eAAejvB,WAAWplB;;;;QAMlDgD,KAAKsxC;QACLtxC,KAAKsxC,SAASzC,QAAQA;QACtB7uC,KAAKsxC,SAASxC,WAAWA;QACzB9uC,KAAKsxC,SAASjC,gBAAgBA;QAC9BrvC,KAAKsxC,SAASpC,0BAA0BA;;IChT5CnxC,GAAG2yC,OAAO,SAASxkC,YAAY/L;QAC3B;QAGA,IAAIoxC,YAAW,OACXC;YACIC;gBACI1yC,MAAM;gBACNyN,OAAO;;;QAKnB,SAASklC,kBAAkBC;YACvB,IAAIxsC,SAAS,GACTysC,MAAM;YAEV,OAAOD,IAAIxvC,SAAS,GAAG;gBACnBgD,UAAUi9B,SAASuP,IAAIzyC,UAAU,GAAG,IAAI,MAAMkF,KAAKwtC,IAAI,GAAGA;gBAC1DD,MAAMA,IAAIzyC,UAAU,GAAGyyC,IAAIxvC;gBAC3ByvC,OAAO;;YAGX,OAAOzsC;;QAKX,SAAS0sC,WAAWC,QAAQ7kC;YACxB,IAAI8kC,YAAYD,QACZE,aAAa/kC;YACjB,IAAI8kC,cAAc1zC,WAAW;gBACzB0zC,YAAY;gBACZC,aAAa,IAAIj0C,GAAGmP;;YAGxBnP,GAAG4O,cAAcT,YAAY6lC,WAAW,GAAG/5B,KAAK,SAAS25B;gBACrD,IAAIxwC,QAAQ,cAAclC,KAAK0yC,MAC3BM;gBAEJ,IAAI9wC,OAAO;oBACP,IAAIA,MAAM,OAAO,KAAK;wBAClB8wC,gBAAgB7P,SAASuP,IAAI9zC,MAAM,GAAG,IAAI;wBAC1Cg0C,WAAWE,YAAYE,gBAAgB,GAAGD;2BAEzC;wBACDA,WAAW5kC,QAAQ2kC;;uBAGtB;oBACDC,WAAW1kC,QAAQ;;;YAI3B,OAAO0kC;;QAIX,SAASE;YACL,IAAIjlC,UAAU,IAAIlP,GAAGmP;YAErBnP,GAAG4O,cAAcT,YAAY,GAAG,GAAG8L,KAAK,SAAS25B;gBAC7C,IAAIA,IAAIhqC,QAAQ,YAAY,GAAG;oBAC3BsF,QAAQK,QAAQ;uBAEf;oBACDukC,aAAa75B,KAAK,SAAS85B;wBACvB7kC,QAAQG,QAAQ0kC;uBAEpB,SAAS5xC;wBACL+M,QAAQK,QAAQpN;;;;YAK5B,OAAO+M;;QAIX,SAASklC,eAAeC;YACpB,IAAInlC,UAAU,IAAIlP,GAAGmP;YAErBnP,GAAG4O,cAAcT,YAAYkmC,YAAY,IAAI,GAAGp6B,KAAK,SAAS25B;gBAC1D1kC,QAAQG,QAAQukC,QAAQ;;YAG5B,OAAO1kC;;QAIX,SAASolC,iBAAiBD,WAAWE;YACjC,IAAIrlC,UAAU,IAAIlP,GAAGmP;YAErBnP,GAAG4O,cAAcT,YAAYkmC,YAAY,IAAI,GAAGp6B,KAAK,SAAS25B;gBAC1D,IAAIW,cAAc;oBACd,OAAOrlC,QAAQG,QAAQskC,kBAAkBC;uBAExC;oBACD1kC,QAAQG,QAAQg1B,SAASuP,KAAK;;;YAItC,OAAO1kC;;QAIX,SAASslC,OAAOH,WAAWI;YACvB,IAAIV,SAASM,YAAY,IACrB5lC,QAAQgmC,aAAa;YAEzB,OAAOz0C,GAAG4O,cAAcT,YAAY4lC,QAAQtlC;;QAIhD,SAASimC,cAAcC;YACnB,IAAIp3B,cACAw2B,SAAS;YAEb,OAAOA,SAAS,MAAMY,OAAOvwC,QAAQ;gBACjCmZ,QAAQzb,KAAK6yC,OAAO70C,MAAMi0C,QAAQA,SAAS;gBAC3CA,UAAU;;YAGd,OAAOx2B;;QAIX,SAASq3B,aAAaL,cAAcE;YAChC,IAAII,iBAAiB,IACjBC,aAAa90C,GAAGuG,WAAWitC,UAC3BuB;YAEJ/0C,GAAGY,KAAK6zC,YAAY,SAAS7yC,KAAK05B;gBAC9B,IAAI0Z,QAAQ1Z,MAAMx7B,MAAM,GAAG,IACvB0d,KAAK+2B,eAAeZ,kBAAkBqB,SAAS3Q,SAAS2Q,OAAO,KAC/DC,gBAAgBH,WAAWlrC,QAAQ4T,KACnC03B,WAAWroC,SAASsoC;gBAExB,IAAIF,iBAAiB,GAAG;oBACpBpoC,UAAU4mC,SAASj2B,IAAIxc;oBACvBm0C,eAAe1B,SAASj2B,IAAI/O;oBAC5BymC,YAAY5Z,MAAMx7B,MAAM+0C,gBAAgBA,iBAAkBM,eAAe;oBACzEJ,KAAKloC,WAAW0nC,eAAeZ,kBAAkBuB,aAAa7Q,SAAS6Q,WAAW;oBAElFJ,WAAW71B,OAAOg2B,eAAe;;gBAGrC,IAAIH,WAAW1wC,WAAW,GAAG;oBACzB,OAAO;;;YAIf,OAAO2wC;;QAGX/0C,GAAGuG,OAAOtE;YAONyS,OAAO;gBACH,IAAI0gC,SAAS,IAAIp1C,GAAGmP,WAChBkmC,iBAAiB,SAAShzC;oBACtBD,IAAIpC,GAAGyL,OAAO,mCAAmCpJ;oBACjD+yC,OAAO7lC,QAAQlN;;gBAGvB8xC,gBAAgBl6B,KAAK,SAASq7B;oBAC1BlzC,IAAIpC,GAAGyL,OAAO,oDAAoD0C,WAAWnN,SAASV,YAAY,SAAS6N,WAAWnN;oBAEtHozC,eAAekB,YAAYr7B,KAAK,SAASs6B;wBAErCnyC,IAAIpC,GAAGyL,OAAO,gCAAgC8oC,eAAe,WAAW;wBAExED,iBAAiBgB,YAAYf,cAAct6B,KAAK,SAASs7B;4BAErDnzC,IAAIpC,GAAGyL,OAAO,mCAAmC8pC;4BAEjDf,OAAOc,YAAYC,eAAet7B,KAAK,SAAS06B;gCAC5C,IAAIF,aAAaC,cAAcC,SAC3Ba,YAAYZ,aAAaL,cAAcE;gCAE3CryC,IAAI;gCAEJgzC,OAAO/lC,QAAQmmC;+BAChBH;2BACJA;uBACJA;mBACJA;gBAEH,OAAOD;;;QAKfnzC,KAAKsxC;QACLtxC,KAAKsxC,SAASI,oBAAoBA;;IC7MtC3zC,GAAGsyC,WAAW,SAASnkC,YAAY/L;QAC/B;QAEA,SAASqzC,eAAeC,YAAYC;YAChC,IAAIC,eAAe,OACfC,uBAAuB1iC,OAAOuiC;YAElC11C,GAAGY,KAAKi1C,mBAAmB,SAASj0C,KAAKk0C;gBACrC,IAAIH,kBAAkB/rC,QAAQksC,0BAA0B,GAAG;oBACvDF,eAAe;oBACf,OAAO;;;YAIf,OAAOA;;QAGX51C,GAAGuG,OAAOtE;YASNuwC,eAAe;gBACX,IAAIzuC,OAAO9B,MACPyoB,aAAa,IAAI1qB,GAAGmP,WACpB4mC,cAAc,OACd/0C,OAAOmN,WAAWnN,SAASV,YAAY,SAAS6N,WAAWnN;gBAE/DoB,IAAIpC,GAAGyL,OAAO,iEAAiEzK;gBAE/EoB,IAAI;gBAEJ,IAAIH,KAAK+zC,qBAAqB;oBAC1B5zC,IAAI;oBAEJpC,GAAG4O,cAAcT,YAAY,GAAG,GAAG8L,KAAK,SAAS25B;wBAC7C5zC,GAAGY,KAAKmD,KAAKkyC,wBAAwB,SAASztC,MAAMiG;4BAChD,IAAIgnC,eAAehnC,OAAOmlC,MAAM;gCAG5B,IAAIprC,SAAS,gBAAgBxI,GAAGgW,kBAAkBwD,cAAc;oCAC5Du8B,cAAc;oCACdrrB,WAAWrb,QAAQ7G;;gCAGvB,OAAO;;;wBAIfpG,IAAIpC,GAAGyL,OAAO,kDAAkDzK,MAAM+0C,cAAc,KAAK;wBAEzF,KAAKA,aAAa;4BACdrrB,WAAWnb;;uBAGnB;wBACInN,IAAI,iCAAiCpB,OAAO;wBAC5C0pB,WAAWnb;;uBAGd;oBACDmb,WAAWnb;;gBAGf,OAAOmb;;YAWXsrB,mBAAmB;gBACf,IAAIE,WAAW/nC,WAAWhL,MAEtBgzC,oBAAoBn2C,GAAG4J,QAAQW,OAAO23B,KAAKjgC,KAAKg0C,yBAAyBC,aAAa,GACtFH,cAAc,OACd/0C,OAAOmN,WAAWnN,SAASV,YAAY,SAAS6N,WAAWnN;gBAE/D,IAAIm1C,mBAAmB;oBACnB,IAAID,aAAa,cAAc;wBAC3BH,cAAc/1C,GAAGgW,kBAAkBwD;2BAElC;wBACDu8B,cAAc;;;iBAIrBA,eAAe3zC,IAAIpB,OAAO;gBAE3B,OAAO+0C;;;;IAKnB/1C,GAAGsyC,SAAShxC,UAAU20C;QAClBG,cAAc;QACdC,aAAa;QACbC,aAAa;QACbC,aAAa;QACbC,gBAAe,YAAY;;ICpG/Bx2C,GAAG03B,kBAAkB,SAAS7oB,MAAMzM;QAChC;QAMA,SAASq0C,iBAAiBC;YACtB,IAAIC,aAAa;YAEjB32C,GAAGY,KAAK81C,QAAQ,SAASE,OAAOlsC;gBAC5B,IAAIA,QAAQ,GAAG;oBACXisC,aAAa;oBACb,OAAO;;;YAIf,OAAOA;;QAQX,SAASE;YACL,IAAIC,oBAAoB,IAAI92C,GAAGmP;YAE/B,IAAInP,GAAGsyC,SAASzjC,MAAMzM,KAAKowC,gBAAgBv4B,KAAK;gBAC5C,IAAI2d,QAAQ,IAAImY,SACZpS,MAAM10B,OAAO+mC,OAAO/mC,OAAO+mC,IAAIC,kBAAkBhnC,OAAO+mC,MAClD/mC,OAAOinC,aAAajnC,OAAOinC,UAAUD,kBAAkBhnC,OAAOinC,YAC9D;gBAEV,IAAIvS,KAAK;oBACL/F,MAAMtoB,UAAU;wBACZlN,IAAI,6DAA6D;wBACjE00C,kBAAkBvnC;;oBAGtBqoB,MAAMxoB,SAAS;wBACX0nC,kBAAkBznC;4BACds9B,OAAO1qC,KAAK0qC;4BACZtwB,QAAQpa,KAAKoa;;;oBAIrBub,MAAMuY,MAAMxS,IAAIsS,gBAAgBphC;uBAE/B;oBACDzM,IAAI,gEAAgE;oBACpE00C,kBAAkBvnC;;eAEvBunC,kBAAkBvnC;YAErB,OAAOunC;;QASX,SAASC,gBAAgBL,QAAQM;YAC7B,IAAIC;YAEJj3C,GAAGY,KAAK81C,QAAQ,SAASQ,WAAWC;gBAChC,IAAIA,aAAa,GAAG;oBAChB,IAAIC,eAAe,0BAA0Bl2C,KAAKg2C,YAC9CG,oBAAoBD,aAAa,GAAGx3C,OAAO,GAAGG,gBAAgBq3C,aAAa,GAAGt3C,MAAM,IACpFw3C,cAAcN,WAAWK;oBAG7B,QAAQD,aAAa;sBACjB,KAAK;wBACD,IAAIE,cAAcH,YAAY;4BAC1BF,eAAeC;4BACf,OAAO;;wBAEX;;sBACJ,KAAK;wBACD,IAAII,cAAcH,YAAY;4BAC1BF,eAAeC;4BACf,OAAO;;wBAEX;;;;YAKhB,OAAOD;;QAWXh1C,KAAK01B,WAAW,SAAS+e;YACrB,IAAIa,mBAAmB,IAAIv3C,GAAGmP;YAE9B/M,IAAI;YAEJ,IAAIq0C,iBAAiBC,SAAS;gBAC1BG,iBAAiB58B,KAAK,SAAS+8B;oBAC3B,IAAIC,eAAeF,gBAAgBL,QAAQM;oBAE3C,IAAIC,cAAc;wBACdM,iBAAiBhoC,QAAQ0nC;2BAExB;wBACDM,iBAAiBloC;;mBAEtBkoC,iBAAiBloC;mBAEnB;gBACDkoC,iBAAiBloC;;YAGrB,OAAOkoC;;;IC7Hfv3C,GAAG22B,UAAU,SAASvY;QAClB;QAEA,IAAInf;YACA4hB,UAAU;YACVrhB;YACAgqB;YACAG;YACAkN,eAAe,SAAStO;YACxBnmB,KAAK,SAASC,SAAS8H;;QAG3BnK,GAAGuG,OAAOtH,SAASmf,MAAM;QAEzB,SAASo5B,oBAAoB/jB;YACzB,IAAIzzB,GAAG6C,QAAQ4wB,WAAW;gBACtB,OAAO;;YAGXx0B,QAAQmD,IAAI,qCAAqC;;QAGrD,SAASq1C,gBAAgBC,WAAWroC,SAAS0a,UAAU7a;YACnD,IAAIyoC,mBAAmB;YAEvBtoC,UAAUA,WAAWmoC,oBAAoBE;YAEzC,IAAIroC,SAAS;gBACTrP,GAAGY,KAAK82C,WAAW,SAAS91C,KAAKu+B;oBAE7B,IAAIA,SAASxiB,QAAQ,MAAM;wBACvBg6B,mBAAmB;wBACnB14C,QAAQmD,IAAIpC,GAAGyL,OAAO,qEAAqE7J,MAAM;2BAEhG,IAAIu+B,SAASn/B,QAAQ,MAAM;wBAC5B22C,mBAAmB;wBACnB14C,QAAQmD,IAAIpC,GAAGyL,OAAO,qEAAqE7J,MAAM;2BAEhG;wBACD;4BACI3C,QAAQ43B,cAAcsJ;4BACtB,OAAO;0BAEX,OAAOyX;4BACHD,mBAAmB;4BACnB14C,QAAQmD,IAAIw1C,IAAIv1C,SAAS;;;oBAIjC,OAAO;;;YAIf6M,QAAQG,YAAYsoC,mBAAmB,YAAY,WAAWD,WAAW3tB;;QAK7E9nB,KAAK60B,UAAU;YAEX,IAAI+gB,gBAAgB,IAAI73C,GAAGmP,WACvB2oC,0BAA0B,SAASrkB,UAAUpkB,SAAS0a;gBAClD0tB,gBAAgBhkB,UAAUpkB,SAAS0a,UAAU8tB;eAEjDE,mBAAmB/3C,GAAGuG,WAAWtH,UACjCgtC,YAAY,IAAIjsC,GAAGg4C,qBACfh4C,GAAGuG,OAAOwxC;gBAAmBzqB,YAAYwqB;;YAGjD7L,UAAUgM;YAEV,OAAOJ;;;ICrEf73C,GAAGg4C,uBAAuB,SAAS55B;QAC/B;QAEA,IAAI6tB,WACAhtC;YACI4hB,UAAU;YACV2I;YACAhqB;YACAmqB;gBACIoI,UAAU;gBACVyI,iBAAiB;;YAErBlN,YAAY,SAASmG,UAAUpkB,SAAS0a;YACxC3nB,KAAK,SAASsJ,KAAKvB;;QAG3BnK,GAAGuG,OAAOtH,SAASmf;QAEnB,SAASkP,WAAW9P,IAAIuM,UAAUC;YAC9B,IAAIyJ,WAAW;YAGf,IAAI1J,SAASmuB,gBAAgB,MAAM;gBAC/B;oBACIzkB,WAAWzzB,GAAGuU,UAAUwV,SAASmuB;kBAErC,OAAON;oBACH34C,QAAQmD,IAAI,uCAAuCw1C,IAAIv1C,SAAS;oBAChE2nB,UAAU;;;YAIlB/qB,QAAQquB,WAAWmG,WAAWzJ,SAASD;;QAG3CkiB,YAAYjsC,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7B;YAC/BI,cAAc;YACdC,gBAAe;YACfzS,QAAQ;YACRO;gBACI5E,KAAK;oBACD,OAAO7lB,QAAQ4hB;;;YAGvB2I,eAAevqB,QAAQuqB;YACvBpnB,KAAKnD,QAAQmD;YACbkrB,YAAYA;YACZ3D,MAAM1qB,QAAQ0qB;;QAGlB3pB,GAAGuG,OAAOtE;YACNg2C,aAAa;gBACT,IAAIz4C,SAASQ,GAAGuG,WAAWtH,QAAQO;gBAEnCP,QAAQmD,IAAI;gBAEZ6pC,UAAUjN,cAAc,kBACnBK,WAAW7/B,QACXmgC,kBACAtB;;;;ICzDjBr+B,GAAG+mB,SAAS,SAAS3I,MAAMhc;QACvB;QAEA,IAAI2B,OAAO9B,MACP6hB,uBAAuB1F,KAAKsc,eAC5Byd,kBAAkB/5B,KAAKuc,cACvBC,SAASxc,KAAKwc,QACdC,cAAczc,KAAKyc,aACnBC,iBAAiB1c,KAAK0c,iBAAiB,KACvCsd,oBAAoBh6B,KAAK2c,aACzBC,cAAc5c,KAAK4c,aACnBC,QAAQh5B,KAAKo2C,gBAAgBj6B,KAAK6c;QAGtCj7B,GAAGuG,OAAOtE;YAGNghB,SAASjjB,GAAGgW,kBAAkBuD,WAAW0hB,MAAM72B,SAAS;YAExDk0C,gBAAgB,SAASC,kBAAkBC,kBAAkBC;gBACzD,IAAI10C,OAAO9B,MACPy2C,cACAC,eAAeF,uBAAuB5pC,OAAO4pC,uBAAuB5pC,OAAO4pC,wBAC3E/tB,aAAa,IAAI1qB,GAAGsyC,SAASqG,cAAcv2C;gBAG/C,IAAIsoB,WAAWsrB,qBAAqB;oBAEhCh2C,GAAGY,KAAKq6B,OAAO,SAASr5B,KAAKg3C;wBACzB,IAAIC,aAAa90C,KAAK+0C;4BAClBje,aAAaA;4BACbke,eAAeH,WAAWz1C;4BAC1B61C,SAASL,aAAax1C;;wBAG1Bu1C,QAAQ52C;4BACJ6b,MAAM3d,GAAGsQ;4BACTtP,MAAM+C,KAAKk1C,SAAST;gCAChBx3C,MAAM43C,WAAW53C;gCACjBmC,MAAM01C;gCACNG,SAASL,aAAax1C;;4BAE1B0L,MAAM,IAAI7O,GAAG2a,UAAUg+B,cACvB34C,GAAG+S,KAAKhP,KAAKm1C,sBAAsBn1C;gCAC/B+f,sBAAsBA;gCACtBF,SAASg1B,WAAWh1B;gCACpBgX,QAAQA;gCACRz3B,MAAM01C;gCACNpwC,SAASqyB;gCACTqe,YAAYf;gCACZpd,aAAaA;gCACb54B,KAAKA;;;;oBAKjBs2C,QAAQ52C;wBACJ6b,MAAM46B;wBACNv3C,MAAMw3C;wBACNj6B,MAAMo6B,aAAap6B;wBACnB1P,MAAMspC,kBAAkBQ,eAAe;;uBAG1C;oBACDD,QAAQ52C;wBACJ6b,MAAM46B;wBACNv3C,MAAMw3C;wBACNj6B,MAAMo6B,aAAap6B;wBACnB1P,MAAM8pC;;;gBAId,OAAOD;;YAGXtd,eAAe,SAAShZ,MAAMphB,MAAM2c,MAAMY,MAAM4S,UAAU3S,SAAS6K,eAAe+vB;gBAC9E,IAAIr1C,OAAO9B,MACPwZ,WAAW2G,KAAKyG,cAAezG,KAAKvT,QAAQuT,KAAKvT,KAAKga,YACtDwwB,gBACAC,aAAa,MACbroB,mBAAmBmoB,IAAInoB,kBACvBlO,aAAaq2B,IAAIr2B,YACjB0G,cAAc2vB,IAAI3vB,aAClBhL,eAAeze,GAAGsQ;gBAEtBtQ,GAAGY,KAAKmD,KAAKu0C,eAAe36B,MAAM3c,MAAMohB,OAAO,SAASxgB,KAAK23C;oBACzD,IAAIC,WAAWD,OAAOh7B,MAClBf;oBAEJ,IAAI+7B,OAAO1qC,gBAAgB7O,GAAG2a,WAAW;wBACrC6+B,YAAY;;oBAGhBh8B,KAAKuF,WAAW5E;wBACZR,MAAM47B,OAAO57B;wBACb3c,MAAMu4C,OAAOv4C;wBACbud,MAAMi7B;wBACNh7B,SAASA;wBACTC,cAAcA;;oBAGlB,IAAI86B,OAAO1qC,gBAAgB7O,GAAG2a,WAAW;wBACrC0+B,UAAUv3C,KAAK0b;2BAEd;wBACD87B,aAAa97B;;oBAGjB,IAAI+7B,OAAO1qC,MAAM;wBACboiB,iBAAiBzT,IAAI+7B,OAAO1qC;wBAC5BsiB,SAASrvB;4BAAM0b,IAAIA;4BAAI4E,MAAMm3B,OAAO1qC;;2BAEnC;wBACDkU,WAAWlE,UAAUrB,IAAIxd,GAAG6d,OAAOkC;;;gBAO3C,IAAIu5B,eAAe,MAAM;oBACrBt5C,GAAGY,KAAKy4C,WAAW,SAASz3C,KAAK63C;wBAC7B,IAAIj6C;4BACAk6C,cAAc32B,WAAWpE;gCAAUnB,IAAI87B;+BAAa37B;4BACpDg8B,cAAc52B,WAAWpE;gCAAUnB,IAAI87B;+BAAa/6B;;wBAKxD/e,OAAO6pB,iBAAiBtG,WAAWpE;4BAAUnB,IAAIi8B;2BAAW97B;wBAE5DoF,WAAWtD,YAAYg6B,UAAUH;wBACjC7vB,YAAY+B,YAAYiuB,UAAUj6C;;oBAKtC,IAAI65C,UAAUj1C,QAAQ;yBACjB;4BACG,IAAIw1C;4BACJA,MAAMvwB,iBAAiBtG,WAAWpE;gCAAUnB,IAAI87B;+BAAa37B;4BAC7D8L,YAAY+B,YAAY8tB,YAAYM;;;;;;;IAQ5D55C,GAAGuG,OAAOvG,GAAG+mB,OAAOzlB;QAChBulB,YAAY,SAASrJ,IAAIsJ,OAAOsyB;YAC5B;YAEA,KAAKp5C,GAAGgW,kBAAkBuD,SAAS;gBAC/B,MAAM,IAAIvZ,GAAGkG,MAAM;;YAGvB,IAAI2zC,gBAAgB,IAAI75C,GAAGmP,WACvB/M,MAAMg3C,IAAIh3C,KACVggB,OAAOg3B,IAAIh1B,QAAQ5G,KACnBuF,aAAaq2B,IAAIr2B,WAAWpE;gBAAUnB,IAAIA;gBAC1Cxc,OAAO+hB,cAAcA,WAAW/hB,MAChC2c,OAAOoF,cAAcA,WAAWpF,MAChCm8B;gBACIpf,eAAe5T,MAAM4T;gBACrBC,cAAc;gBACdC,QAAQ9T,MAAM8T;gBACdC,aAAa/T,MAAM3jB,QAAQ;gBAC3B23B,gBAAgBhU,MAAMre;gBACtB2vC,mBAAmB;gBACnBnd;oBAASj6B,MAAM;oBAAI4iB,SAASkD,MAAMlD;;eAEtCm2B,SAAS,IAAI/5C,GAAG+mB,OAAO+yB,gBAAgB13C;YAE3C,KAAKpC,GAAG+mB,WAAW/mB,GAAGgW,kBAAkBiD,kBAAkBmJ,MAAM;gBAC5Dy3B,cAActqC;gBAEdnN,IAAI,mDAAmDob,KAAK,QACxD,qFAAqF;mBAExF;gBACAxd,GAAG+S,KAAK;oBAEL,IAAIwmC,SAASQ,OAAOzB,eAAe36B,MAAM3c,MAAMohB,MAAM;oBAErD,IAAIm3B,UAAUA,OAAO1qC,gBAAgB7O,GAAG2a,WAAW;wBAC/C4+B,OAAO1qC,KAAKiM,SAASb,KAAK4/B,cAAcxqC,SAASwqC,cAActqC;2BAE9D;wBACDnN,IAAIob,KAAK,6BAA6B;wBACtCq8B,cAActqC;;mBAEnBtN;;YAGP,OAAO43C;;QAKXf,sBAAsB,SAAS16B;YAC3B;YAEA,IAAI26B,gBAAgB36B,KAAK26B,eACrBle,cAAczc,KAAKyc,aACnBmf,gBAAgB57B,KAAK46B;YAIzB,KAAKne,gBAAgBke,eAAe;gBAChC,IAAIiB,kBAAkB,cAAc;oBAChC,OAAO;;gBAEX,OAAOA;;YAIX,KAAKjB,eAAe;gBAChB,OAAOle;;YAIX,IAAI76B,GAAG4J,QAAQW,OAAO23B,KAAKliC,GAAGsyC,SAAShxC,UAAU20C,yBAAyB8C,kBAAkB,GAAG;gBAC3F,IAAIA,kBAAkB,cAAc;oBAChC,OAAO/4C,GAAGgW,kBAAkBwD,eAAeu/B,gBAAgBle;;gBAG/D,OAAOke;;YAGX,OAAOle;;QAIXoe,UAAU,SAAS36B,cAAc27B;YAC7B;YAEA,IAAIC,aAAa57B,aAAavJ,YAAY,MACtColC,cAAcF,wBAAwB92C,QAAQ,aAC9C62C,gBAAgBC,wBAAwBjB,SACxCoB,aAAa,IACbC,YAAYr6C,GAAG4U,aAAa0J,eAC5Bg8B,gBAAgB;YAEpB,IAAIL,wBAAwBj5C,QAAQi5C,wBAAwBj5C,KAAKwK,OAAOpH,QAAQ;gBAC5Ek2C,gBAAgB,OAAOL,wBAAwBj5C,OAAO;;YAG1D,IAAIk5C,cAAc,GAAG;gBACjBE,aAAa97B,aAAatJ,OAAO,GAAGklC;gBAEpC,IAAIF,kBAAkBG,aAAa;oBAC/BE,YAAYF,YAAYxwC,MAAM,KAAK;;gBAGvCywC,cAAcE,gBAAgB,MAAMD;mBAEnC;gBACDD,aAAa97B,eAAeg8B;;YAGhC,OAAOF;;QAIX/B,iBAAiB,SAASpd;YACtB;YAEAA,QAAQj7B,GAAGuG,WAAW00B;YAEtB,OAAOA,MAAMsf,KAAK,SAASC,GAAGC;gBAC1B,IAAID,EAAE52B,UAAU62B,EAAE72B,SAAS;oBACvB,OAAO;;gBAEX,IAAI42B,EAAE52B,UAAU62B,EAAE72B,SAAS;oBACvB,QAAQ;;gBAEZ,OAAO;;;QAIfs1B,sBAAsB,SAAS96B,MAAMs8B;YACjC;YAEA,IAAI32C,OAAO9B,MACP6hB,uBAAuB1F,KAAK0F,sBAC5B1hB,MAAMgc,KAAKhc,KACXwhB,UAAUxF,KAAKwF,SACfgX,SAASxc,KAAKwc,QACdz3B,OAAOib,KAAKjb,MACZsF,UAAU2V,KAAK3V,SACf0wC,aAAa/6B,KAAK+6B,YAClBne,cAAc5c,KAAK4c,eAAe0f,WAAWv3C,SAAS,gBAAgBA,SAAS,cAC/E02C,gBAAgB,IAAI75C,GAAGmP,WACvBwrC,iBAAiB,IAAI36C,GAAGk7B,eAAe94B,MACvCmG,SAAS2E,SAASC,cAAc;YAEpC/K,IAAI,+CAA+Cs4C,WAAW15C;YAE9D25C,eAAer2B,SAASo2B,YAAYnyC;gBAASqb,SAASA;gBAASgX,QAAQA;gBAAQ9W,sBAAsBA;eAAuB7J,KAAK;gBAC7H,IAAI2gC,qBAAqBryC,OAAOI,UAAUxF,MAAMsF,UAC5CoyC,gBAAgB;oBACZz4C,IAAI,2CAA2Cs4C,WAAW15C;oBAC1D,IAAI6N,OAAO7O,GAAG0I,cAAckyC;oBAC5Bf,cAAcxqC,QAAQR;;gBAG9B,IAAImsB,aAAa;oBACbj3B,KAAK+2C,kBAAkBJ,YAAYE,oBAAoBx4C,KAAK6X,KAAK,SAAS8gC;wBACtEH,qBAAqBG;wBACrBF;uBAEJ;wBACIz4C,IAAI,yFAAyF;wBAC7Fy4C;;uBAGH;oBACDA;;eAEL;gBACCz4C,IAAI,mDAAmDs4C,WAAW15C,MAAM;gBACxE64C,cAActqC,QAAQ4pC;;YAG1B,OAAOU;;QAIXiB,mBAAmB,SAASE,eAAeJ,oBAAoBx4C;YAC3D;YAEA,IAAI64C,SAAS,IAAIhsC,cACbisC,kBAAkB,IAAIl7C,GAAGmP,WACzBgsC,uBAAuB;YAE3BF,OAAO7rC,SAAS;gBACZ+rC,uBAAuBF,OAAO7zC;gBAC9B8zC,gBAAgB7rC,QAAQrP,GAAGo7C,aAAajM,QAAQgM,sBAAsBP;;YAG1EK,OAAO3rC,UAAU;gBACblN,IAAI,qBAAqB44C,cAAch6C,OAAO,4DAA4D;gBAC1Gk6C,gBAAgB3rC;;YAGpB0rC,OAAOI,cAAcL;YAErB,OAAOE;;QAGXI,gBAAgB,SAAS1yC;YACrB;YAEA,IAAIE,YAAYY,YAAYb,aAAaY;YAGzC,IAAIb,QAAQe,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cd,aAAae,KAAKjB,QAAQe,MAAM,KAAK;mBAEpC;gBACDb,aAAagB,UAAUlB,QAAQe,MAAM,KAAK;;YAI9CD,aAAad,QAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBd,cAAc,IAAIkB,YAAYjB,WAAW1E;YACzCqF,WAAW,IAAIO,WAAWnB;YAC1B7I,GAAGY,KAAKkI,YAAY,SAASlH,KAAKqI;gBAC9BR,SAAS7H,OAAOqI,UAAUC,WAAW;;YAGzC,OAAOjI,KAAKs5C,YAAY1yC,aAAaa;;QAGzC6xC,aAAa,SAASl7C,MAAMmI;YACxB;YAEA,IAAIQ,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;YAErC,IAAIK,aAAa;gBACbA,YAAYC,OAAOjJ;gBACnB,OAAOgJ,YAAYE,QAAQf;mBAE1B;gBACD,OAAO,IAAIgB,OAAMnJ;oBAAQ8C,MAAMqF;;;;;IChZ3CxI,GAAGo7C,eAAe;QAGjB,IAAIA;QAEDA,aAAaI,UAAU,qBACF,qBACA,qBACA,qBACA;QAErBJ,aAAaK,WAAW,SAASxuC;YAE7B,IAAIyuC,SAAS,IACTC,MAAMC,MAAMC,OAAO,IACnBC,MAAMC,MAAMC,MAAMC,OAAO,IACzBroC,IAAI;YAER,GAAG;gBACC+nC,OAAO1uC,MAAM2G;gBACbgoC,OAAO3uC,MAAM2G;gBACbioC,OAAO5uC,MAAM2G;gBAEbkoC,OAAOH,QAAQ;gBACfI,QAASJ,OAAO,MAAM,IAAMC,QAAQ;gBACpCI,QAASJ,OAAO,OAAO,IAAMC,QAAQ;gBACrCI,OAAOJ,OAAO;gBAEd,IAAIK,MAAMN,OAAO;oBACdI,OAAOC,OAAO;uBACV,IAAIC,MAAML,OAAO;oBACrBI,OAAO;;gBAGVP,SAASA,SACNz5C,KAAKu5C,QAAQ57C,OAAOk8C,QACpB75C,KAAKu5C,QAAQ57C,OAAOm8C,QACpB95C,KAAKu5C,QAAQ57C,OAAOo8C,QACpB/5C,KAAKu5C,QAAQ57C,OAAOq8C;gBACvBN,OAAOC,OAAOC,OAAO;gBACrBC,OAAOC,OAAOC,OAAOC,OAAO;qBACvBroC,IAAI3G,MAAM7I;YAEnB,OAAOs3C;;QAGXN,aAAajM,UAAU,SAASgN,gBAAgBC;YAE5C,IAAIC,uBAAuB;YAE3B,KAAKF,eAAe/4C,MAAMi5C,uBAC1B;gBACC,OAAOD;;YAGR,IAAIE,WAAWr6C,KAAKs6C,SAASJ,eAAen1C,QAAQq1C,sBAAsB;YAC1E,IAAIG,WAAWv6C,KAAKw6C,eAAeH;YAEnC,IAAI1kB,QAAQ31B,KAAKy6C,iBAAiBN,mBAAmBI;YAErD,OAAOH,uBAAuBp6C,KAAKw5C,SAAS7jB;;QAKhDwjB,aAAasB,mBAAmB,SAASN,mBAAmBI;YAEpD,IAAIG,YAAY16C,KAAK26C,aAAaJ,WAC9BK,gBAAgB56C,KAAK66C,WAAWV,mBAAmBO,YACnDI,UAAU,IAAI/yC,WAAW6yC;YAE7B,OAAOE;;QAIf3B,aAAawB,eAAe,SAASJ;YAE7B,IAAIQ;YACJ,KAAK,IAAIC,IAAI,GAAGA,IAAIT,SAASp4C,QAAQ64C,KACrC;gBACID,MAAMR,SAASS;gBACf,IAAID,IAAI,MAAM,MAAMA,IAAI,MAAM,KAC9B;oBACI,OAAOA;;;YAGf;;QAIR5B,aAAa0B,aAAa,SAASV,mBAAmBO;YAE9C,IAAIO,YAAYd,kBAAkBp1C,QAAQ,2BAA2B,KACjEm2C,MAAMl7C,KAAKs6C,SAASW,YACpBE,gBAAgBD,IAAIvzC,QAAQ,KAAI,IAChCyzC,MAAMF,IAAIr9C,MAAM,GAAGs9C,gBACnBE,MAAMH,IAAIr9C,MAAMs9C,gBAChBG,QAAQF;YAEZE,QAAQA,MAAMpqC,OAAOwpC;YACrBY,QAAQA,MAAMpqC,OAAOmqC;YACtB,OAAOC;;QAKdnC,aAAaqB,iBAAiB,SAASe;YAEnC,IAAIC,OAAO,GACPjB;YAEJ,OAAO,GACP;gBACI,IAAIgB,cAAcC,SAAS,MAAMD,cAAcC,OAAO,MAAM,KAAI;oBAAC;;gBACjE,IAAID,cAAcC,SAAS,MAAMD,cAAcC,OAAO,MAAM,KAC5D;oBACIA,QAAQ;uBAGZ;oBACI,IAAIr5C,SAASo5C,cAAcC,OAAO,KAAK,MAAMD,cAAcC,OAAO,IAC9DC,WAAWD,OAAOr5C,SAAS,GAC3B44C,MAAMQ,cAAc19C,MAAM29C,MAAMC;oBACpClB,SAAS16C,KAAKk7C;oBACdS,OAAOC;;gBAEX,IAAID,OAAOD,cAAcp5C,QAAO;oBAAC;;;YAGrC,OAAOo4C;;QAKXpB,aAAamB,WAAW,SAAStvC;YAE7B,IAAIyuC,SAAS,IACTC,MAAMC,MAAMC,OAAO,IACnBC,MAAMC,MAAMC,MAAMC,OAAO,IACzBroC,IAAI,GACJupC;YAGJ,IAAIQ,aAAa;YACjB,IAAIA,WAAWz8C,KAAK+L,QAAQ;gBACxB,MAAM,IAAI/G,MAAM,8DACZ;;YAER+G,QAAQA,MAAMjG,QAAQ,uBAAuB;YAE7C,GAAG;gBACC80C,OAAO75C,KAAKu5C,QAAQ5xC,QAAQqD,MAAMrN,OAAOgU;gBACzCmoC,OAAO95C,KAAKu5C,QAAQ5xC,QAAQqD,MAAMrN,OAAOgU;gBACzCooC,OAAO/5C,KAAKu5C,QAAQ5xC,QAAQqD,MAAMrN,OAAOgU;gBACzCqoC,OAAOh6C,KAAKu5C,QAAQ5xC,QAAQqD,MAAMrN,OAAOgU;gBAEzC+nC,OAAQG,QAAQ,IAAMC,QAAQ;gBAC9BH,QAASG,OAAO,OAAO,IAAMC,QAAQ;gBACrCH,QAASG,OAAO,MAAM,IAAKC;gBAE3BkB,IAAIr7C,KAAK65C;gBAET,IAAIK,QAAQ,IAAI;oBACbmB,IAAIr7C,KAAK85C;;gBAEZ,IAAIK,QAAQ,IAAI;oBACbkB,IAAIr7C,KAAK+5C;;gBAGZF,OAAOC,OAAOC,OAAO;gBACrBC,OAAOC,OAAOC,OAAOC,OAAO;qBAEvBroC,IAAI3G,MAAM7I;YAEnB,OAAO+4C;;QAIX,OAAO/B;;IC7KXp7C,GAAGq7B,gBAAgB,SAAS1oB,UAAUyS;QAClC;QAEA,IAAIw4B,sBACAC,cAAc,GACdC,YAAY,GAEZC,kBAAkB,GAClBC,iBAAiB,GACjBC,gBAAgB,SAAS9wB,QAAQC;YAC7B,IAAID,WAAW4wB,kBAAkB3wB,UAAU4wB,eAAe;gBACtDrrC,SAASwa,QAAQC;;YAGrB2wB,iBAAiB5wB;YACjB6wB,gBAAgB5wB;WAQpB8wB,mBAAmB,SAAS9pB,QAAQ+pB;YAChC,IAAIC,OAAO;YAEXp+C,GAAGY,KAAKwzB,QAAQ,SAASxyB,KAAKy8C;gBAC1B,IAAIr+C,GAAG4J,QAAQu0C,WAAWE,aAAa,GAAG;oBACtCD,OAAO;oBACP,OAAO;;;YAIf,OAAOA;WAGX5wB,WAAW,SAAShQ;YAChB8gC,oBAAoB9gC,KAAK,IAAI;mBACtBogC,gBAAgBpgC;WAG3B6W,gBAAgB,SAASF,YAAYC,QAAQ+pB;YACzC,IAAI/pB,OAAOhwB,WAAW,KAAK85C,iBAAiB9pB,QAAQ+pB,YAAY;gBAC5DF,cAAcH,WAAWA;gBACzB77C,KAAK6a;;WAIbyhC,QAAQ,SAAS/gC;YACb,IAAIe,OAAO6G,QAAQ5H;YAGnB,IAAIe,OAAO,GAAG;gBACV+/B,oBAAoB9gC,IAAI,GAAGe;gBAC3Bq/B,gBAAgBpgC;oBAAO2P,QAAQ;oBAAGC,OAAO7O;;;WAYjD+/B,sBAAsB,SAAS9gC,IAAIghC,WAAWC;YAC1C,IAAIC,YAAYd,gBAAgBpgC,MAAMogC,gBAAgBpgC,IAAI2P,SAAS,GAC/DwxB,WAAWf,gBAAgBpgC,MAAMogC,gBAAgBpgC,IAAI4P,QAAQ;YAEjE,IAAIoxB,eAAe,KAAKC,cAAc,GAAG;gBACrCZ,eAAea;gBACfZ,aAAaa;mBAEZ;gBACD,IAAIH,WAAW;oBACXX,eAAeW,YAAYE;;gBAE/B,IAAID,UAAU;oBACVX,aAAaW,WAAWE;;;YAIhCV,cAAcJ,aAAaC;;QAGnC99C,GAAGuG,OAAOtE;YAENoyB,eAAeA;YAGf3V,gBAAgB,SAASlB,IAAIuB,WAAWD;gBACpC,IAAIA,cAAc9e,GAAG6d,OAAOoC,YAAYnB,cAAc9e,GAAG6d,OAAOkC,UAAU;oBACtEyN,SAAShQ;uBAER,IAAIsB,cAAc9e,GAAG6d,OAAOQ,YAAY;oBACzCkgC,MAAM/gC;;;YAKdwX,sBAAsB,SAASxX,IAAI2P,QAAQC;gBACvCkxB,oBAAoB9gC,IAAI2P,QAAQC;gBAChCwwB,gBAAgBpgC;oBAAO2P,QAAQA;oBAAQC,OAAOA;;;YAIlD6J,WAAW,SAASzZ;gBAChB+gC,MAAM/gC;;YAGVV,OAAO;gBACH8gC;gBACAC,cAAc;gBACdC,YAAY;;;;ICzHxB99C,GAAGmqB,eAAe,SAASnP;QACvB;QAEA,IAAI/b,SAAS2/C;QAEb3/C;YACImrB,eAAe;YACfzpB;gBACIyB,KAAK,SAASC,SAAS8H;gBACvBmgB,eAAe,SAASzb;;;QAIhC,SAASgwC,QAAQ5zC;YACb,OAAOA,KAAK9H,QACR8H,KAAK9H,KAAKyG,QAAQ,cAAc;;QAGxC,SAASk1C;YACLF,qBAAqB5+C,GAAGf,QAAQmrB,eAAellB,OAAO,SAAS,SAASuxB;gBACpE,IAAIsoB,gBAAgBtoB,MAAMsoB;gBAE1B,IAAIA,eAAe;oBACf/+C,GAAGY,KAAKm+C,cAAcnxC,OAAO,SAAShM,KAAKqJ;wBACvC,IAAI4zC,QAAQ5zC,OAAO;4BACf,IAAI4D,OAAO5D,KAAK+zC;4BAChB//C,QAAQ0B,UAAU2pB,cAAczb;;;;;;QAOpD,SAASowC;YACL,IAAIL,oBAAoB;gBACpBA;;;QAIR5+C,GAAGuG,OAAOtH,SAAS+b;QACnB8jC;QAEA9+C,GAAGuG,OAAOtE;YACN6a,OAAO;gBACHmiC;;;;ICpCZj/C,GAAGwxB,cAAc,SAASvyB,SAASigD,aAAa98C;QAC5C;QACA,IAAI2B,OAAQ9B,MACRw4B,kBAAkBx7B,QAAQw7B,iBAC1B0kB,SAASlgD,QAAQyD,SACjBivB,aAAa1yB,QAAQ0yB;QAGzB3xB,GAAGuG,OAAOtE;YAIN4vB,aAAa;YAIbD,eAAeD;YAGfF,gBAAgB;YAGhBC,uBAAuB;gBAEnB,IAAIytB,UAAU,MAAM;oBAChB,OAAO;;gBAGX,OAAOp7C,KAAKq7C,UAAUD;;;QAK9B,SAASE,qBAAqBF;YAC1B,IAAIA,OAAO92C,aAAa,WAAW;gBAC/BtE,KAAK8tB,cAAcstB,OAAO92C,aAAa;;;QAM/C,SAASi3C,aAAaH,QAAQI;YAC1B,IAAIJ,OAAOK,kBAAkBL,OAAOK,iBAAiB;gBACjDp9C,IAAI,0DAA0D;gBAC9Dm9C;mBAEC;gBACD,OAAO;;;QAKf,SAASE,oBAAoBN;YACzB,IAAII,eAAeJ,OAAOO;YAG1B1/C,GAAGm/C,QAAQj6C,OAAO,UAAU,SAASuxB;gBACjCA,QAAQA,SAASxtB,OAAOwtB;gBAExB,IAAIA,MAAMtkB,gBAAgB;oBACtBskB,MAAMtkB;uBAEL;oBACDskB,MAAMpkB,cAAc;;gBAGxBitC,aAAaH,QAAQI,iBAAiBL;;YAK1CC,OAAOO,SAAS;gBACZJ,aAAaH,QAAQI,iBAAiBL;;;QAM9C,SAASS,gBAAgBR;YACrB,IAAIA,QAAQ;gBACR,IAAIn/C,GAAGmL,SAASg0C,SAAS;oBACrBA,SAASjyC,SAASg6B,eAAeiY;;gBAGrC,IAAIA,QAAQ;oBACR/8C,IAAI;oBACJi9C,qBAAqBF;oBACrB1kB,mBAAmBglB,oBAAoBN;;;YAI/C,OAAOA;;QAGXA,SAASQ,gBAAgBR;QACzBl9C,KAAKwvB,mBAAmB0tB;;IAG5Bn/C,GAAGuG,OAAOvG,GAAGwxB,YAAYlwB;QAGrB89C,WAAW,SAAShrC;YAChB;YACA,IAAIf,UACAusC,oBAAoB,SAASz8C;gBACzB,IAAI08C,oBACA,UACA,SACA,SACA;gBAGJ,OAAO7/C,GAAG4J,QAAQi2C,iBAAiB18C,KAAKpD,iBAAiB;eAE7D+/C,kBAAkB,SAAS38C;gBACvB,OAAOnD,GAAG4J,UAAS,YAAY,WAAUzG,KAAKpD,kBAAkB;eAEpEggD,cAAc,SAAS57C;gBACnB,IAAI27C,gBAAgB37C,GAAGhB,UAAUgB,GAAG67C,SAAS;oBACzC,OAAO;;gBAGX,OAAO77C,GAAGgT,YAAYhT,GAAGhB,KAAKpD,kBAAkB;eAEpDkgD,cAAc,SAASC;gBACnB,IAAIx1C,QAAQ;gBAEZ1K,GAAGY,KAAKZ,GAAGkgD,QAAQz4C,YAAY,SAAS7F,KAAK8F;oBACzC,IAAIA,MAAMmF,QAAQ9M,kBAAkB,YAAY2H,MAAMy4C,UAAU;wBAC5Dz1C,QAAQhD,MAAMgD;wBACd,OAAO;;;gBAIf,OAAOA;;YAGf1K,GAAGY,KAAKwT,KAAKgsC,UAAU,SAASx+C,KAAKuC;gBACjC,KAAKnE,GAAGuM,QAAQpI,IAAI,SAASA,GAAG0I,QAAQ9M,kBAAkB,eACtD6/C,kBAAkBz7C,GAAGhB,UACpB48C,YAAY57C,KAAK;oBAElBkP,IAAIlP,GAAGnD,QAAQmD,GAAGuG;uBAEjB,IAAIvG,GAAG0I,QAAQ9M,kBAAkB,aAAaggD,YAAY57C,KAAK;oBAChE,IAAIuG,QAAQu1C,YAAY97C;oBAExB,IAAIuG,UAAU,MAAM;wBAChB2I,IAAIlP,GAAGnD,QAAQ0J;;;;YAK3B,OAAO2I;;;ICzJfrT,GAAGglC,cAAchlC,GAAGglC;IACpBhlC,GAAGglC,YAAYyB,oBAAoB,SAASxnC,SAASghC;QACjD;QAEA,IAAInP,UAAU7uB,MACVihB,UAAU+c,MAAM/c,SAChByC,UAAUsa,MAAMta,SAChBvjB,MAAM69B,MAAM79B;QAKhB,SAASi+C,qBAAqB7iC,IAAIypB;YAG9B,IAAIxT,UAAU6sB,KAAKC;YAGnB;gBAEID,MAAMrZ,OAAOa,mBAAmBb,OAAOuZ,cAActzC;gBACrDqzC,YAAYD,IAAI/Y,KAAK90B;gBAErBrQ,IAAI;gBACJA,IAAI,iBAAiBm+C;gBAErB,IAAIA,aAAaA,UAAUn9C,MAAM,WAAW;oBACxCm9C,YAAYD,IAAI/Y,KAAK5/B,WAAWA,WAAW84C;;gBAG/ChtB,WAAW3C,QAAQ2W,mBAAmB8Y;cAE1C,OAAOp+C;gBACHC,IAAI,0DAA0DD,MAAME,UAAU,KAAK;gBACnFoxB;oBAAYpkB,SAAS;;;YAGzB,OAAOokB;;QAMX,SAASitB,WAAWljC,IAAIypB;YACpB,IAAIznC,SAASP,QAAQwqB,YAAY3E,IAAItH,KACjC2L,SAASlqB,QAAQkqB,OAAOppB,kBAAkB,QAAQ,QAAQ,QAC1D8gB,WAAW5hB,QAAQyqB,cAAc5E,IAAItH,KACrCxc,OAAOkiB,QAAQ1F;YAEnBhe,OAAOP,QAAQsqB,YAAY5D,QAAQnI;YACnChe,OAAOP,QAAQq5B,iBAAiBt3B;YAEhC,OAAO8vB,QAAQkX;gBACX7e,QAAQA;gBACRtI,UAAUA;gBACVrhB,QAAQA;gBACRg5B,cAAcv5B,QAAQu5B;gBACtByP,YAAYhB,OAAOjmC;;;QAI3BiB,KAAKyiC,aAAa,SAASlnB;YACvB,IAAIvQ,QAAQ6jB,QAAQtU,SAASgB,KACzBypB,SAASnW,QAAQiX,cAAcvqB,KAC/BtO,UAAU,IAAIlP,GAAGmP,WACjBiF;YAEJA,OAAOssC,WAAWljC,IAAIypB;YACtB7yB,KAAKE,YAAYrH;YAEjB6jB,QAAQ8W,iBAAiBX,QAAQ,SAAS0Z;gBACtCv+C,IAAI;gBAEJ,IAAIqxB,WAAWktB,sBAAsBA,sBAAsBN,qBAAqB7iC,IAAIypB;gBAEpFnW,QAAQ6W,iBAAiBnqB;gBAGzB,KAAKve,QAAQ0qB,KAAKoI,UAAU;oBACxB/xB,GAAGinC,QAAQnhC;;gBAGf,IAAI2tB,SAASpkB,SAAS;oBAClBH,QAAQG,QAAQokB;uBAEf;oBACDvkB,QAAQK,QAAQkkB;;;YAIxBrxB,IAAI,gCAAgCob;YACpCpJ,KAAKsrC;YACL1/C,GAAGoU,MAAMtO;YAET,OAAOoJ;;QAGXlP,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGymC;YACnBxnC;gBACI6nC,QAAQ7nC,QAAQ0qB,KAAKoI;gBACrBtF,WAAWxtB,QAAQwtB;;YAGvBwT;gBACIzS,UAAUvuB,QAAQuuB;gBAClBtK,SAASA;gBACTyC,SAASA;gBACTvjB,KAAKA;;;;IC5GjBpC,GAAGglC,cAAchlC,GAAGglC;IACpBhlC,GAAGglC,YAAYmD,mBAAmB,SAAS/pB,MAAM6hB;QAC7C;QAEA,IAAInP,UAAU7uB,MACVihB,UAAU+c,MAAM/c,SAChBkC,UAAU6a,MAAM7a,SAChBO,UAAUsa,MAAMta,SAChBvjB,MAAM69B,MAAM79B,KACZw+C,YAAYxiC,KAAKma,kBAAkBna,KAAKoa,cAExCqoB,4BAA4B,SAASrjC,IAAIhe,QAAQwuB;YAC7C,IAAIzP,OAAO6G,QAAQ5H,KACfxc,OAAOkiB,QAAQ1F;YAEnBhe,OAAO4e,KAAK5F,SAASshB,WAAWC,aAAa/L,UAAUqc;YACvD7qC,OAAO4e,KAAK5F,SAASshB,WAAWE,kBAAkBhM,UAAU5f;YAC5D5O,OAAO4e,KAAK5F,SAASshB,WAAWG,aAAajM,UAAUzP;YACvD/e,OAAO4e,KAAK5F,SAASshB,WAAWK,cAAcnM,UAAUsc;YACxD9qC,OAAO4e,KAAKqa,qBAAqBla;YAMjC,IAAIqiC,WAAW;gBACXphD,OAAO4e,KAAKka,iBAAiBt3B;;WAIrC8/C,yBAAyB,IAAI9gD,GAAGglC,YAAY+b;YACxCp3B,MAAMvL,KAAKuL;YACX9I,UAAUzC,KAAK5F,SAASnJ,QAAQwR;YAChCze,KAAKA;YAGT4+C,iCAAiC,SAASxjC,IAAIhG;YAC1C,IAAItI,UAAU,IAAIlP,GAAGmP;YAErBqI,IAAIwmB,qBAAqB;gBACrB,IAAIxmB,IAAIgnB,eAAe,GAAG;oBACtB,IAAIp3B,SAAS65C,wBAAwBzjC,IAAIhG;oBAEzC,IAAIpQ,OAAOiI,SAAS;wBAChBH,QAAQG,QAAQjI,OAAOqsB,UAAUjc;2BAEhC;wBACDtI,QAAQK,QAAQnI,OAAOqsB,UAAUjc;;;;YAK7C,OAAOtI;WAGXgyC,0BAA0B,SAAS1jC;YAC/B,IAAIhe,SAAS4e,KAAKqL,YAAY3E,IAAItH,KAC9Bxc,OAAOkiB,QAAQ1F,KACfe,OAAO6G,QAAQ5H;YAEnBhe,OAAO4e,KAAKmL,YAAY5D,QAAQnI;YAChChe,OAAO4e,KAAKka,iBAAiBt3B;YAC7BxB,OAAO4e,KAAKqa,qBAAqBla;YACjC/e,OAAO4e,KAAK5F,SAASshB,WAAWK,cAAcrJ,QAAQgS,gBAAgBtlB;YAEtE,OAAOhe;WAGX2hD,wBAAwB,SAAS3pC,KAAKic;YAClC,OAAOzzB,GAAG4J,UAAS,KAAK,KAAK,KAAK,KAAK,OAAM4N,IAAIqG,UAAU,MACtD4V,SAASpkB,WACVokB,SAAS3W;WAGjBmkC,0BAA0B,SAASzjC,IAAIhG;YACnC,IAAIic;YAEJrxB,IAAI,wCAAwCob;YAC5Cpb,IAAI,oBAAoBoV,IAAI0gC;YAE5BzkB,WAAW2tB,cAAc,MAAM5pC;YAE/B;gBACInI,UAAU8xC,sBAAsB3pC,KAAKic;gBACrCA,UAAUA;;WAKlB2tB,gBAAgB,SAAS7zC,QAAQiK;YAC7B,IAAIic;YAEJ;gBACIrxB,IAAIpC,GAAGyL,OAAO,6CAA6C+L,IAAIqG,QAAQrG,IAAI0gC;gBAC3EzkB,WAAWzzB,GAAGuU,UAAUiD,IAAI0gC;cAEhC,OAAO/1C;gBACHoL,UAAUnL,IAAI,uDAAuDD,MAAME,UAAU,KAAK;;YAG9F,OAAOoxB;WAGX4tB,4BAA4B,SAAS7jC;YACjC,IAAItO,UAAU,IAAIlP,GAAGmP;YAErB2xC,uBAAuBQ,SACf9jC,IACAsT,QAAQgZ,WAAWtsB,KACnB0jC,wBAAwB1jC,KACxBY,KAAKoL,cAAc1E,IAAItH,KAE1BvD,KAAK,SAASzC;gBACXtI,QAAQG,QAAQ+xC,cAAc,OAAO5pC,MAAMA;eAC5C,SAASA;gBACRtI,QAAQK,QAAQ6xC,cAAc,OAAO5pC,MAAMA;;YAGnD,OAAOtI;WAGXqyC,8BAA8B,SAAS/hD,QAAQgY,KAAKrJ,YAAYqP;YAC5D,IAAIvJ,WAAW,IAAI5G,YACf8b,SAAS/K,KAAK+K,QACdtI,WAAWzC,KAAKsL,cAAc5E,IAAItH,KAClCxc,OAAOkiB,QAAQ1F,KACfe,OAAO6G,QAAQ5H;YAEnBhe,OAAO4e,KAAKmL,YAAY5D,QAAQnI;YAChChe,OAAO4e,KAAKka,iBAAiBt3B;YAE7B,IAAI4/C,WAAW;gBACXphD,OAAO4e,KAAKqa,qBAAqBla;;YAIrC,KAAKH,KAAKoa,cAAc;gBACpB,KAAKooB,WAAW;oBACZphD,OAAO4e,KAAKqO,aAAazrB;;gBAE7B6f,WAAW7gB,GAAGoT,QAAQ5T,QAAQqhB;;YAGlCrJ,IAAI2mB,KAAKhV,QAAQtI,UAAU;YAE3B,IAAIzC,KAAKuL,KAAKoI,YAAY3T,KAAKuL,KAAK6Q,iBAAiB;gBACjDhjB,IAAIC,kBAAkB;;YAG1B,IAAImpC,WAAW;gBACX,IAAIxiC,KAAKoa,cAAc;oBACnBx4B,GAAGgU,aAAaxU,QAAQyU;;gBAG5BA,SAAS3K,OAAO8U,KAAKqO,WAAWte;gBAChC,OAAO8F;;YAGX,OAAO9F;WAGXqzC,mBAAmB,SAAShkC,IAAIhG;YAC5B,IAAIiqC,eAAerjC,KAAKoL,cAAc1E,IAAItH,KACtCrP,aAAa2iB,QAAQ1M,QAAQ5G;YAEjChG,IAAIqnB,iBAAiB,UAAU;YAC/BrnB,IAAIqnB,iBAAiB,oBAAoB;YACzCrnB,IAAIqnB,iBAAiB,iBAAiB;YAEtC,KAAK+hB,WAAW;gBACZppC,IAAIqnB,iBAAiB,gBAAgB;gBAErCrnB,IAAIqnB,iBAAiB,eAAe1wB,WAAWhL;;YAGnDnD,GAAGY,KAAK6gD,cAAc,SAASzgD,MAAMZ;gBACjCoX,IAAIqnB,iBAAiB79B,MAAMZ;;;QAIvCJ,GAAGuG,OAAOtE;YACNkhC,aAAa,SAAS3lB,IAAIujB,UAAUzG;gBAChC,IAAItM,YAAY8C,QAAQkQ,cAAcxjB,IAAIujB,WACtCvpB,MAAMsZ,QAAQgZ,WAAWtsB,IAAIujB,WAC7BxiB,OAAO6G,QAAQ5H,KACftO,SAASwyC,QAAQliD;gBAErB0P,UAAU8xC,+BAA+BxjC,IAAIhG;gBAC7CsZ,QAAQqa,yBAAyB3tB,IAAIujB,UAAU/S,UAAUzP;gBACzD/e,SAAS4e,KAAKqL,YAAY3E,IAAItH;gBAC9BqjC,0BAA0BrjC,IAAIhe,QAAQwuB;gBAEtC,IAAIsM,UAAU;oBACV96B,OAAO4e,KAAK9E,OAAOwgB,WAAWQ,YAAY;;gBAG9ConB,SAASH,4BAA4B/hD,QAAQgY,KAAKwW,UAAUnf,MAAM2O;gBAClEgkC,iBAAiBhkC,IAAIhG;gBACrBA,IAAI6mB,KAAKqjB;gBAET,OAAOxyC;;YAGXw1B,YAAY,SAASlnB;gBACjB,IAAIrP,aAAa2iB,QAAQ1M,QAAQ5G,KAC7BtO,SAASsI,KAAKhY,QAAQkiD;gBAE1BlqC,MAAMsZ,QAAQgZ,WAAWtsB;gBACzBsT,QAAQqa,yBAAyB3tB;gBACjCtO,UAAU8xC,+BAA+BxjC,IAAIhG;gBAC7ChY,SAAS4e,KAAKqL,YAAY3E,IAAItH;gBAC9BkkC,SAASH,4BAA4B/hD,QAAQgY,KAAKrJ,YAAYqP;gBAC9DgkC,iBAAiBhkC,IAAIhG;gBACrBA,IAAI6mB,KAAKqjB;gBAET,OAAOxyC;;;QAIflP,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGmoC;YACnBlpC,SAASe,GAAGuG;gBAAQ5G,WAAW;eAAgBye;YAC/C6hB,OAAOjgC,GAAGuG;gBAAQqe,aAAaxG,KAAKsL,cAAc5E;eAAMmb;;QAG5DjgC,GAAG2P,SAAS1N,MAAM,SAAS6N;YACvB;gBACIuxB,gBAAgB,SAAS7jB;oBACrB,IAAIY,KAAK5F,SAASnJ,QAAQwR,UAAU;wBAChC,OAAOwgC,0BAA0B7jC;2BAEhC;wBACD,OAAO1N,OAAOuxB,eAAe7jB,IAAIxd,GAAG+S,KAAKquC,eAAen/C,MAAM;;;;;;ICvOlFjC,GAAGglC,YAAY+b,6BAA6B,SAAS/lC;QACjD;QAEA,IAAIixB,WACA9iB,SAAS,QACTlqB;YACI0qB;gBACIqI,UAAU;gBACVD,UAAU;gBACVyI,iBAAiB;;YAErB3Z,UAAU;YACVze,KAAK,SAASsJ,KAAKvB;WAEvBw3C,eACAC;YACI98B,KAAK,SAAStH;gBACV,OAAOve,QAAQ4hB;;;QAI3B7gB,GAAGuG,OAAOtH,SAAS+b;QAEnBixB,YAAYjsC,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7B;YAC/BI,cAAc;YACdC,gBAAezS;YACfA,QAAQA;YACRO,eAAek4B;YACf7lB,oCAAoC;YACpCpS,MAAM1qB,QAAQ0qB;YACdvnB,KAAKnD,QAAQmD;YACbkrB,YAAY,SAAS9P,IAAIhG,KAAKwS;gBAC1B,IAAI9a,UAAUyyC,SAASnkC;uBAEhBmkC,SAASnkC;gBAEhB,IAAIwM,SAAS;oBACT9a,QAAQK,QAAQiI;uBAEf;oBACDtI,QAAQG,QAAQmI;;;;QAK5BxX,GAAGuG,OAAOtE;YACNq/C,UAAU,SAAS9jC,IAAIhG,KAAKhY,QAAQynB;gBAChC,IAAI/X,UAAU,IAAIlP,GAAGmP;gBAErBlQ,QAAQmD,IAAI,4CAA4Cob;gBAExDmkC,SAASnkC,MAAMtO;gBAEf+8B,UAAUjN,cAAcxhB,IACnB6hB,WAAW7/B,QACXggC,YAAYvY,SACZoX,KAAK7mB;gBAEV,OAAOtI;;;;ICjEnBlP,GAAGyE,cAAc,SAASuW;QACtB;QAEA,IAAI/b,SACA4iD,wBAAwB,gBACxBC,yBAAyB,oBACzBC,sBACAC,mBACA/mC,iBAAiB,IAAIjb,GAAGoV;QAE5BnW;YACIsF;YACA09C,oBAAoB;YACpB51B;gBACI61B,YAAY;;YAEhBvhD,WAAW,IAAIX,GAAGyE,YAAY9D;;QAGlCX,GAAGuG,OAAOtH,SAAS+b,GAAG;QAEtB,SAASmnC,mBAAmBhgC,OAAOigC;YAE/B,IAAIC,eAAehhD,MAAMC,UAAUxB,MAAMyB,KAAK4gB;YAE9CljB,QAAQ0B,UAAU2hD,QAAQ,aAAangC,MAAM/d,SAAS;YACtDg+C,eAAeG,aAAa;YAC5BtjD,QAAQ0B,UAAU6hD,+BAA+BH,cAAcD,eAAeK;;QAGlF,SAASC,iBAAiBpnB;YACtB,IAAIqnB,oBAAoB,IAAI3iD,GAAGmP;YAE/B,IAAImsB,MAAMvvB,QAAQ;gBACduvB,MAAMlZ,KAAK,SAASA;oBAChB,IAAIphB,OAAOs6B,MAAMt6B,MACb4hD,WAAWtnB,MAAMsnB,UACjBC,wBAAwBD,SAASh5C,QAAQ5I;oBAG7C4hD,WAAWA,SAAS5tC,OAAO,GAAG6tC;oBAG9B,IAAID,SAAShjD,OAAO,OAAO,KAAK;wBAC5BgjD,WAAWA,SAAS5tC,OAAO;;oBAG/BoN,KAAK0gC,SAASF;oBACdZ,aAAalgD,KAAKsgB;oBAClBugC,kBAAkBtzC;mBAEtB,SAAS0zC;oBACL9jD,QAAQ0B,UAAU2hD,QAAQ,sBAAsBhnB,MAAMsnB,WAAW,wBAAwBG,UAAU1wB,OAAO,KAAK;oBAC/GswB,kBAAkBpzC;;mBAGrB,IAAI+rB,MAAM0nB,aAAa;gBACxBC,oBAAoB3nB,OAAOrhB,KACvB,SAASipC,eAAe3lC;oBACpB,IAAI4lC,cAAc5lC,QAAQnZ;oBAE1BpE,GAAGY,KAAK2c,SAAS,SAAS3b,KAAK05B;wBAC3BonB,iBAAiBpnB,OAAO5gB,KAAK;4BACzByoC,eAAe;4BAEf,IAAIA,gBAAgB,GAAG;gCACnBR,kBAAkBtzC;;;;oBAK9B,KAAKkO,QAAQnZ,QAAQ;wBACjBu+C,kBAAkBtzC;;mBAI1B,SAAS+zC,YAAYL;oBACjB9jD,QAAQ0B,UAAU2hD,QAAQ,sBAAsBhnB,MAAMsnB,WAAW,wBAAwBG,UAAU1wB,OAAO,KAAK;oBAC/GswB,kBAAkBpzC;;;YAK9B,OAAOozC;;QAIX,SAASM,oBAAoB3nB,OAAO2f,QAAQoI,cAAcC;YACtD,IAAIp0C,UAAUo0C,mBAAmB,IAAItjD,GAAGmP,WACpCo0C,YAAYtI,UAAU3f,MAAMkoB;YAEhCD,UAAUE,YACN,SAASC,YAAYnmC;gBACjB,IAAIomC,aAAaN,eAAeA,aAAalwC,OAAOoK,WAAWA;gBAE/D,IAAIA,QAAQnZ,QAAQ;oBAChBwnB,WAAW;wBACPq3B,oBAAoB3nB,OAAOioB,WAAWI,YAAYz0C;uBACnD;uBAEF;oBACDA,QAAQG,QAAQs0C;;eAIxBz0C,QAAQK;YAGZ,OAAOL;;QAGX,SAAS00C,mBAAmBj2C,cAAcy0C;YACtC,IAAIyB,4BACAC,4BAA4B,IAAI9jD,GAAGmP;YAEvClQ,QAAQ0B,UAAUojD;YAClB3B,eAAeG,aAAa;YAE5B,IAAI50C,aAAawU,MAAM/d,SAAS,MAAMnF,QAAQgjD,oBAAoB;gBAC9DhjD,QAAQ0B,UAAU6hD;gBAClBvjD,QAAQ0B,UAAUqjD,UAAU,qBAAqB;gBACjD5B,eAAeG,aAAa;gBAC5BuB,0BAA0Bv0C;mBAEzB;gBACDyyC;gBAEA,IAAIhiD,GAAG0N,sBAAsBC,eAAe;oBACxC3N,GAAGY,KAAK+M,aAAaC,OAAO,SAAShM,KAAKqJ;wBACtC,IAAIqwB,QAAQrwB,KAAK4C;wBAEjB,IAAIytB,OAAO;4BAEP,IAAIA,MAAMvvB,QAAQ;gCACdi2C,aAAalgD,KAAKmJ,KAAK+zC;mCAGtB;gCACD6E,sBAAsB/hD,KAAK4gD,iBAAiBpnB,OAAO5gB,KAAK;oCACpDmpC,sBAAsBtf;oCACtB,IAAIsf,sBAAsBz/C,WAAW,GAAG;wCACpC0/C,0BAA0Bz0C;;;;;;uBAO7C;oBACD2yC,eAAer0C,aAAawU;;gBAGhC,IAAI0hC,sBAAsBz/C,WAAW,GAAG;oBACpC0/C,0BAA0Bz0C;;;YAIlC,OAAOy0C;;QAGX,SAASG,cAAcC;YACnB,IAAIC,WAAW,IAAInkD,GAAGokD;gBAClBvC,uBAAuBA;gBACvBn/C,SAASwhD;gBACTG,SAAS,SAASjyC;oBACdpS,GAAGkkD,UAAUp9C,SAAS7H,QAAQotB,QAAQ61B;oBACtC9vC,EAAEkyC;;gBAENC,uBAAuB,SAASnyC;oBAC5BpS,GAAGkkD,UAAUn9C,YAAY9H,QAAQotB,QAAQ61B;;gBAE7CsC,QAAQ,SAASpyC;oBACbwxC,mBAAmBxxC,EAAEzE,cAAcw2C,UAAUlqC,KACzC;wBACIkoC,mBAAmBH,cAAcmC;uBAErC;wBACIllD,QAAQ0B,UAAU2hD,QAAQ,uEAAuE;;;;YAMjHrnC,eAAexF,YAAY;gBACvB0uC,SAAS7uC;;YAGbtV,GAAGkkD,UAAUh8C,aAAa45C,2BAA2B9hD,GAAGkkD,UAAUn/C;YAElEg9C,gBAAgBjgD,KAAKqiD;YAErB,OAAOA;;QAGX,SAASM,WAAWC;YAChB,IAAIC;YAEJ3kD,GAAGY,KAAK8jD,UAAU/2C,aAAai3C,OAAO,SAASzkD,KAAKC;gBAChD,IAAIA,QAAQ,SAAS;oBACjBukD,WAAW;oBACX,OAAO;;;YAIf,OAAOA;;QAWX,SAASE,mBAAmBzyC;YACxB,IAAIpS,GAAGuR,WAAW;gBACd,QAAQa,EAAE0yC;;YAGd,IAAI9kD,GAAGmR,UAAU;gBACb,OAAOiB,EAAE6qC,IAAI,KAAK7qC,EAAE2yC,IAAI;;YAG5B,OAAO3yC,EAAE6qC,MAAM,KAAK7qC,EAAE2yC,MAAM;;QAGhC,SAASC;YACL,IAAIC,YAAYhmD,QAAQsF,kBAEpB2gD,qBAAqB;gBACjBt5B,WAAW;oBACP5rB,GAAGY,KAAKqkD,WAAW,SAASrjD,KAAKuiD;wBAC7BnkD,GAAGmkD,UAAUj8C,aAAa45C,2BAA2B9hD,GAAGmkD,UAAUp/C;wBAClE/E,GAAGmkD,UAAUp9C,YAAY9H,QAAQotB,QAAQ61B;;mBAE9C;;YAGXliD,GAAGY,KAAKqkD,WAAW,SAASrjD,KAAKuiD;gBAC7B,IAAI/B,iBAAiB6B,cAAcE;gBAGnC,IAAIc,UAAU7gD,UAAUpE,GAAGgW,kBAAkB8C,UAAU;oBACnDmC,eAAe/V,OAAOgI,UAAU,aAAa,SAASkF;wBAClD,KAAKgwC,eAAeG,kBAAkBkC,WAAWryC,IAAI;4BACjDpS,GAAGY,KAAKqkD,WAAW,SAASrjD,KAAKuiD;gCAG7B,IAAIA,oBAAoBgB,eACpBnlD,GAAGmkD,UAAUj8C,aAAa45C,yBAAyB;oCAEnD9hD,GAAGmkD,UAAUn+C;wCAAKf,SAAS;;;;;;;;YAQnDgW,eAAe/V,OAAOgI,UAAU,aAAa,SAASkF;gBAClD,IAAIyyC,mBAAmBzyC,IAAI;oBACvB8yC;;;YAORjqC,eAAe/V,OAAOlF,GAAGkN,UAAUzF,WAAW,IAAI,cAAc,SAAS2K;gBACrE8yC;;YAGJjqC,eAAe/V,OAAOgI,UAAU,QAAQ,SAASkF;gBAC7CA,EAAED;gBACF+yC;;YAGJjqC,eAAe/V,OAAOgI,UAAU20C,uBAAuBqD;;QAG3DF;QAEAhlD,GAAGuG,OAAOtE;YACNmjD,oBAAoB,SAAS1iD;gBACzBzD,QAAQsF,iBAAiBzC,KAAKY;gBAC9BuhD,cAAcvhD;;YAGlB2iD,gBAAgB,SAAS3iD;gBACrB,IAAIkR,GACA0xC,MAAMrmD,QAAQsF;gBAElB,KAAKqP,KAAK0xC,KAAK;oBACX,IAAIA,IAAI1xC,OAAOlR,SAAS;wBACpB,OAAO4iD,IAAIrmC,OAAOrL,GAAG;;;;YAKjC0B,SAAS;gBACL2F,eAAe3F;gBACftV,GAAGY,KAAKmhD,iBAAiB,SAASngD,KAAKuiD;oBACnCA,SAAS7uC;;;;;IAMzBtV,GAAGyE,YAAY9D,YAAY;QACvB;QAEA;YACIojD,wBAAwB;YACxBvB,gCAAgC,SAASrgC,OAAOojC;YAChDvB,WAAW,SAAS3xB,MAAMmzB;gBACtBxlD,GAAGoC,IAAI,6BAA6BiwB,OAAO,6BAA6BmzB,iBAAiB,KAAK;;YAElGlD,SAAS,SAASjgD,SAAS8H;gBACvBnK,GAAGoC,IAAIC,SAAS8H;;;;IAK5BnK,GAAGokD,iBAAiB,SAASppC;QACzB;QAEA,IAAIC,iBAAiB,IAAIjb,GAAGoV,kBACxBnW,SAASyD,SAAS+iD,aAAaC;QAEnCzmD;YACIyD,SAAS;YACT2hD,SAAS,SAASjyC;YAClBskB,SAAS,SAAStkB;YAElBmyC,uBAAuB,SAASnyC;YAChCoyC,QAAQ,SAASpyC;;QAGrBpS,GAAGuG,OAAOtH,SAAS+b;QACnBtY,UAAUzD,QAAQyD;QAElB,SAASijD;YACL,OAAO3lD,GAAGmR,YAAanR,GAAGuR,aAAavR,GAAGwR;;QAG9C,SAASo0C,mBAAmBxzC;YAExB,KAAKszC,qBAAqB;gBAGtB,IAAIC,0BAA0B;oBAC1B1qC,eAAe/V,OAAOgI,UAAU,YAAY,SAASkF;wBACjDA,EAAED;;uBAEH;oBACH8I,eAAe/V,OAAOgI,UAAU,YAAY,SAASkF;wBACjD,IAAIA,EAAEzE,cAAc;4BAChByE,EAAEzE,aAAak4C,aAAa;4BAC5BzzC,EAAED;;;;gBAKduzC,sBAAsB;;;QAI9B,SAASI,gBAAgB1zC;YAGrB,KAAKpS,GAAGgW,kBAAkB8C,UAAU;gBAChC,OAAO;;YAGX,IAAIitC,YAAYC,KAAK5zC,EAAEzE,cAEvBs4C,WAAWjmD,GAAGmR;YAOd40C,aAAa/lD,GAAG2Q,QAAQ3Q,GAAGgW,kBAAkB8C,WAAW,OAAOktC,GAAGE,kBAAkB;YACpF,OAAOF,MAAMD,eAAeC,GAAG7jC,UAAW8jC,YAAYD,GAAGpB,MAAMp/C,YAAYwgD,GAAGpB,MAAMp/C,SAAS;;QAGjG,SAAS2gD,oBAAoBC;YACzB,IAAIA,eAAe9lD,WAAW;gBAC1BmlD,cAAcW;;YAElB,OAAOX;;QAGX,SAASY;YACL,IAAIC;YAEJ,SAASC;gBACLD,iBAAiBp5C,SAASs5C,YAAY;gBACtCF,eAAeG,UAAUxnD,QAAQ4iD,uBAAuB,MAAM;;YAGlE,IAAI54C,OAAOy9C,aAAa;gBACpB;oBACIJ,iBAAiB,IAAII,YAAYznD,QAAQ4iD;kBAE7C,OAAOjK;oBACH2O;;mBAGH;gBACDA;;YAGJr5C,SAASy5C,cAAcL;;QAG3B,SAASM;YACL3rC,eAAe/V,OAAOxC,SAAS,YAAY,SAAS0P;gBAChD,KAAK0zC,gBAAgB1zC,IAAI;oBACrB;;gBAKJ,IAAIy0C,SAAS7mD,GAAG2Q,QAAQ3Q,GAAGgW,kBAAkB8C,WAAW,OAAO1G,EAAEzE,aAAau4C;gBAC9E,IAAIW,WAAW,UAAUA,WAAW,YAAY;oBAC5Cz0C,EAAEzE,aAAak4C,aAAa;uBACzB;oBACHzzC,EAAEzE,aAAak4C,aAAa;;gBAGhCzzC,EAAEkyC;gBACFlyC,EAAED;;YAGN8I,eAAe/V,OAAOxC,SAAS,aAAa,SAAS0P;gBACjD,KAAK+zC,uBAAuB;oBACxB,KAAKL,gBAAgB1zC,IAAI;wBACrB;;oBAEJnT,QAAQolD,QAAQjyC;;;YAIxB6I,eAAe/V,OAAOxC,SAAS,aAAa,SAAS0P;gBACjD,KAAK0zC,gBAAgB1zC,IAAI;oBACrB;;gBAGJnT,QAAQy3B,QAAQtkB;gBAEhB,IAAI0yC,gBAAgB53C,SAAS45C,iBAAiB10C,EAAE20C,SAAS30C,EAAE40C;gBAE3D,IAAIhnD,GAAGiC,MAAMuD,SAASs/C,gBAAgB;oBAClC;;gBAGJ7lD,QAAQslD,sBAAsBnyC;;YAGlC6I,eAAe/V,OAAOxC,SAAS,QAAQ,SAAS0P;gBAC5C,KAAK+zC,uBAAuB;oBACxB,KAAKL,gBAAgB1zC,IAAI;wBACrB;;oBAGJA,EAAED;oBACFC,EAAEkyC;oBACFrlD,QAAQulD,OAAOpyC;oBAEfi0C;;;;QAKZT;QACAgB;QAEA5mD,GAAGuG,OAAOtE;YACNsgD,cAAc,SAAS6D;gBACnB,OAAOD,oBAAoBC;;YAG/B9wC,SAAS;gBACL2F,eAAe3F;;YAGnBmtC,YAAY;gBACR,OAAO//C;;;;KCvelB;QACG;QAEA1C,GAAGinD;YACClmC,iBAAiB,SAASC;gBACtB/e,KAAKilD,QAAQ5lD,UAAUyf,gBAAgB/e,MAAMC,MAAMT;gBACnDS,KAAKklD,YAAYC;;YAGrBvkC,kBAAkB;gBACd5gB,KAAKilD,QAAQ5lD,UAAUuhB,iBAAiB7gB,MAAMC,MAAMT;gBACpDS,KAAKklD,YAAYE;;YAGrBC,kBAAkB,SAAS5kD;gBACvBT,KAAKslD,QAAQtlD,KAAKslD,KAAKnC,mBAAmB1iD;;YAG9C8kD,qBAAqB,SAAS9kD;gBAC1B,IAAIT,KAAKslD,MAAM;oBACX,OAAOtlD,KAAKslD,KAAKlC,eAAe3iD;;;YAIxC+kD,iBAAiB,SAASjqC;gBACtB,KAAKvb,KAAKklD,YAAYO,gBAAgBlqC,KAAK;oBACvC,OAAOvb,KAAKklD,YAAYQ,iBAAiBnqC;;;YAIjDV,OAAO;gBACH7a,KAAKilD,QAAQ5lD,UAAUwb,MAAM9a,MAAMC,MAAMT;gBACzCS,KAAKklD,YAAYrqC;gBAEjB,KAAK7a,KAAKpB,SAASqlB,UAAUjkB,KAAKklD,YAAY1iC,aAAa;oBACvDxiB,KAAKwtB,mBAAmBxtB,KAAK4pB;wBACzBnpB,SAAST,KAAKklD,YAAY1iC;wBAC1BjJ,OAAOvZ,KAAKpB,SAASiH,KAAK6kB;uBAC3BlQ;;gBAGP,IAAIxa,KAAKslD,MAAM;oBACXtlD,KAAKslD,KAAKjyC;oBACVrT,KAAKslD,OAAOtlD,KAAK2lD;;gBAGrB3lD,KAAK4lD,qBAAqB;gBAC1B5lD,KAAK6lD,yBAAyB;gBAE9B7lD,KAAK8lD;;YAGT//B,SAAS,SAASxK,IAAI8B;gBAClB,IAAI0oC,oBAAoB/lD,KAAKpB,SAASiyB,eAAexT;gBAErDrd,KAAKilD,QAAQ5lD,UAAU0mB,QAAQhmB,MAAMC,MAAMT;gBAC3CS,KAAKklD,YAAYc,eAAezqC,IAAIwqC;;YAGxCniC,aAAa,SAASrI;gBAClB,IAAIisB,SAASxnC,KAAKilD,QAAQ5lD,UAAUukB,YAAY7jB,MAAMC,MAAMT;gBAE5DioC,UAAUxnC,KAAKklD,YAAYe,aAAa1qC;gBACxC,OAAOisB;;YAGX3mB,gBAAgB,SAAStF;gBACrB,IAAI2qC,YAAYlmD,KAAKilD,QAAQ5lD,UAAUwhB,eAAe9gB,MAAMC,MAAMT;gBAElE2mD,aAAalmD,KAAKklD,YAAYiB,gBAAgB5qC;gBAC9C,OAAO2qC;;YAGXE,OAAO,SAASC;gBACZ,OAAOrmD,KAAKklD,YAAYoB,UAAUD;;YAGtCE,eAAe,SAAS9kC;gBACpB,IAAItB,OAAOngB,KAAKmiB,QAAQV;gBAExB,OAAOtB,KAAKqmC;;;QAOpBzoD,GAAG0oD;YACChkC,YAAY,SAASjJ;gBACjB,IAAIyK,SAASjkB,KAAKilD,QAAQ5lD,UAAUojB,WAAW1iB,MAAMC,MAAMT;gBAE3D,KAAK0kB,QAAQ;oBACT,IAAIzK,aAAaxZ,KAAKwtB,kBAAkB;wBACpCvJ,SAASjkB,KAAKklD,YAAY1iC;;;gBAIlC,OAAOyB;;YAGXyiC,iBAAiB,SAASjlC;gBACtBzhB,KAAKklD,YAAYyB,WAAWllC;;YAGhCqkC,iCAAiC;gBAC7B9lD,KAAK4mD,2BAA2B7oD,GAAG8oD,2BAA2B7mD,KAAK8mD;gBAInE9mD,KAAK+mD,0BAA0BhpD,GAAGuR;gBAElC,IAAItP,KAAKgnD,0BACT;oBACIhnD,KAAKinD,wBAAwBjnD,KAAKknD;oBAClClnD,KAAKmnD,+BAA+BnnD,KAAKonD;oBACzCpnD,KAAKqnD,6BAA6BrnD,KAAKsnD;;;YAI/C3B,mBAAmB;gBACf,IAAI7jD,OAAO9B,MACPsC,mBAAmBtC,KAAKpB,SAAS2oD,YAAYC,gBAC7CC,aAAaznD,KAAKklD,aAClBwC,kBAAkBD,WAAWE;gBAEjCD,mBAAmBplD,iBAAiBzC,KAAK6nD;gBAEzC,OAAO,IAAI3pD,GAAGyE;oBACVF,kBAAkBA;oBAClB09C,oBAAoBhgD,KAAKpB,SAASuM;oBAClCif;wBACI61B,YAAYjgD,KAAKpB,SAASwrB,QAAQ61B;;oBAEtCvhD;wBACIojD,wBAAwB;4BACpB2F,WAAWG;;wBAEfrH,gCAAgC,SAASrgC,OAAOojC;4BAC5CmE,WAAWI;4BAEX9pD,GAAGY,KAAKuhB,OAAO,SAASvgB,KAAKwgB;gCACzBA,KAAKqmC,eAAelD;;4BAGxB,IAAIpjC,MAAM/d,QAAQ;gCACdL,KAAK+c,SAASqB,OAAO,MAAM;;;wBAGnC6hC,WAAW,SAAS3xB,MAAM03B;4BACtBhmD,KAAKqkB,WAAWiK,MAAM03B;;wBAE1BzH,SAAS,SAASjgD,SAAS8H;4BACvBpG,KAAK3B,IAAIC,SAAS8H;;;;;YAMlC4+C,4BAA4B;gBACxB,IAAIhlD,OAAO9B;gBAEX,OAAO,IAAIjC,GAAG8oD;oBACVY,YAAYznD,KAAKklD;oBAEjB/kD,KAAK,SAASC,SAAS2nD;wBACnBjmD,KAAK3B,IAAIC,SAAS2nD;;oBAGtBC,cAAc,SAASvmC;wBACnB3f,KAAKqf,WAAWM;;oBAGpB8J,UAAU,SAAS9J;wBACf3f,KAAKye,OAAOkB;;oBAGhBwmC,SAAS,SAASxmC;wBACd3f,KAAK4iB,MAAMjD;;oBAGfymC,SAAS,SAASzmC;wBACd3f,KAAK8hB,YAAYnC;;oBAGrB0mC,YAAY,SAAS1mC;wBACjB3f,KAAK+e,eAAeY;;oBAGxB2mC,WAAW,SAAS3mC;wBAChB,OAAO3f,KAAKmf,QAAQQ;;;;YAKhCulC,wBAAwB;gBAEpB,OAAOhnD,KAAKklD,YAAYmD,6BAChBroD,KAAKpB,SAAS8wB,cACf3xB,GAAGuqD,wBACHvqD,GAAGwqD,6BACHxqD,GAAGwqD;;YAGdC,sBAAsB;gBAClB,IAAI1mD,OAAO9B,MACPynD,aAAaznD,KAAKklD;gBAEtB;oBACIuC,YAAYA;oBACZtnD,KAAK,SAASC,SAAS2nD;wBACnBjmD,KAAK3B,IAAIC,SAAS2nD;;oBAEtBU,mBAAmB,SAAShnC;wBACxB,OAAO3f,KAAKmhB;4BAAY1H,IAAIkG;2BAAS7F;;oBAEzCwsC,WAAW,SAAS3mC;wBAChB,OAAO3f,KAAKmf,QAAQQ;;oBAExBinC,WAAW,SAASntC,IAAI8B;wBACpBvb,KAAKikB,QAAQxK,IAAI8B;;oBAErBsrC,uBAAuB,SAASptC,IAAIqtC;wBAChC,IAAIC,UAAU9qD,GAAG0pD,WAAWqB,aAAavtC,MACrCwtC,kBAAkBhrD,GAAG0pD,WAAW/B,iBAAiBnqC;wBAErD,IAAIqtC,WAAW;4BACXC,QAAQhkD,SAAS;4BACjB4iD,WAAWuB,aAAaztC;4BACxBksC,WAAWwB,aAAa1tC;+BAEvB;4BACDstC,QAAQ/jD,YAAY;4BACpB2iD,WAAWyB,aAAa3tC;4BACxBksC,WAAW0B,aAAa5tC;;wBAI5BwtC,gBAAgBlkD,SAAS,WAAWC,YAAY;;;;YAK5D2kB,uBAAuB,SAASlO,IAAIuB,WAAWD;gBAC3C7c,KAAKilD,QAAQ5lD,UAAUoqB,sBAAsB1pB,MAAMC,MAAMT;gBAEzD,IAAIS,KAAKgnD,0BAA0B;oBAE/B,IAAIhnD,KAAKklD,YAAYQ,iBAAiBnqC,OAAOsB,cAAc9e,GAAG6d,OAAOiC,WAAW;wBAC5E7d,KAAKklD,YAAYkE,qBAAqB7tC;wBACtCvb,KAAKklD,YAAY+D,aAAa1tC;;;gBAItC,IAAIuB,cAAc/e,GAAG6d,OAAOuC,mBAAmBtB,cAAc9e,GAAG6d,OAAOsC,WAAW;oBAC9Ele,KAAKklD,YAAYmE,UAAU9tC;oBAC3Bvb,KAAKklD,YAAYoE,cAAc/tC;oBAC/Bxd,GAAGiC,KAAKklD,YAAYQ,iBAAiBnqC,KAAKzW,YAAY9E,KAAKupD,SAASC;uBAEnE,IAAI3sC,cAAc9e,GAAG6d,OAAOyC,eAAe;oBAC5Cre,KAAKklD,YAAYuE,UAAUluC;;;YAInC6rC,gCAAgC;gBAC5B,IAAIjrC,OAAOpe,GAAGuG,WAAWtE,KAAKwoD;gBAE9B,OAAO,IAAIzqD,GAAG2rD,4BAA4BvtC;;YAG9CmrC,8BAA8B;gBAC1B,IAAInrC,OAAOpe,GAAGuG,WAAWtE,KAAKwoD;gBAE9B,OAAO,IAAIzqD,GAAGwqD,0BAA0BpsC;;YAG5C+qC,yBAAyB;gBACrB,IAAI/qC,OAAOpe,GAAGuG,WAAWtE,KAAKwoD;gBAE9B,OAAO,IAAIzqD,GAAGuqD,qBAAqBnsC;;YAGvCiX,gBAAgB,SAAS7X;gBACrBvb,KAAKilD,QAAQ5lD,UAAU+zB,eAAerzB,MAAMC,MAAMT;gBAClDS,KAAKklD,YAAYyE,YAAYpuC;;YAGjC4V,gBAAgB,SAASe,YAAYC;gBACjCnyB,KAAKilD,QAAQ5lD,UAAU8xB,eAAepxB,MAAMC,MAAMT;gBAClDS,KAAKklD,YAAY0E;;YAGrB52B,WAAW,SAASzX,IAAIxc;gBACpB,IAAIohB,OAAOngB,KAAKmiB,QAAQ5G;gBAExB,IAAI4E,QAAQA,KAAK0gC,UAAU7gD,KAAKpB,SAAS2oD,YAAYsC,sBAAsB;oBACvE7pD,KAAKkkB,aAAaqF,YAAYhO;wBAC1BuuC,QAAQ3pC,KAAK0gC;;;gBAIrB7gD,KAAKilD,QAAQ5lD,UAAU2zB,UAAUjzB,MAAMC,MAAMT;gBAC7CS,KAAK+pD,WAAWxuC,IAAIxc;;YAIxBm0B,cAAc,SAAS3X;gBAEnB,IAAIvb,KAAKgnD,0BAA0B;oBAC/BhnD,KAAKklD,YAAYkE,qBAAqB7tC;oBACtCvb,KAAKklD,YAAYiE,aAAa5tC;oBAG9B,KAAKvb,KAAK+mD,wBAAwB;wBAC9B/mD,KAAKqnD,2BAA2B2C,WAAWhqD,KAAKklD,YAAY4D,aAAavtC;;;;YAMrF6P,aAAa,SAAS7P,IAAIxc,MAAMmsB,QAAQC;gBACpCnrB,KAAKilD,QAAQ5lD,UAAU+rB,YAAYrrB,MAAMC,MAAMT;gBAE/CS,KAAKklD,YAAY+E,eAAe1uC,IAAI2P,QAAQC;gBAE5C,IAAIA,UAAU,KAAK/mB,KAAKC,MAAM6mB,SAASC,QAAQ,SAAS,KAAK;oBACzDnrB,KAAKklD,YAAYgF,WAAW3uC;oBAC5Bvb,KAAKklD,YAAYuE,UAAUluC;oBAC3Bvb,KAAKklD,YAAYiF,aAAa5uC;oBAC9Bvb,KAAKklD,YAAYoE,cAAc/tC,IAAIvb,KAAKpB,SAASiH,KAAKukD;oBAGtDpqD,KAAKqqD,iBAAiB9uC;uBAErB;oBAEDvb,KAAKqqD,iBAAiB9uC,IAAI2P,QAAQC;;;YAI1CwI,kBAAkB,SAASzI,QAAQC;gBAC/BnrB,KAAKilD,QAAQ5lD,UAAUs0B,iBAAiB5zB,MAAMC,MAAMT;gBACpDS,KAAKklD,YAAY7I,oBAAoBnxB,QAAQC;;YAGjDG,aAAa,SAAS/P,IAAIxc,MAAMoG,QAAQoQ;gBACpC,IAAI+0C,eAAetqD,KAAKilD,QAAQ5lD,UAAUisB,YAAYvrB,MAAMC,MAAMT,YAC9DkoD,aAAaznD,KAAKklD,aAClB7kC,gBAAgBonC,WAAW/B,iBAAiBnqC,KAC5CzZ,OAAO9B;gBAEX,SAASuqD,eAAeplD;oBAGpB,KAAKkb,eAAe;wBAChB;;oBAGJonC,WAAW6B,cAAc/tC;oBAEzBxd,GAAGsiB,eAAevb,YAAYhD,KAAKynD,SAASC;oBAC5C/B,WAAW0C,aAAa5uC;oBAExB,IAAIzZ,KAAKmhB;wBAAY1H,IAAIA;uBAAKK,WAAW7d,GAAG6d,OAAOyC,eAAe;wBAC9DopC,WAAWyC,WAAW3uC;;oBAE1BksC,WAAWkC,YAAYpuC;oBAEvB,IAAIpW,OAAOiI,SAAS;wBAChBtL,KAAK0oD,sBAAsBjvC;2BAE1B;wBACDxd,GAAGsiB,eAAexb,SAAS/C,KAAKynD,SAASkB;wBACzChD,WAAWiD,WAAWnvC;wBAEtB,IAAIksC,WAAWkD,sBAAsB7oD,KAAKiiB,gBAAgBxI,KAAK;4BAC3Dxd,GAAGsiB,eAAexb,SAAS/C,KAAKynD,SAASrN;4BACzCuL,WAAWmD,UAAUrvC;;wBAEzBzZ,KAAK+oD,2BAA2BtvC,IAAIpW;;;gBAK5C,IAAImlD,wBAAwBvsD,GAAGmP,SAAS;oBACpCo9C,aAAa7xC,KAAK,SAASqyC;wBACvBP,eAAeO;;uBAIlB;oBACDP,eAAeplD;;gBAGnB,OAAOmlD;;YAGXE,uBAAuB,SAASjvC;gBAC5B,IAAIksC,aAAaznD,KAAKklD;gBAEtB,IAAIllD,KAAK6vB,qBAAqB;oBAC1B43B,WAAWsD,iBAAiBxvC;;gBAGhCxd,GAAG0pD,WAAW/B,iBAAiBnqC,KAAK1W,SAAS7E,KAAKupD,SAASn8C;gBAE3DpN,KAAKgrD,sBAAsBzvC;;YAG/BoQ,eAAe,SAASpQ;gBACpBvb,KAAKilD,QAAQ5lD,UAAUssB,cAAc5rB,MAAMC,MAAMT;gBACjDS,KAAKklD,YAAY+F,YAAY1vC;;YAGjCsQ,WAAW,SAAStQ,IAAIxc;gBACpB,IAAIurD,eAAetqD,KAAKilD,QAAQ5lD,UAAUwsB,UAAU9rB,MAAMC,MAAMT;gBAEhES,KAAKklD,YAAY+F,YAAY1vC;gBAE7B,OAAO+uC;;YAGXt+B,gBAAgB,SAASzQ,IAAIwQ;gBACzB/rB,KAAKilD,QAAQ5lD,UAAU2sB,eAAejsB,MAAMC,MAAMT;gBAIlD,IAAIwsB,UAAU+L,YAAY,KAAK93B,KAAKwgB,SAASyjB,YAAY1oB,KAAK;oBAC1Dvb,KAAKklD,YAAYgG,WAAW3vC;;;YAIpCkQ,WAAW,SAASlQ,IAAIxc;gBACpBiB,KAAKilD,QAAQ5lD,UAAUosB,UAAU1rB,MAAMC,MAAMT;gBAC7CS,KAAK0mD,gBAAgBnrC;gBAErB,IAAIvb,KAAK6tB,sBAAsB,GAAG;oBAC9B7tB,KAAKklD,YAAY0E;;;YAIzBp3B,oBAAoB,SAASjX;gBACzB,IAAI4vC,oBAAoBC,SAASC;gBAEjCrrD,KAAKilD,QAAQ5lD,UAAUmzB,mBAAmBzyB,MAAMC,MAAMT;gBAEtDS,KAAKsrD,gBAAgB/vC;gBAErB,IAAIvb,KAAKpB,SAAS8lB,MAAM6mC,mBAAmB;oBACvCJ,qBAAqBnrD,KAAK6jB,aAAatI;oBACvC6vC,UAAUprD,KAAKpB,SAAS8lB,MAAMwQ;oBAE9Bm2B,YAAYrrD,KAAKpB,SAAS8lB,MAAM8mC,cAAczmD,QAAQ,iBAAiBomD;oBACvEE,YAAYA,UAAUtmD,QAAQ,gBAAgBqmD;oBAE9CprD,KAAKklD,YAAYoE,cAAc/tC,IAAI8vC;oBACnCttD,GAAGiC,KAAKklD,YAAYQ,iBAAiBnqC,KAAK1W,SAAS7E,KAAKupD,SAASC;;;YAKzEv4B,sBAAsB,SAAS1V;gBAC3B,IAAIvb,KAAKilD,QAAQ5lD,UAAU4xB,qBAAqBlxB,MAAMC,MAAMT,YAAY;oBACpES,KAAKklD,YAAYuG,cAAclwC;oBAC/Bxd,GAAGiC,KAAKklD,YAAYQ,iBAAiBnqC,KAAKzW,YAAY9E,KAAKupD,SAASkB;oBACpEzqD,KAAKklD,YAAYoE,cAAc/tC;oBAC/Bvb,KAAKklD,YAAY+F,YAAY1vC;oBAC7Bvb,KAAKsrD,gBAAgB/vC;oBACrB,OAAO;uBAEN;oBACDxd,GAAGiC,KAAKklD,YAAYQ,iBAAiBnqC,KAAK1W,SAAS7E,KAAKupD,SAASrN;oBACjEl8C,KAAKklD,YAAY0F,UAAUrvC;oBAC3B,OAAO;;;YAIf6F,iBAAiB,SAAS7F;gBACtB,IAAI8X,oBAAoBt1B,GAAG+S,KAAK9Q,KAAK0rD,wBAAwB1rD;gBAE7DA,KAAKilD,QAAQ5lD,UAAU+hB,gBAAgB9hB,KAAKU,MAAMub,IAAI8X;;YAG1Dq4B,wBAAwB,SAASnwC,IAAIG,MAAM4X;gBACvC,IAAItzB,KAAKpB,SAASuiB,WAAWwqC,cAAc;oBACvC3rD,KAAK4rD,mBAAmB7rD,MAAMC,MAAMT;uBAEnC;oBACDS,KAAK6rD,mBAAmB9rD,MAAMC,MAAMT;;;YAI5CyoB,mBAAmB,SAASzM,IAAIhG,KAAKwS;gBACjC/nB,KAAKilD,QAAQ5lD,UAAU2oB,kBAAkBjoB,MAAMC,MAAMT;gBAErDS,KAAKklD,YAAYyE,YAAYpuC;gBAE7B,IAAIwM,SAAS;oBACT/nB,KAAKklD,YAAYoE,cAAc/tC,IAAIvb,KAAKpB,SAASuiB,WAAW2qC;oBAC5D9rD,KAAKklD,YAAY6F,iBAAiBxvC;uBAEjC;oBACDvb,KAAK0mD,gBAAgBnrC;;;YAI7BswC,oBAAoB,SAAStwC,IAAIG,MAAM4X;gBACnCtzB,KAAKklD,YAAY6G,iBAAiBxwC;gBAClCvb,KAAKklD,YAAY+F,YAAY1vC;gBAC7Bvb,KAAKklD,YAAYoE,cAAc/tC,IAAIvb,KAAKpB,SAASuiB,WAAW6qC;gBAC5DhsD,KAAKyzB,eAAeC,WAAW3zB,MAAMC,MAAMT;;YAG/CqsD,oBAAoB,SAASrwC,IAAIG,MAAMme;gBAEnC,IAAI3mB,WAAWlT,KAAKihB,QAAQ1F,KACxB0wC,iBAAiBjsD,KAAKpB,SAASuiB,WAAW8qC,eAAelnD,QAAQ,iBAAiBmO,WAClFwI,OAAO1b,KAAK0jB,QAAQnI,KACpB2wC,oBAAoB3sD,WACpBuC,OAAO9B,MACPuB;gBAEJA,SAASvB,KAAKpB,SAASutD,YAAYF;gBAEnC,IAAIluD,GAAG+Z,iBAAiBvW,SAAS;oBAC7BA,OAAOyW,KAAK;wBACRlW,KAAK+pD,mBAAmB9rD,MAAM+B,MAAMoqD;;uBAGvC,IAAI3qD,WAAW,OAAO;oBACvBO,KAAK+pD,mBAAmB9rD,MAAM+B,MAAMoqD;;;YAI5CnC,YAAY,SAASxuC,IAAIxc,MAAMqtD;gBAC3B,IAAIC,aACAC,eAAe,GACfC,cAAcvsD,KAAKwgB,SAASwjB,UAAUzoB,OAAOvb,KAAKpB,SAAS0Y,QAAQk1C,YACnElV;gBAEJ,IAAIt3C,KAAKpB,SAASoE,QAAQypD,cAAc;oBACpC,IAAIzsD,KAAK4lD,qBAAqB,KAAK5lD,KAAK6lD,yBAAyB,GAAG;wBAChEyG,eAAetsD,KAAK6lD,yBAAyB;;oBAGjDwG;wBACIpqD,OAAOqqD;;;gBAIf,KAAKF,QAAQ;oBACT,IAAIpsD,KAAKpB,SAASw3B,gCAAgCr4B,GAAGgW,kBAAkBqC,eAAe;wBAClFpW,KAAKklD,YAAYwH;;oBAMrB,KAAK1sD,KAAKpB,SAASuM,UAAU;wBACzBmsC,SAASt3C,KAAKijB;4BAAY1H,IAAIA;;wBAE9Bvb,KAAK2sD,qBAAqB3sD,KAAK2sD,sBAAsBrV,OAAO96B;wBAE5D,IAAI86B,OAAO96B,iBAAiBxc,KAAK2sD,uBAAuBrV,OAAO96B,cAAc;4BACzExc,KAAKwgB,SAASC;4BACdzgB,KAAK4sD;4BACL5sD,KAAK2sD,qBAAqB;;;;gBAKtC,IAAIP,QAAQ;oBACRpsD,KAAKklD,YAAY2H,eAAetxC,IAAIvb,KAAKpB,SAASiyB,eAAe9xB,OAAOstD,aAAaE;oBACrFvsD,KAAKklD,YAAY4H,gBAAgBvxC,IAAIvb,KAAKiiB,eAAe1G,KAAK,MAAMvb,KAAKpB,SAASmuD,WAAWt0B;uBAE5F;oBACDz4B,KAAKklD,YAAYhpC,QAAQX,IAAIvb,KAAKpB,SAASiyB,eAAe9xB,OAAOstD,aAAaE;oBAC9EvsD,KAAKklD,YAAY8H,gBAAgBzxC,IAAIvb,KAAKmiB,QAAQ5G,KAAKvb,KAAKpB,SAASmuD,WAAWt0B;;gBAGpFz4B,KAAK6lD,0BAA0B;gBAE/B,IAAIuG,UACCpsD,KAAKpB,SAASoE,QAAQiqD,oBAAoBlvD,GAAGgW,kBAAkBqC,eAAgB;oBAEhFpW,KAAKqqD,iBAAiB9uC;;;YAI9BqxC,YAAY;gBACR5sD,KAAKklD,YAAYE;gBACjBplD,KAAK4gB;;YAGTypC,kBAAkB,SAAS9uC,IAAI2xC,YAAYrR;gBACvC,IAAIv/B,OAAOtc,KAAKmjB,QAAQ5H,KACpB4xC,iBAAiBntD,KAAK6sB,YAAYvQ;gBAEtC,IAAIA,QAAQ,GAAG;oBACX,IAAI4wC,eAAe7uD,aAAaw9C,cAAcx9C,WAAW;wBACrD8uD,iBAAiBntD,KAAKotD,gBAAgBF,YAAYrR;;oBAGtD77C,KAAKklD,YAAY5nC,WAAW/B,IAAI4xC;;;YAIxCC,iBAAiB,SAASC,cAAcxR;gBACpC,IAAIz7C,UAAUJ,KAAKpB,SAASiH,KAAKynD;gBACjC,SAAS/+C,EAAExP,MAAM4xB;oBAAevwB,UAAUA,QAAQ2E,QAAQhG,MAAM4xB;;gBAEhEpiB,EAAE,aAAanK,KAAKC,MAAMgpD,eAAexR,YAAY;gBACrDttC,EAAE,gBAAgBvO,KAAK6sB,YAAYgvB;gBACnC,OAAOz7C;;YAGXyqD,4BAA4B,SAAStvC,IAAIiW;gBACrC,IAAI+7B,MAAMC,kBAAkBC;gBAE5BF,OAAOvtD,KAAKpB,SAAS8uD,wBAAwBH;gBAC7CC,mBAAmBxtD,KAAKpB,SAAS8uD,wBAAwBF;gBAEzD,IAAID,SAAS,UAAU;oBACnBE,gBAAgBj8B,SAASg8B;oBACzB,KAAKC,eAAe;wBAChBA,gBAAgBztD,KAAKpB,SAASiH,KAAK8nD;;oBAGvC3tD,KAAKklD,YAAYoE,cAAc/tC,IAAIkyC;oBAEnC,IAAIztD,KAAKpB,SAAS8uD,wBAAwBE,eAAe;wBACrD5tD,KAAK6tD,aAAatyC,IAAIkyC;;uBAGzB,IAAIF,SAAS,WAAW;oBACzBvtD,KAAKklD,YAAYoE,cAAc/tC,IAAIvb,KAAKpB,SAASiH,KAAK8nD;uBAErD,IAAIJ,SAAS,QAAQ;oBACtBvtD,KAAKG,IAAI,4CAA4CotD,OAAO,kBAAkB;;;YAItFM,cAAc,SAAStyC,IAAI1V;gBACvB7F,KAAKklD,YAAYQ,iBAAiBnqC,IAAIhC,QAAQ1T;;YAGlDylD,iBAAiB,SAAS/vC;gBACtB,KAAKvb,KAAKpB,SAASw3B,+BAA+Br4B,GAAGgW,kBAAkBqC,eAAe;oBAClFpW,KAAKklD,YAAYwF,WAAWnvC;;;YAIpC4K,YAAY,SAASiK,MAAMrxB,MAAMiK;gBAC7B,IAAI5I,UAAUJ,KAAKilD,QAAQ5lD,UAAU8mB,WAAWpmB,MAAMC,MAAMT;gBAC5DS,KAAKpB,SAASkvD,YAAY1tD;;YAG9B0mB,aAAa,SAAS1mB;gBAClBJ,KAAKilD,QAAQ5lD,UAAUynB,YAAY/mB,MAAMC,MAAMT;gBAC/CS,KAAKpB,SAASkvD,YAAY1tD;;YAG9B2tD,mBAAmB;gBACf,IAAIjsD,OAAO9B;gBAEXA,KAAKpB,SAASF,UAAU6pB,kBAAkB;oBACtC,IAAInoB,UAAU0B,KAAKlD,SAASwpB,MAAM4lC,mBAC9BC,aAAansD,KAAKlD,SAASwpB,MAAM5I;oBAErC,OAAO1d,KAAKlD,SAASsvD,WAAW9tD,SAAS6tD;;;YAIjDrhC,qBAAqB,SAASrR,IAAIxc;gBAC9BiB,KAAK4lD,sBAAsB;gBAC3B5lD,KAAKilD,QAAQ5lD,UAAUutB,oBAAoB7sB,MAAMC,MAAMT;;YAG3D+gB,wBAAwB,SAAS3U,OAAOpO,QAAQqhB;gBAC5C5e,KAAK4lD,qBAAqBj6C,MAAMxJ;gBAChCnC,KAAK6lD,yBAAyB;gBAC9B7lD,KAAKilD,QAAQ5lD,UAAUihB,uBAAuBvgB,MAAMC,MAAMT;;YAG9DyrD,uBAAuB,SAASvpC;gBAC5B,IAAIgF,eAAezmB,KAAKiiB,eAAeR,SACnC0sC,aAAanuD,KAAKijB;oBAAY1H,IAAIkG;mBAAS7F;gBAE/C,IAAIuyC,eAAepwD,GAAG6d,OAAO4C,YACxBiI,gBACDzmB,KAAKpB,SAASmuD,WAAWqB,aAAaC,sBACrCtwD,GAAGgW,kBAAkBiD,gBAAgB;oBAItChX,KAAKklD,YAAY4H,gBAAgBrrC,QAAQgF,cAAczmB,KAAKpB,SAASmuD,WAAWt0B;;;YAIxFxZ,gBAAgB,SAASqH;gBACrB,IAAI/K,KAAKvb,KAAKilD,QAAQ5lD,UAAU4f,eAAelf,MAAMC,MAAMT;gBAE3DS,KAAK+pD,WAAWxuC,IAAIvb,KAAKihB,QAAQ1F,KAAK;gBACtCvb,KAAKklD,YAAYyE,YAAYpuC;gBAC7Bvb,KAAKklD,YAAYgF,WAAW3uC;gBAC5Bvb,KAAKwqD,sBAAsBjvC;gBAE3B,OAAOA;;YAGXiR,UAAU,SAASjR,IAAIgC;gBACnBvd,KAAKilD,QAAQ5lD,UAAUmtB,SAASzsB,MAAMC,MAAMT;gBAE5CS,KAAKklD,YAAY5nC,WAAW/B,IAAIvb,KAAK6sB,YAAYtP;;YAGrDuX,yBAAyB;gBACrB90B,KAAKklD,YAAYC;gBACjBnlD,KAAKilD,QAAQ5lD,UAAUy1B,wBAAwB/0B,MAAMC,MAAMT;;;;IC7sBvExB,GAAGC,eAAe,SAAS+a,GAAGrb;QAC1B;QAEA,IAAIoE,OAAO9B;QAKXA,KAAKilD,UAAUvnD,YAAYK,GAAGL,WAAWy4B,oBAAoBp4B,GAAGo4B;QAChEn2B,KAAKilD,QAAQllD,MAAMC,MAAMT;QAGzBxB,GAAGuG,OAAOtE,KAAKpB;YACX6B,SAAS;YAETwjB,QAAQ;YAERqqC,aAAa;YAEb/G;gBACIC;gBACAqC,sBAAsB;;YAG1BhkD;gBACIynD,gBAAgB;gBAChBK,YAAY;gBACZvD,oBAAoB;gBACpB5iB,QAAQ;;YAGZ+mB,UAAU;YAEVnkC;gBACIo/B,UAAU;gBACVtN,WAAW;gBACX9uC,SAAS;gBACTq9C,MAAM;gBACN+D,UAAU;gBACV1rD,MAAM;gBACNm9C,YAAY;;YAGhByN;gBACIH,MAAM;gBACNC,kBAAkB;gBAClBI,eAAe;;YAGnBt9B;gBACIm+B,mBAAmB;gBACnBC,oBAAoB;;YAGxBhqC;gBACI6mC,mBAAmB;gBACnBC,eAAe;;YAGnBrqC;gBACIwqC,cAAc;gBACdM,gBAAgB;gBAChBD,oBAAoB;gBACpBF,oBAAoB;;YAIxB9oD;gBACIiqD,kBAAkB;gBAClBR,cAAc;;YAGlBrkC;gBACIumC,eAAe;gBACfX,mBAAmB;;YAGvBjB;gBACIt0B,eAAe;gBACfm2B,UAAU;gBACVR;oBACIC,mBAAmB;oBACnBQ,kBAAkB;oBAClBC,aAAa;;gBAEjBC,mBAAmB;;YAGvBz3C;gBACIk1C,YAAY;;YAGhBsB,aAAa,SAAS1tD;gBAClB,IAAI0B,KAAKojD,YAAY8J,UAAU,UAAU;oBACrC,OAAOltD,KAAKojD,YAAY+J,WAAW,SAAS7uD;uBAE3C;oBACDupB,WAAW;wBACP3iB,OAAOqqB,MAAMjxB;uBACd;;;YAIX+rD,aAAa,SAAS/rD;gBAClB,IAAI0B,KAAKojD,YAAY8J,UAAU,YAAY;oBACvC,OAAOltD,KAAKojD,YAAY+J,WAAW,WAAW7uD;uBAE7C;oBACD,OAAO4G,OAAOkoD,QAAQ9uD;;;YAI9B8tD,YAAY,SAAS9tD,SAAS+uD;gBAC1B,IAAIrtD,KAAKojD,YAAY8J,UAAU,WAAW;oBACtC,OAAOltD,KAAKojD,YAAY+J,WAAW,UAAU7uD,SAAS+uD;uBAErD;oBACD,OAAOnoD,OAAOooD,OAAOhvD,SAAS+uD;;;WAGvC;QAGHpxD,GAAGuG,OAAOtE,KAAKpB,UAAUma,GAAG;QAE5B/Y,KAAKklD,cAAc,IAAInnD,GAAGsxD;YACtBlvD,KAAKpC,GAAG+S,KAAK9Q,KAAKG,KAAKH;YACvBsvD,gBAAgBtvD,KAAKpB,SAAS2vD;YAC9BgB,aAAavvD,KAAKpB,SAAS6B;YAC3B+uD,iBAAiBxvD,KAAKpB,SAAS0vD;YAC/BrqC,QAAQjkB,KAAKpB,SAASqlB;YACtBy0B,gBAAgB14C,KAAKgiB;YACrBoI;gBACItnB,MAAM9C,KAAKpB,SAASwrB,QAAQtnB;gBAC5B0rD,UAAUxuD,KAAKpB,SAASwrB,QAAQokC;;YAEpC/Z;gBACIgb,WAAWzvD,KAAKpB,SAASmuD,WAAW6B;gBACpCG,mBAAmB/uD,KAAKpB,SAASmuD,WAAWgC;;YAEhDX;gBACIsB,iBAAiB1vD,KAAKpB,SAASmuD,WAAWqB,aAAaC;gBACvDsB,uBAAuB3vD,KAAKpB,SAASmuD,WAAWqB,aAAaS;gBAC7De,qBAAqB5vD,KAAKpB,SAASmuD,WAAWqB,aAAaU;;YAE/DjpD,MAAM7F,KAAKpB,SAASiH;;QAGxB,IAAI7F,KAAKpB,SAASqrB,YAAYmH,qBAAqBrzB,GAAG+R,YAAY/R,GAAGiS,aAAa;YAC9EhQ,KAAKklD,YAAY2K,cAAc7vD,KAAKpB,SAAS0xB,SAASgB;eAErD,KAAKvzB,GAAGgW,kBAAkB0D,aAAczX,KAAKpB,SAAS8oB,KAAKoI,aAAa/xB,GAAGgW,kBAAkB2D,YAAa;YAC3G1X,KAAKklD,YAAY2K,cAAc7vD,KAAKpB,SAAS0xB,SAASo+B;eAErD;YACD1uD,KAAK61B;YAEL71B,KAAKklD,YAAY7W;YAEjBruC,KAAKupD,WAAWvpD,KAAKpB,SAASwrB;YAE9B,KAAKpqB,KAAKpB,SAASqlB,UAAUjkB,KAAKklD,YAAY1iC,aAAa;gBACvDxiB,KAAKwtB,mBAAmBxtB,KAAK4pB;oBACzBnpB,SAAST,KAAKklD,YAAY1iC;oBAC1BjJ,OAAOvZ,KAAKpB,SAASiH,KAAK6kB;mBAC3BlQ;;YAGPxa,KAAK8lD;YAEL,IAAI/nD,GAAGyE,eAAezE,GAAGgW,kBAAkB8C,UAAU;gBACjD7W,KAAKslD,OAAOtlD,KAAK2lD;;YAGrB,IAAI3lD,KAAKpB,SAASwpB,MAAMD,iBAAiBnoB,KAAKpB,SAASwpB,MAAMumC,eAAe;gBACxE,IAAI5wD,GAAGmqB,cAAc;oBACjBloB,KAAK+tD;uBAEJ;oBACD/tD,KAAKG,IAAI,mCAAmC;;;YAIpDH,KAAK4lD,qBAAqB;YAC1B5lD,KAAK6lD,yBAAyB;;;IAKtC9nD,GAAGuG,OAAOvG,GAAGC,aAAaqB,WAAWtB,GAAG0gB;IACxC1gB,GAAGuG,OAAOvG,GAAGC,aAAaqB,WAAWtB,GAAGsoB;IAGxCtoB,GAAGuG,OAAOvG,GAAGC,aAAaqB,WAAWtB,GAAGinD;IACxCjnD,GAAGuG,OAAOvG,GAAGC,aAAaqB,WAAWtB,GAAG0oD;IC5LxC1oD,GAAGsxD,aAAa,SAASlzC;QACrB;QAEA,IAAI2zC,eAAe,cACfC,oBAAoB,eACpBC,0BAA0B,eAC1BC,8BAA8B,mBAE9BC,qBAAqB,oBACrBC,sBAAsB,qBACtBC,oBAAoB,kBACpBC,uBAAuB,qBACvBC;YACIC,SAAStlD,SAASulD;YAClBC;WAEJC,mBAAmB,OACnBC,sBAAsB,GACtBC,+BAA+B,OAC/BC,2BACAC,oBAAoB,GACpB9zD;YACImD,KAAK;YACLs0C;gBACIgb,WAAW;gBACXV,mBAAmB;;YAEvBO,gBAAgB;YAChBC,aAAa;YACbC,iBAAiB;YACjBvrC,QAAQ;YACRy0B,gBAAgB;YAChBtuB;gBACItnB,MAAM;gBACN0rD,UAAU;;YAEdJ;gBACIsB,iBAAiB;gBACjBC,uBAAuB;gBACvBC,qBAAqB;;YAEzB/pD;gBACI2hC,QAAQ;;WAGhBupB;YACI9sC,QAAQ;YACR+sC,aAAa;YACbC,oBAAoB;YACpBC,eAAe;YACfC,eAAe;YACfC,gBAAgB;YAChBC,cAAc;YACdh0D,UAAU;YACVi0D,MAAM;YACNC,MAAM;YACNC,sBAAsB;YACtBp6C,aAAa;YACbq6C,2BAA2B;YAC3BC,kBAAkB;YAClBvxC,MAAM;YACNwxC,SAAS;YACTr1C,MAAM;YACNiE,QAAQ;YACRpJ,OAAO;YACPy6C,gBAAgB;YAChBC,cAAc;YACdntC,OAAO;YACPotC,YAAY;YACZC,mBAAmB;YACnBC,cAAc;YACdC,UAAU;YACVC,gBAAgB;YAChBC,uBAAuB;YACvBC,WAAW;WAEfC,wBACAC,iCAAiC,IAAIv0D,GAAGmP,WACxCqlD,+BAA+B,IAAIx0D,GAAGmP,WACtC/M,KACAqyD,qBACAC,qBACAC,cACAtwC,WACA8M,UACAyjC,gBACAC,aAKAC,6BAA6B;YACzB,IAAIC,kBAAmB91D,QAAQoxD,aAAauB,uBACxCoD,aAAa/1D,QAAQoxD,aAAawB,qBAClCzzC;gBACIwF,SAASmvC;gBACT5uC,OAAO0wC;;YAGf,IAAID,gBAAgB;gBAChB,IAAIG,iBAAiB;oBACjB91D,QAAQ07C,eAAer2B,SAASywC,iBAAiB,IAAIhlB,SAAS3xB,MAAMnE,KAChE,SAASg7C;wBACLV,+BAA+BllD,QAAQ4lD;uBAE3C;wBACIV,+BAA+BhlD;wBAC/BnN,IAAI,0DAA0D2yD,iBAAiB;;uBAItF;oBACDR,+BAA+BhlD;;gBAGnC,IAAIylD,YAAY;oBACZ/1D,QAAQ07C,eAAer2B,SAAS0wC,YAAY,IAAIjlB,SAAS3xB,MAAMnE,KAC3D,SAASg7C;wBACLT,6BAA6BnlD,QAAQ4lD;uBAEzC;wBACIT,6BAA6BjlD;wBAC7BnN,IAAI,kEAAkE4yD,YAAY;;uBAIzF;oBACDR,6BAA6BjlD;;;WAOzC2lD,oBAAoB,SAASb;YACzB,IAAIc,sBAAsB,IAAIn1D,GAAGmP;YAEjCqlD,6BAA6Bv6C,KAAK,SAASoyB;gBACvC+oB,4BAA4B/oB,KAAKgoB;gBAEjC,KAAKA,UAAUlkB,KAAK;oBAChBkkB,UAAUlkB,MAAM9D,IAAI8D;oBACpBkkB,UAAUjlD,SAAS;wBACfilD,UAAUjlD,SAAS;wBACnBimD,KAAKhB;wBACLc,oBAAoB9lD;;uBAGvB;oBACD8lD,oBAAoB9lD;;eAEzB;gBAICtK,KAAKsvD;gBACLc,oBAAoB9lD;;YAGxB,OAAO8lD;WAGXG,qBAAqB,SAAS93C,IAAI3O,MAAMuP;YACpC,IAAIi2C,YAAYkB,aAAa/3C;YAE7Bpb,IAAI,kCAAkCob;YACtC3O,KAAK2mD,gBAAgBh4C;YAErB,OAAOve,QAAQ07C,eAAer2B,SAASzV,MAAMwlD,WAAWj2C,MAAMnE,KAC1D;gBACI24C;gBACAyC,KAAKhB;gBACLC,kBAAkB92C,IAAInO;eAE1B;gBACIilD,kBAAkB92C,IAAIjO;gBAItB,KAAKtQ,QAAQoxD,aAAasB,iBAAiB;oBACvC8D,+BAA+Bj4C,IAAI62C;;;WAKnDqB,4BAA4B;YACxB,IAAI5C,qBAAqB1uD,QAAQ;gBAC7ByuD,+BAA+B;gBAE/B,IAAI8C,qBAAqB7C,qBAAqBt9C;gBAE9C,IAAImgD,mBAAmBC,QAAQ;oBAC3BC,kCAAkCF;uBAEjC;oBACDG,+BAA+BH;;mBAGlC;gBACD9C,+BAA+B;;WAIvCkD,YAAY,SAASv4C;YACjB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBxwC;WAGtDyzC,cAAc,SAASz4C;YACnB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBa;WAGtDqC,YAAY,SAAS/yD;YACjB,OAAO6yD,cAAc3xC,WAAW2uC,gBAAgB7vD,OAAO;WAG3DgzD,YAAY,SAAS34C;YACjB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBc;WAGtDsC,oBAAoB;YAChB,OAAOJ,cAAc3xC,WAAW2uC,gBAAgBmB;WAGpDkC,cAAc,SAAS74C;YACnB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBiB;WAGtD7vC,UAAU,SAAS5G;YACf,OAAO+0C,UAAUG,IAAIl1C,OAAOxd,GAAGmxB,UAAU3pB,gBAAgBwqD,oBAAoBx0C;WAGjFvI,cAAc,SAASuI;YACnB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgB5wC;WAGtDk0C,WAAW,SAAS94C;YAChB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgB55C;WAGtDm9C,cAAc,SAAS/4C;YAGnB,IAAIA,MAAM,MAAM;gBACZ,OAAOw4C,cAAc3xC,WAAW2uC,gBAAgBU,8BAC5CsC,cAAc3xC,WAAW2uC,gBAAgBW;;YAIjD,OAAOqC,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBS,yBAC9CuC,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgB35C;WAGnDm9C,WAAW,SAASh5C;YAChB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBrsC;WAGtDvB,UAAU,SAAS5H;YACf,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBz0C;WAGtDk4C,aAAa,SAASj5C;YAClB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBY;WAGtDoC,gBAAgB,SAAS/iD,SAASyjD;YAC9B,OAAOzjD,WAAWjT,GAAGiT,SAASzL,gBAAgBkvD;WAGlDnB,eAAe,SAAS/3C;YACpB,OAAOo3C,kBAAkBoB,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBqB;WAGxEtvD,OAAO,SAASZ;YACZA,MAAMnE,GAAGmE,IAAI2C,SAAS7H,QAAQotB,QAAQtnB;WAM1CqwD,8BAA8B,SAASniC,aAAaohC;YAChD,IAAI17B,WAAW1F,YAAYjuB,MAAM2zB,UAC7BD,YAAYzF,YAAYjuB,MAAM0zB;YAElC,IAAIA,aAAaC,aAAa07B,UAAUrvD,MAAM2zB,aAAa07B,UAAUrvD,MAAM0zB,WAAW;gBAClF14B,GAAGq0D,WAAWruD;oBACV2yB,UAAUA;oBACVD,WAAWA;;;WAQvB+8B,iCAAiC,SAASj4C,IAAI62C;YAC1C,IAAIsC,aAAarC,kBAAkB92C,OAAO,IAAIxd,GAAGmP,UAAUI,WACvDqnD,2BAA2B,IAAI52D,GAAGmP;YAEtColD,+BAA+Bt6C,KAAK,SAASoyB;gBACzCsqB,WAAW18C,KACP;oBACI28C,yBAAyBvnD;mBAE7B;oBACI+lD,4BAA4B/oB,KAAKgoB;oBAEjCA,UAAUjlD,SAAS;wBACfilD,UAAUjlD,SAAS;wBACnBwnD,yBAAyBvnD;;oBAG7BglD,UAAUlkB,MAAM9D,IAAI8D;oBACpBklB,KAAKhB;;;YAKjB,OAAOuC;WAWXC,sBAAsB;YAClB,IAAIC,UACAC,YACAC,cACAC,gBACAC,cACAC,eACAjT,UACAmQ,WACAF,gBACAiD,YACAC;YAEJj1D,IAAI;YAGJ,IAAInD,QAAQsyD,kBAAkB,MAAM;gBAChC,MAAM,IAAIrrD,MAAM;;YAIpB,IAAIlG,GAAGmL,SAASlM,QAAQsyD,iBAAiB;gBACrCuF,WAAW5pD,SAASg6B,eAAejoC,QAAQsyD;gBAE3C,IAAIuF,aAAa,MAAM;oBACnB,MAAM,IAAI5wD,MAAMlG,GAAGyL,OAAO,2CAA2CxM,QAAQsyD;;gBAGjFwF,aAAaD,SAASrkD;mBAErB;gBACD,IAAIxT,QAAQsyD,eAAe9+C,cAAcnS,WAAW;oBAChD,MAAM,IAAI4F,MAAM,mEACZ;;gBAGR6wD,aAAa93D,QAAQsyD,eAAe9+C;;YAGxCskD,aAAa/2D,GAAGqL,QAAQ0rD;YACxBE,iBAAiB/pD,SAASC,cAAc;YACxC8pD,eAAe3iD,YAAYtU,GAAGsS,UAAUykD;YACxCM,aAAar3D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgB1zD;YAIhE,IAAIL,QAAQinB,QAAQ;gBAChBixC,gBAAgBn3D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgB9sC;gBACnE,IAAIixC,eAAe;oBACfn3D,GAAGm3D,eAAerxD;;;YAS1B,KAAK9F,GAAGyE,gBAAgBzE,GAAGgW,kBAAkB8C,UAAU;gBACnDq7C,iBAAiBn0D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgBmB;gBACpE,IAAIA,gBAAgB;oBAChBn0D,GAAGm0D,gBAAgBruD;;;YAI3Bo+C,WAAWlkD,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgBO;YAI9D,IAAIrP,aAAalkD,GAAGyE,aAAa;gBAC7BrC,IAAI,2BAA2B;gBAC/BpC,GAAGkkD,UAAUp+C;;YAGjB,KAAK9F,GAAGgW,kBAAkB8C,UAAU;gBAEhCu+C,WAAWz6C,gBAAgBw1C;gBAE3B,IAAIlO,YAAYlkD,GAAGkkD,UAAUh8C,aAAaiqD,qBAAqB;oBAI3DnyD,GAAGkkD,UAAUl+C;wBACTf,SAAS;;;mBAIhB,IAAIjF,GAAGq3D,YAAYnvD,aAAakqD,wBAAwBlO,UAAU;gBACnEkT,aAAap3D,GAAGkkD,UAAU18C,gBAAgBwrD,gBAAgBkB;gBAC1DkD,cAAcp3D,GAAGo3D,YAAYtxD;;YAKjCuuD,YAAYr0D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgBqB;YAC/D,KAAKO,gBAAgB;gBACjBP,aAAar0D,GAAGq0D,WAAWvuD;mBAE1B,IAAIuuD,WAAW;gBAChBtB,mBAAmB1uB,SAASgwB,UAAUhsD,aAAa4pD;gBAEnDc,mBAAmBA,mBAAmB,IAAIA,mBAAmB;gBAE7D8B,cAAc70D,GAAGq0D,WAAWnsD,aAAagqD;;YAE7C0C,iBAAiBA,kBAAkBP;YAEnCI,sBAAsBz0D,GAAGi3D,gBAAgBhwD,WAAW+rD,gBAAgBgB,mBAAmB5vD,SAAS;YAChGswD,sBAAsB10D,GAAGi3D,gBAAgBhwD,WAAW+rD,gBAAgBrsC,OAAOviB,SAAS;YAEpF4yD,eAAeh3D,GAAGi3D,gBAAgBzvD,gBAAgBwrD,gBAAgBQ;YAElE,IAAIwD,gBAAgB,MAAM;gBACtB,MAAM,IAAI9wD,MAAM;;YAGpBgxD,eAAeF,aAAavkD;YAC5BukD,aAAavkD,YAAY;YAGzB,IAAIwkD,eAAe1vD,qBAAqB,UAAUnD,QAAQ;gBACtD8I,SAASC,cAAc;;YAG3B/K,IAAI;YAEJ;gBACIouD,UAAUxwD,GAAGqL,QAAQ4rD,eAAexkD;gBACpC6kD,cAAct3D,GAAGqL,QAAQ6rD;;WAIjCK,cAAc,SAASpzD,IAAID,OAAOitB;YAC9B,IAAIqmC,WAAWrmC,UACXsmC,WAAWD,SAAS7vD;YAExB,IAAIzD,QAAQ,GAAG;gBACXuzD,WAAWz3D,GAAGw3D,UAAU/vD,WAAWvD,OAAO0D;;YAI9C4vD,SAAS7xD,aAAaxB,IAAIszD;WAG9B3B,iCAAiC,SAASH;YACtC,IAAIn4C,KAAKm4C,mBAAmBn4C,IACxBk6C,gBAAgB/B,mBAAmB+B,eACnCC,qBAAqBD,iBAAiBA,cAAclC,eACpDnB,YAAYkB,aAAa/3C,KACzBY;gBACI0F,sBAAsB6xC,mBAAmB7xC;gBACzCF,SAASmvC;gBACTn4B,QAAQ;gBACRzW,OAAO;;YAGf,IAAInkB,GAAGgW,kBAAkBiD,eAAe;gBACpC,IAAIo7C,WAAW;oBACX,IAAIp1D,QAAQy3C,OAAOgb,aAAazyD,QAAQy3C,OAAOgb,aAAakB,qBAAqB;wBAC7E6C,+BAA+Bj4C,IAAI62C;wBACnCqB;2BAEC;wBACDR,kBAAkBb,WAAW35C,KAAK;4BAC9B45C,kBAAkB92C,MAAM,IAAIxd,GAAGmP;4BAE/BmlD,kBAAkB92C,IAAI9C,KAAK;gCACvBkR,WAAW8pC,2BAA2Bz2D,QAAQy3C,OAAOsa;;4BAMzD,IAAI2G,sBAAsB,MAAM;gCAC5BC,iBAAiBp6C,IAAIm6C;mCAEpB;gCACDrC,mBAAmB93C,IAAIk6C,eAAet5C;;;;uBAMjD;oBACDs3C;;mBAGH,IAAIrB,WAAW;gBAChBa,kBAAkBb;gBAClBqB;;WAIRG,oCAAoC,SAASF;YACzC,IAAIn4C,KAAKm4C,mBAAmBn4C,IACxBkL,eAAeitC,mBAAmBjtC,cAClCmvC,iBAAiBlC,mBAAmBkC,gBACpCxD,YAAYkB,aAAa/3C,KACzBY;gBACI0F,sBAAsB6xC,mBAAmB7xC;gBACzCK,OAAO0wC;gBACPjxC,SAASmvC;;YAGjB,IAAIsB,WAAW;gBACX,IAAI3rC,cAAc;oBACd,IAAIzpB,QAAQy3C,OAAOgb,aAAazyD,QAAQy3C,OAAOgb,aAAakB,qBAAqB;wBAC7E6C,+BAA+Bj4C,IAAI62C;wBACnCqB;2BAEC;wBACD,IAAImC,gBAAgB;4BAChB3C,kBAAkBb;;wBAGtB,OAAOp1D,QAAQ07C,eAAer2B,SAASoE,cAAc2rC,WAAWj2C,MAAMnE,KAClE;4BACIo7C,KAAKhB;4BACLzB;4BACAhnC,WAAW8pC,2BAA2Bz2D,QAAQy3C,OAAOsa;2BAGzD;4BACIyE,+BAA+Bj4C,IAAI62C;4BACnCzoC,WAAW8pC,2BAA2Bz2D,QAAQy3C,OAAOsa;;;uBAKhE;oBACDyE,+BAA+Bj4C,IAAI62C;oBACnCqB;;;WAKZoC,sBAAsB,SAASt6C,IAAIu6C;YAC/B,IAAIC,MAAMzB,YAAY/4C,KAElBy6C,sBAAsBz6C,MAAM,OAAOw1C,gBAAgBW,mBAAmBX,gBAAgB35C;YAE1F,IAAI2+C,QAAQh4D,GAAGg4D,KAAKxxD,SAASyxD,sBAAsB;gBAC/CD,MAAMh4D,GAAGg4D,KAAKxwD,gBAAgBywD;;YAGlC,IAAID,KAAK;gBACLh4D,GAAGg4D,KAAKhyD;oBAAK2mC,OAAOorB,UAAU;;gBAC9BC,IAAI3jD,aAAa,iBAAiB0jD;;WAI1C1C,OAAO,SAASlxD;YACZA,MAAMnE,GAAGmE,IAAI4C,YAAY9H,QAAQotB,QAAQtnB;WAG7C6yD,mBAAmB,SAASM,mBAAmBC;YAC3C,IAAIC,kBAAkB7C,aAAa2C,oBAC/BG,kBAAkB9C,aAAa4C;YAEnC/1D,IAAIpC,GAAGyL,OAAO,sFAAsFysD,mBAAmBC,mBAAmBA;YAG1I7D,kBAAkB6D,mBAAmBl+C,KAAK;gBACtC24C;gBACA0B,kBAAkB4D,mBAAmB7oD;gBACrCjN,IAAIpC,GAAGyL,OAAO,wEAAwE0sD,mBAAmBD;gBACzGE,gBAAgBjoB,MAAMkoB,gBAAgBloB;gBACtCklB,KAAK+C;eAET;gBACI9D,kBAAkB4D,mBAAmB3oD;gBACrC,KAAKtQ,QAAQoxD,aAAasB,iBAAiB;oBACvC8D,+BAA+ByC,mBAAmBE;;;;QAKlEp4D,GAAGuG,OAAOtH,SAASmf;QACnBhc,MAAMnD,QAAQmD;QAId,KAAKpC,GAAGgW,kBAAkBiD,eAAe;YACrCha,QAAQy3C,OAAOsa,oBAAoB;YACnC/xD,QAAQy3C,OAAOgb,YAAY;;QAG/BrtC,YAAYplB,QAAQuyD;QACpBoD,iBAAiB31D,QAAQ07C,mBAAmBr6C;QAC5Cq0D,eAAekC;QAEf/B;QAEA90D,GAAGuG,OAAOtE;YACNquC,QAAQ;gBACJluC,IAAI;gBAEJwwD,sBAAsB;gBAEtBvuC,UAAU5R,YAAYkiD,aAAanE;gBACnCzrD,KAAKqxD;gBACLn0D,KAAKq2D;gBACLnnC,WAAWlyB,QAAQwyD,mBAAmBuE,cAAc3xC,WAAW2uC,gBAAgBQ;gBAE/EpxD,IAAI;;YAGR0vD,eAAe,SAASzvD;gBACpB,IAAIk2D,eAAev4D,GAAGsS,UAAUjQ;gBAChCgiB,UAAU5R,YAAY;gBACtB4R,UAAU/P,YAAYikD;;YAG1Bz7C,OAAO;gBACH7a,KAAKquC;;YAGT+W,YAAY;gBACRl2B,SAAS1e,YAAY;;YAGzBk8C,eAAe;gBACXgE,mBAAmB;;YAGvBx0C,SAAS,SAASX,IAAIxc,MAAMw3D,aAAaC,aAAaC;gBAClD,IAAIC,SAAS34D,GAAGsS,UAAUqiD,aAAa2C,eACnCsB,aAAa5C,cAAc2C,QAAQ3F,gBAAgB5wC,OACnDi1C,aAAarB,cAAc3xC,WAAW2uC,gBAAgB1zD,WACtDgjB,gBAAgBo2C,QAAQnG,UAAUC,UAAUrhC,UAC5C0nC;gBAEJ,IAAIH,OAAO;oBACPnG,UAAUG,IAAIl1C,MAAMm7C;;gBAGxB34D,GAAG24D,QAAQ7xD,SAASkrD,oBAAoBx0C;gBACxC65C,WAAWz6C,gBAAgBw1C;gBAE3B,IAAIwG,YAAY;oBACZ54D,GAAG44D,YAAY/wD,QAAQ7G;oBACvB43D,WAAWvkD,aAAa,SAASrT;;gBAGrC23D,OAAOtkD,aAAa09C,cAAcv0C;gBAElC,IAAIg7C,aAAa;oBACbjB,YAAYoB,QAAQH,YAAYt0D,OAAOoe;uBAEtC;oBACDA,cAAchO,YAAYqkD;;gBAG9B,IAAIF,aAAa;oBACbE,OAAO3zD,MAAMC,UAAU;oBACvBjF,GAAG24D,QAAQ7xD,SAASwrD;uBAEnB;oBACDvtD,KAAKwxD,YAAY/4C;oBACjBzY,KAAKqgB,QAAQ5H;oBACbzY,KAAKoxD,UAAU34C;oBACfzY,KAAKyxD,SAASh5C;oBACdzY,KAAKuxD,SAAS94C;oBACdzY,KAAKkxD,YAAYz4C;oBAEjB,IAAIm1C,kBAAkB;wBAClB1wD,KAAKkqD,WAAW3uC;;oBAGpBq7C,QAAQtD,aAAa/3C;oBACrB,IAAIq7C,UAAUA,MAAM1oB,KAAK;wBACrBqkB,6BAA6Bv6C,KAAK,SAAS6+C;4BACvCD,MAAM1oB,MAAM2oB,WAAW3oB;4BACvB,IAAI2oB,WAAW9zD,MAAM0zB,aAAaogC,WAAW9zD,MAAM2zB,UAAU;gCACzD34B,GAAG64D,OAAO7yD;oCACN0yB,WAAWogC,WAAW9zD,MAAM0zB;oCAC5BC,UAAUmgC,WAAW9zD,MAAM2zB;;;4BAInC08B,KAAKwD;;;;;YAMrB/J,gBAAgB,SAAStxC,IAAIxc,MAAMw3D,aAAaC;gBAC5Cx2D,KAAKkc,QAAQX,IAAIxc,MAAMw3D,aAAaC,aAAa;;YAGrDrR,eAAe;gBACXj2B,SAAS7c,YAAYi+C,UAAUC;gBAC/BD,UAAUC,UAAUtlD,SAASulD;gBAC7BF,UAAUG;;YAGd9J,YAAY,SAASprC;gBACjBxd,GAAGokB,QAAQ5G,KAAK1X;;YAGpByiD,WAAW,SAASpkD;gBAChB,IAAI40D,cAAc50D;gBAElB,IAAI40D,aAAa;oBAEb,OAAOA,YAAY1wD,aAAa0pD,iBAAiB,MAAM;wBACnDgH,cAAcA,YAAYlzD;;oBAG9B,OAAOw+B,SAAS00B,YAAY1wD,aAAa0pD;;;YAIjDiH,aAAa;gBACT,OAAO7nC;;YAGXk6B,sBAAsB,SAAS7tC;gBAC3B,IAAI3I,WAAWI,YAAYuI;gBAE3B3I,YAAY7U,GAAG6U,UAAU/N,SAAS7H,QAAQotB,QAAQokC;;YAGtDxI,gBAAgB,SAASzqC,IAAIxc;gBACzB,IAAIi4D,aAAahkD,YAAYuI;gBAE7B,IAAIy7C,YAAY;oBACZj5D,GAAGi5D,YAAYpxD,QAAQ7G;oBACvBi4D,WAAW5kD,aAAa,SAASrT;;;YAIzCiqD,cAAc,SAASztC;gBACnBzY,KAAKkQ,YAAYuI;;YAGrB2tC,cAAc,SAAS3tC;gBACnB63C,KAAKpgD,YAAYuI;;YAGrB07C,YAAY,SAAS/0D;gBACjB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgB5wC;;YAG3CqC,WAAW;gBACP,OAAOxlB,QAAQinB,UAAU8vC,cAAc3xC,WAAW2uC,gBAAgB9sC;;YAGtE4jC,oBAAoB;gBAChB/kD,KAAKqxD;;YAGTvM,oBAAoB;gBAChBwL,KAAKe;;YAGTxM,aAAa;gBACT,OAAOoM,cAAc3xC,WAAW2uC,gBAAgBO;;YAGpDjJ,wBAAwB;gBACpB,OAAOmK;;YAGXnJ,WAAW,SAAS9tC;gBAChBzY,KAAKyxD,SAASh5C;;YAGlBovC,iBAAiB;gBACb,OAAO8H;;YAGX7H,WAAW,SAASrvC;gBAChB63C,KAAKmB,SAASh5C;;YAGlBmqC,kBAAkB,SAASnqC;gBACvB,OAAO4G,QAAQ5G;;YAGnB4tC,cAAc,SAAS5tC;gBACnB,IAAI27C,OAAO9C,YAAY74C;gBAEvB27C,QAAQn5D,GAAGm5D,MAAMryD,SAAS7H,QAAQotB,QAAQokC;;YAG9C/I,iBAAiB,SAASlqC;gBACtB,OAAOxd,GAAGokB,QAAQ5G,KAAKhX,SAAS8rD;;YAGpCpH,cAAc,SAAS1tC;gBACnB,IAAI27C,OAAO9C,YAAY74C;gBAEvB27C,QAAQn5D,GAAGm5D,MAAMpyD,YAAY9H,QAAQotB,QAAQokC;;YAGjD2I,YAAY,SAASj1D;gBACjB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBiB,cAAc;;YAGzDlJ,cAAc,SAASvtC;gBACnB,OAAOw4C,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBgB;;YAGtDqF,aAAa,SAASl1D;gBAClB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBgB,mBAAmB;;YAG9D9H,gBAAgB,SAAS1uC,IAAI2P,QAAQC;gBACjC,IAAI4qC,MAAMzB,YAAY/4C,KAClBu6C;gBAEJ,IAAIC,OAAO5qC,QAAQ,GAAG;oBAClB2qC,UAAU1xD,KAAKC,MAAM6mB,SAASC,QAAQ;oBAEtC,IAAI2qC,YAAY,KAAK;wBACjBhzD,KAAKizD;2BAEJ;wBACD3C,KAAK2C;;oBAGTF,oBAAoBt6C,IAAIu6C;;;YAIhCzZ,qBAAqB,SAASnxB,QAAQC;gBAClCnrB,KAAKiqD,eAAe,MAAM/+B,QAAQC;;YAGtCg/B,cAAc,SAAS5uC;gBACnB,IAAIw6C,MAAMzB,YAAY/4C;gBAEtBw6C,OAAOjzD,KAAKizD;;YAGhBM,mBAAmB;gBACfr2D,KAAKmqD;;YAGTsB,eAAe,SAASlwC;gBACpBs6C,oBAAoBt6C,IAAI;gBACxBvb,KAAKq2D,kBAAkB96C;;YAG3BquC,oBAAoB;gBAChB5pD,KAAKyrD;;YAGTf,YAAY,SAASnvC;gBACjB,KAAKm1C,kBAAkB;oBACnB,IAAInwC,SAASuzC,UAAUv4C;oBAEvBgF,UAAUxiB,GAAGwiB,QAAQzb,YAAY9H,QAAQotB,QAAQtnB;;;YAIzDonD,YAAY,SAAS3uC;gBACjBzY,KAAKgxD,UAAUv4C;;YAGnB87C,UAAU,SAASn1D;gBACf,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBxwC,QAAQ;;YAGnD2qC,YAAY,SAAS3vC;gBACjB63C,KAAKiB,SAAS94C;gBACdzY,KAAKkxD,YAAYz4C;;YAGrB0qC,cAAc,SAAS1qC;gBACnBvb,KAAKspD,cAAc/tC,IAAIve,QAAQ6I,KAAK2hC;gBACpCxnC,KAAKs3D,oBAAoB/7C;gBACzBzY,KAAK0xD,WAAWj5C;;YAGpBkuC,WAAW,SAASluC;gBAChBzY,KAAKuxD,SAAS94C;;YAGlBg8C,SAAS,SAASr1D;gBACd,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgB55C,OAAO;;YAGlDqgD,kBAAkB,SAASt1D;gBACvB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBa,gBAAgB;;YAG3D0F,qBAAqB,SAAS/7C;gBAC1B63C,KAAKY,YAAYz4C;gBACjBzY,KAAKuxD,SAAS94C;;YAGlB4qC,iBAAiB,SAAS5qC;gBACtBvb,KAAKspD,cAAc/tC,IAAI;gBACvBvb,KAAKkrD,WAAW3vC;gBAChB63C,KAAKoB,WAAWj5C;;YAGpBwvC,kBAAkB,SAASxvC;gBACvB63C,KAAKc,UAAU34C;;YAGnBwwC,kBAAkB,SAASxwC;gBACvBzY,KAAKoxD,UAAU34C;;YAGnBk8C,gBAAgB,SAASv1D;gBACrB,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBc,cAAc;;YAGzD6F,SAAS,SAASx1D;gBACd,OAAOnE,GAAGmE,IAAIqC,SAASwsD,gBAAgBrsC,OAAO;;YAGlDpH,YAAY,SAAS/B,IAAI1V;gBACrB,IAAIyW,OAAO6G,QAAQ5H;gBAEnB,IAAIe,MAAM;oBACN82C,KAAK92C;oBACLve,GAAGue,MAAM1W,QAAQC;;;YAIzByjD,eAAe,SAAS/tC,IAAI1V;gBACxB,IAAI8xD,SAAS5D,cAAc5xC,QAAQ5G,KAAKw1C,gBAAgBe;gBAExD,IAAI6F,QAAQ;oBAER,IAAI9xD,QAAQ,MAAM;wBACd9H,GAAG45D,QAAQ3xD;2BAEV;wBACDjI,GAAG45D,QAAQ/xD,QAAQC;;;;YAK/B8jD,aAAa,SAASpuC;gBAClBxd,GAAGokB,QAAQ5G,KAAKzW,YAAYsrD;gBAC5BttD,KAAK0xD,WAAWj5C;;YAGpB0vC,aAAa,SAAS1vC;gBAClBxd,GAAGokB,QAAQ5G,KAAK1W,SAASurD;gBACzBgD,KAAKoB,WAAWj5C;;YAGpByxC,iBAAiB,SAASzxC,IAAIk6C,eAAe5zC;gBACzC,KAAK7hB,KAAKylD,gBAAgBlqC,KAAK;oBAC3Bs1C,qBAAqBhxD;wBAAM0b,IAAIA;wBAAIsG,sBAAsBA;wBAAsB4zC,eAAeA;;qBAC7F7E,gCAAgC6C;;;YAIzC3G,iBAAiB,SAASvxC,IAAIkL,cAAcmvC,gBAAgB/zC;gBACxD,KAAK7hB,KAAKylD,gBAAgBlqC,KAAK;oBAC3Bs1C,qBAAqBhxD;wBAAMgiB,sBAAsBA;wBAAsB8xC,QAAQ;wBAAMp4C,IAAIA;wBAAIkL,cAAcA;wBAAcmvC,gBAAgBA;;qBACxIhF,gCAAgC6C;;;YAIzCzE,WAAW,SAAS9tD;gBAChB,OAAOnD,GAAGgW,kBAAkB4C,mBAAmBs9C,UAAU/yD;;YAG7D+tD,YAAY,SAAS/tD,MAAMd,SAAS+uD;gBAChC,IAAIyI,SAAS3D,UAAU/yD,OACnB22D,YAAY9D,cAAc6D,QAAQ7G,gBAAgBI,gBAClD2G,UAAUF,OAAOtyD,qBAAqB,SAAS,IAC/CyyD,YAAYhE,cAAc6D,QAAQ7G,gBAAgBE,qBAClD+G,QAAQjE,cAAc6D,QAAQ7G,gBAAgBK,iBAC9CnkD,UAAU,IAAIlP,GAAGmP,WAEjB+qD,eAAe;oBACXF,UAAU10D,oBAAoB,SAAS60D;oBACvCF,SAASA,MAAM30D,oBAAoB,SAAS80D;oBAC5ClrD,QAAQK;mBAGZ4qD,qBAAqB;oBACjBH,UAAU10D,oBAAoB,SAAS60D;oBACvCN,OAAOQ;mBAGXD,iBAAiB;oBACbP,OAAOv0D,oBAAoB,SAAS40D;oBACpCD,MAAM30D,oBAAoB,SAAS80D;oBACnCP,OAAOQ;oBAEPnrD,QAAQG,QAAQ0qD,WAAWA,QAAQrvD;;gBAG3CmvD,OAAO10D,iBAAiB,SAAS+0D;gBACjCF,UAAU70D,iBAAiB,SAASg1D;gBACpCF,SAASA,MAAM90D,iBAAiB,SAASi1D;gBAEzC,IAAIL,SAAS;oBACTA,QAAQrvD,QAAQ0mD;;gBAEpB0I,UAAU9xD,cAAc3F;gBAExBw3D,OAAOS;gBAEP,OAAOprD;;;;IC/gCnBlP,GAAGu6D,iBAAiB,SAASC,GAAGC;QAC5B;QAEA,IAAIllD,WAAW,IAAIvV,GAAGoV,kBAClBgJ;YACIs8C,WAAW;YACXC,UAAU;YACVC,WAAW,SAAShrD,QAAQ6mB;;QAKpCz2B,GAAGuG,OAAOtE;YACNgqD,YAAY,SAASvpD;gBACjBupD,WAAWvpD;;YAGf4S,SAAS;gBACLC,SAASD;;;QAIjB,SAAS22C,WAAWvpD;YAChB6S,SAASrQ,OAAOxC,SAAS0b,KAAKs8C,WAAW,SAASjkC;gBAE9CA,QAAQA,SAASxtB,OAAOwtB;gBAGxB,IAAI7mB,SAAS6mB,MAAM7mB,UAAU6mB,MAAMokC;gBAEnCz8C,KAAKw8C,UAAUhrD,QAAQ6mB;;;QAK/Bz2B,GAAGuG,OAAOk0D;YACNK,mBAAmB,SAAS7vD;gBACxB,OAAOA,KAAK8vD;;YAGhBC,mBAAmB;gBACf,OAAOzlD;;;QAIfvV,GAAGuG,OAAO6X,MAAMo8C;QAEhB,IAAIp8C,KAAKu8C,UAAU;YACf1O,WAAW7tC,KAAKu8C;;;IClDxB36D,GAAG8oD,0BAA0B,SAAS0R;QAClC;QAEA,IAAIS,2BACA78C;YACIsrC,YAAY;YACZtnD,KAAK,SAASC,SAAS2nD;YACvBC,cAAc,SAASvmC;YACvB8J,UAAU,SAAS9J;YACnBwmC,SAAS,SAASxmC;YAClBymC,SAAS,SAASzmC;YAClB0mC,YAAY,SAAS1mC;YACrB2mC,WAAW,SAAS3mC;WAExBw3C;YACI14C,QAAQ,SAAShF;gBAAMY,KAAKoP,SAAShQ;;YACrCmJ,OAAQ,SAASnJ;gBAAMY,KAAK8rC,QAAQ1sC;;YACpCs2C,cAAc,SAASt2C;gBAAMY,KAAK6rC,aAAazsC;;YAC/CpE,OAAO,SAASoE;gBAAMY,KAAK+rC,QAAQ3sC;;YACnCq2C,gBAAgB,SAASr2C;gBAAMY,KAAKgsC,WAAW5sC;;;QAGvD,SAAS29C,aAAavrD,QAAQ6mB;YAC1Bz2B,GAAGY,KAAKs6D,gBAAgB,SAASE,YAAYtqC;gBACzC,IAAIuqC,2BAA2BD,WAAWx7D,OAAO,GAAGC,gBAAgBu7D,WAAWt7D,MAAM,IACjF4jB;gBAEJ,IAAItF,KAAKsrC,WAAW,OAAO2R,0BAA0BzrD,SAAS;oBAC1D8T,SAAStF,KAAKsrC,WAAWnB,UAAU34C;oBACnC5P,GAAGmS,eAAeskB;oBAClBrY,KAAKhc,IAAIpC,GAAGyL,OAAO,gEAAgE2S,KAAKisC,UAAU3mC,SAASA;oBAC3GoN,QAAQpN;oBACR,OAAO;;;;QAKnB1jB,GAAGuG,OAAO6X,MAAMo8C;QAEhBp8C,KAAKs8C,YAAY;QACjBt8C,KAAKw8C,YAAYO;QACjB/8C,KAAKu8C,WAAWv8C,KAAKsrC,WAAWsP;QAEhCh5D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu6D,eAAen8C,MAAM68C;;IC1ChDj7D,GAAGuqD,uBAAuB,SAASiQ;QAC/B;QAEA,IAAIS,2BACA78C;YACIsrC,YAAY;YACZtnD,KAAK,SAASC,SAAS2nD;YACvB39B;gBACIjK,MAAM;gBACN6xC,cAAc;;YAElBvJ,mBAAmB,SAAShnC;YAC5B2mC,WAAW,SAAS3mC;;QAG5B1jB,GAAGuG,OAAO6X,MAAMo8C;QAGhB,SAASW,aAAavrD,QAAQ6mB;YAC1B,IAAIrY,KAAKsrC,WAAWwP,WAAWtpD,WAAWwO,KAAKsrC,WAAW0P,WAAWxpD,SAAS;gBAC1E,IAAI8T,SAAStF,KAAKsrC,WAAWnB,UAAU34C,SACnCiO,SAASO,KAAKssC,kBAAkBhnC;gBAGpC,IAAI7F,WAAW7d,GAAG6d,OAAOiC,WAAW;oBAChC1B,KAAKhc,IAAIpC,GAAGyL,OAAO,6DAA6D2S,KAAKisC,UAAU3mC,SAASA;oBACxG1jB,GAAGmS,eAAeskB;oBAElBwkC,qBAAqBK,mBAAmB53C,QAAQ9T,QAAQ;;;;QAKpEwO,KAAKs8C,YAAY;QACjBt8C,KAAKw8C,YAAYO;QAEjBn7D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7D,oBAAoBn9C,MAAM68C;;ICpCrDj7D,GAAG2rD,8BAA8B,SAAS6O,GAAGS;QACzC;QAEA,IAAI78C;YACIsrC,YAAY;YACZgB,mBAAmB,SAAShnC;YAC5BthB,KAAK,SAASC,SAAS2nD;;QAG/B,KAAKiR,sBAAsB;YACvBA;;QAIJ,SAASO,iBAAiB5rD,QAAQ6mB;YAC9B,IAAIrY,KAAKsrC,WAAW2P,YAAYzpD,SAAS;gBACrC,IAAI8T,SAAStF,KAAKsrC,WAAWnB,UAAU34C,SACnCiO,SAASO,KAAKssC,kBAAkBhnC;gBAEpC,IAAI7F,WAAW7d,GAAG6d,OAAOiC,WAAW;oBAChC1B,KAAKhc,IAAIpC,GAAGyL,OAAO,mEAAmE2S,KAAKisC,UAAU3mC,SAASA;oBAC9Gu3C,qBAAqBK,mBAAmB53C,QAAQ9T;;;;QAK5DwO,KAAKs8C,YAAY;QACjBt8C,KAAKw8C,YAAYY;QAEjBx7D,GAAGuG,OAAO6X,MAAMo8C;QAChBx6D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu7D,oBAAoBn9C,MAAM68C;;ICzBrDj7D,GAAGwqD,4BAA4B,SAASpsC;QACpC;QAEAA,KAAKs8C,YAAY;QACjBt8C,KAAKu8C,WAAW;QAEhB36D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAG2rD,4BAA4BvtC;;ICVvDpe,GAAGu7D,sBAAsB,SAASf,GAAGS;QACjC;QAEA,IAAI78C;YACIsrC,YAAY;YACZtnD,KAAK,SAASC,SAAS2nD;YACvBU,mBAAmB,SAAShnC;YAC5B2mC,WAAW,SAAS3mC;YACpBinC,WAAW,SAASjnC,QAAQpE;YAC5BsrC,uBAAuB,SAASlnC,QAAQmnC;;QAGhD,SAAS4Q,yBAAyB/3C;YAC9B,IAAIg4C,kBAAkBt9C,KAAKisC,UAAU3mC,SACjC5O,SAAS4mD,gBAAgB3mD,YAAY;YAEzC,IAAID,SAAS,GAAG;gBACZ4mD,kBAAkBA,gBAAgB1mD,OAAO,GAAGF;;YAGhD,OAAO4mD;;QAGX,SAASC,qBAAqBj4C;YAC1B,IAAIk4C,WAAWx9C,KAAKisC,UAAU3mC;YAC9B,OAAO1jB,GAAG4U,aAAagnD;;QAI3B,SAASC,iBAAiBC,oBAAoBp4C;YAC1C,IAAIpE,UAAUw8C,mBAAmBpxD,OAC7BqxD;YAEJ,IAAIz8C,YAAYhf,aAAaN,GAAGqL,QAAQiU,SAASlb,SAAS,GAAG;gBACzD23D,gBAAgBJ,qBAAqBj4C;gBAErC,IAAIq4C,kBAAkBz7D,WAAW;oBAC7Bgf,UAAUA,UAAU,MAAMy8C;;gBAG9B39C,KAAKusC,UAAUjnC,QAAQpE;;YAG3BlB,KAAKwsC,sBAAsBlnC,QAAQ;;QAIvC,SAASs4C,yBAAyBjC,SAASr2C;YACvCu3C,qBAAqBD,oBAAoB91D,OAAO60D,SAAS,QAAQ;gBAC7D8B,iBAAiB9B,SAASr2C;;;QAKlC,SAASu4C,6BAA6BlC,SAASr2C;YAC3Cu3C,qBAAqBD,oBAAoB91D,OAAO60D,SAAS,SAAS,SAAStjC;gBAEvE,IAAIpE,OAAOoE,MAAMylC,WAAWzlC,MAAM0lC;gBAElC,IAAI9pC,SAAS,IAAI;oBACbwpC,iBAAiB9B,SAASr2C;;;;QAKtC1jB,GAAGuG,OAAO6X,MAAMo8C;QAEhBp8C,KAAKu8C,WAAWv8C,KAAKsrC,WAAWsP;QAEhCh5D,GAAGuG,OAAOtE,MAAM,IAAIjC,GAAGu6D,eAAen8C,MAAM68C;QAE5Cj7D,GAAGuG,OAAO00D;YACNK,oBAAoB,SAAS99C,IAAI5N,QAAQwsD;gBACrC,IAAIN,qBAAqB19C,KAAKsrC,WAAWqB,aAAavtC;gBAEtDY,KAAKwsC,sBAAsBptC,IAAI;gBAE/Bs+C,mBAAmBpxD,QAAQ+wD,yBAAyBj+C;gBAEpD,IAAI4+C,YAAY;oBACZN,mBAAmBO;;gBAGvBL,yBAAyBF,oBAAoBt+C;gBAC7Cy+C,6BAA6BH,oBAAoBt+C;;;;G7CvF9BvU","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
c&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],q=d.blob?d.blob:d;return new qq.Identify(q,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:q.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:q.type}),blob:new qq.BlobProxy(q,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:q.size,blob:i?q:null})):h.push({uuid:e,name:c,size:q.size,blob:q}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,q=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:q}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA,QCEV,GAAIC,IAAK,SAASC,GACd,YAEA,QACIC,KAAM,WAEF,MADAD,GAAQE,MAAMC,QAAU,OACjBC,MAIXC,OAAQ,SAASC,EAAMC,GAMnB,MALIP,GAAQQ,iBACRR,EAAQQ,iBAAiBF,EAAMC,GAAI,GAC5BP,EAAQS,aACfT,EAAQS,YAAY,KAAOH,EAAMC,GAE9B,WACHR,GAAGC,GAASU,OAAOJ,EAAMC,KAIjCG,OAAQ,SAASJ,EAAMC,GAMnB,MALIP,GAAQW,oBACRX,EAAQW,oBAAoBL,EAAMC,GAAI,GAC/BP,EAAQS,aACfT,EAAQY,YAAY,KAAON,EAAMC,GAE9BH,MAGXS,SAAU,SAASC,GAKf,QAAKA,IAKDd,IAAYc,IAIZd,EAAQa,SACDb,EAAQa,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwBf,OAOrDgB,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAahB,EAASiB,GACnCb,MAGXe,OAAQ,WAEJ,MADAnB,GAAQkB,WAAWE,YAAYpB,GACxBI,MAOXiB,IAAK,SAASC,GAEV,GAAqB,MAAjBtB,EAAQE,MACR,KAAM,IAAIH,IAAGwB,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1BxB,GAAQE,MAAMsB,SAAqD,SAArBxB,EAAe,UACpEsB,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9EzB,GAAG6B,OAAO5B,EAAQE,MAAOoB,GAElBlB,MAGXyB,SAAU,SAASC,EAAMC,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAUH,EAAO,QACrC,OAAOE,GAAGE,KAAKlC,EAAQmC,eAAiBJ,IAAkBC,EAAGE,KAAKlC,EAAQkB,WAAWiB,aAGzFC,SAAU,SAASN,GAIf,MAHK/B,IAAGC,GAAS6B,SAASC,KACtB9B,EAAQmC,WAAa,IAAML,GAExB1B,MAGXiC,YAAa,SAASP,GAClB,GAAIE,GAAK,GAAIC,QAAO,QAAUH,EAAO,QAErC,OADA9B,GAAQmC,UAAYnC,EAAQmC,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtElC,MAGXmC,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASxC,EAAQ2C,cACV3C,EAAQ2C,cAAc,IAAMR,GAE9BnC,EAAQ4C,iBACN5C,EAAQ4C,iBAAiB,IAAMT,IAG1CM,EAAazC,EAAQ6C,qBAAqB,KAE1C9C,GAAG+C,KAAKL,EAAY,SAASM,EAAKC,GAC1BjD,GAAGiD,GAAKnB,SAASM,IACjBO,EAAOO,KAAKD,KAGbR,EAAQE,EAAO,GAAKA,IAG/BQ,gBAAiB,SAASf,GACtB,MAAOpC,IAAGC,GAASuC,WAAWJ,GAAW,IAG7CgB,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQpD,EAAQqD,WAEbD,GACoB,IAAnBA,EAAME,UACNH,EAASF,KAAKG,GAElBA,EAAQA,EAAMG,WAGlB,OAAOJ,IAGXK,QAAS,SAASC,GAGd,MAFAzD,GAAQ0D,UAAYD,EACpBzD,EAAQ2D,YAAcF,EACfrD,MAGXwD,UAAW,WACP,MAAO7D,IAAGC,GAASwD,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAI/D,GAAQ6D,eAEH7D,EAAQ6D,aAAaC,IAKkC,MAArD,WAAaE,KAAKhE,EAAQiE,aAAaH,KAG9CC,EAAU/D,EAAQ8D,GAEFI,SAAZH,GAKiC,MAA9B,WAAaC,KAAKD,QAMxC,WACG,YAEAhE,IAAGoE,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAOvE,IAAGwE,cAAcH,EAAOI,UAAUH,EAAMC,KAGnDvE,GAAGwE,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAASC,EAAMV,GACxB,GAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,IAyB3C,OAlBIM,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlCnB,EAAWJ,EAAaG,IAGnC9E,GAAGmG,IAAM,SAASC,EAASC,GACnBnB,OAAOoB,UACFD,GAAmB,SAAVA,EAKNnB,OAAOoB,QAAQD,GACfnB,OAAOoB,QAAQD,GAAOD,GAGtBlB,OAAOoB,QAAQH,IAAI,IAAME,EAAQ,KAAOD,GAR5ClB,OAAOoB,QAAQH,IAAIC,KAc/BpG,GAAGuG,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAASjD,UAAyD,oBAA7CkD,OAAOC,UAAUC,SAASC,KAAKJ,IAG5ExG,GAAG6G,WAAa,SAASL,GACrB,MAA6B,kBAAf,IASlBxG,GAAG8G,QAAU,SAASC,GAClB,MAAiD,mBAA1CN,OAAOC,UAAUC,SAASC,KAAKG,IACjCA,GAAS7B,OAAOY,aAAeiB,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBnB,aAIrF9F,GAAGkH,WAAa,SAASC,GACrB,MAAyD,kCAAlDV,OAAOC,UAAUC,SAASC,KAAKO,IAK1CnH,GAAGoH,WAAa,SAASC,GACrB,MAAyD,sBAAlDZ,OAAOC,UAAUC,SAASC,KAAKS,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CvH,GAAGwH,SAAW,SAASC,GACnB,MAAuD,oBAAhDhB,OAAOC,UAAUC,SAASC,KAAKa,IAG1CzH,GAAG0H,QAAU,SAASC,GAClB,MAAIC,QAAOlB,UAAUmB,KACVF,EAAOE,OAGXF,EAAOpF,QAAQ,aAAc,KAOxCvC,GAAG8H,OAAS,SAASC,GAEjB,GAAIC,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,GAC9CC,EAASL,EACTM,EAAmBD,EAAOzC,QAAQ,KAetC,OAbA3F,IAAG+C,KAAKiF,EAAM,SAAShF,EAAKC,GAQxB,GAJAmF,EAHgBA,EAAOE,UAAU,EAAGD,GAGfpF,EAFNmF,EAAOE,UAAUD,EAAmB,GAGnDA,EAAmBD,EAAOzC,QAAQ,KAAM0C,EAAmBpF,EAAI8C,QAG3DsC,EAAmB,EACnB,OAAO,IAIRD,GAGXpI,GAAGuI,OAAS,SAASC,GACjB,MAAOtD,QAAOuD,MAAsD,kBAA9ChC,OAAOC,UAAUC,SAASC,KAAK4B,IAGzDxI,GAAG0I,WAAa,SAASC,GACrB,MAAOzD,QAAO0D,UAA8D,sBAAlDnC,OAAOC,UAAUC,SAASC,KAAK+B,IAG7D3I,GAAG6I,cAAgB,SAASC,GACxB,MAAO9I,IAAGuI,OAAOO,IAAqB9I,GAAG+I,QAAQD,IAGrD9I,GAAG+I,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAAS3I,GACxB,GAAI4I,GAAiB5I,EAAK6I,aAE1B,OAAIH,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAIjE,OAAOmE,kBAC4C,8BAA/C5C,OAAOC,UAAUC,SAASC,KAAKoC,IAC3BA,EAAWzI,MAAQ2I,EAAaF,EAAWzI,WAKnDyI,EAAWM,SAC8B,UAArCN,EAAWM,QAAQF,eACfJ,EAAWzI,MAAQ2I,EAAaF,EAAWzI,QAS3DP,GAAGuJ,OAAS,SAASC,GACjB,GAAItE,OAAOO,MAAsD,kBAA9CgB,OAAOC,UAAUC,SAASC,KAAK4C,GAC9C,OAAO,GAIfxJ,GAAGyJ,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAMnJ,KAAO,OAGU4D,SAAnBuF,EAAMG,UACc,mBAATpB,OACa,mBAAbqB,WACoC,SAAnC9J,GAAG+J,oBAAqBC,QAI5ChK,GAAG+J,kBAAoB,WACnB,GAAI7E,OAAO+E,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOC,GAEH,MADAnK,IAAGmG,IAAI,wCAAyC,SACzC,OAIfnG,GAAGoK,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMvE,OAAS,GAC5BsE,EAAaC,MAAM,GAAGC,kBAG9BvK,GAAGwK,wBAA0B,WACzB,OAAQxK,GAAGyK,gBACPzK,GAAGyJ,yBACuBtF,SAAzBsE,KAAK/B,UAAUwB,OAAsD/D,SAA/BsE,KAAK/B,UAAUgE,aAAyDvG,SAA5BsE,KAAK/B,UAAUiE,WAG1G3K,GAAG4K,UAAY,SAASC,EAAYC,EAAOC,GAGvC,OAFaF,EAAW3C,OAAS2C,EAAWF,UAAYE,EAAWH,aAErD9D,KAAKiE,EAAYC,EAAOC,IAG1C/K,GAAGgL,iBAAmB,SAAShE,GAC3B,GAAIiE,GAAa,GACbC,EAAQ,GAAIlF,YAAWgB,EAY3B,OAVAhH,IAAG+C,KAAKmI,EAAO,SAASlI,EAAKmI,GACzB,GAAIC,GAAeD,EAAIxE,SAAS,GAE5ByE,GAAarF,OAAS,IACtBqF,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXjL,GAAGqL,cAAgB,SAASC,EAAMC,EAAaxF,GAC3C,GAAIyF,GAAcxL,GAAG4K,UAAUU,EAAMC,EAAaA,EAAcxF,GAC5D0F,EAAa,GAAIC,YACjBC,EAAU,GAAI3L,IAAG4L,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQ9L,GAAGgL,iBAAiBS,EAAW9I,UAGnD8I,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGX3L,GAAG6B,OAAS,SAASY,EAAOyJ,EAAQC,GAahC,MAZAnM,IAAG+C,KAAKmJ,EAAQ,SAASE,EAAMnJ,GACvBkJ,GAAgBnM,GAAGuG,SAAStD,IACRkB,SAAhB1B,EAAM2J,KACN3J,EAAM2J,OAEVpM,GAAG6B,OAAOY,EAAM2J,GAAOnJ,GAAK,IAG5BR,EAAM2J,GAAQnJ,IAIfR,GAaXzC,GAAGqM,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACAC,EAASF,EAASC,EAUtB,OARAxM,IAAG+C,KAAK0J,EAAQ,SAASC,EAAaC,GACNxI,SAAxBmI,EAAOI,KACPF,EAAOE,GAAeJ,EAAOI,IAGjCJ,EAAOI,GAAeC,IAGnBL,GAMXtM,GAAG2F,QAAU,SAASiH,EAAKC,EAAKC,GAC5B,GAAIF,EAAIjH,QACJ,MAAOiH,GAAIjH,QAAQkH,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAI7G,MAMd,KAJI+G,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIX9M,GAAGiN,YAAc,WACb,MAAO,uCAAuC1K,QAAQ,QAAS,SAAS2K,GAEpE,GAAIC,GAAoB,GAAhBxL,KAAKyL,SAAgB,CAC7B,QADyC,KAALF,EAAWC,EAAS,EAAJA,EAAU,GACrDxG,SAAS,OAM1B3G,GAAGqN,GAAK,WACJ,MAAOC,WAAUC,UAAU5H,QAAQ,WAAY,GAC3C2H,UAAUC,UAAU5H,QAAQ,cAAe,GAGnD3F,GAAGwN,IAAM,WACL,MAAOF,WAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAGyN,IAAM,WACL,MAAOH,WAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAG0N,KAAO,WACN,MAAOJ,WAAUC,UAAU5H,QAAQ,cAAe,GAGtD3F,GAAG2N,KAAO,WACN,MAAO3N,IAAGqN,MAAQC,UAAUC,UAAU5H,QAAQ,YAAa,GAG/D3F,GAAG4N,KAAO,WACN,MAAON,WAAUC,UAAU5H,QAAQ,SAAW,GAGlD3F,GAAG6N,OAAS,WACR,MAA4B1J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,YAAa,GAGnF3F,GAAG+N,OAAS,WACR,MAA4B5J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,aAAc,GAGpF3F,GAAGgO,MAAQ,WACP,MAA4B7J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,YAAa,GAGnF3F,GAAGiO,QAAU,WACT,OAASjO,GAAG4N,SAAW5N,GAAG2N,QAAUL,UAAUC,UAAU5H,QAAQ,cAAe,GAA2BxB,SAArBmJ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrI9N,GAAGkO,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrBnO,GAAGoO,QAAU,WACT,MAAOd,WAAUC,UAAUnE,cAAczD,QAAQ,cAAe,GAKpE3F,GAAGyK,aAAe,WACd,MAAOzK,IAAGoO,WAAad,UAAUC,UAAUnE,cAAczD,QAAQ,UAAY,GAGjF3F,GAAGqO,KAAO,WACN,MAAOrO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAGjE3F,GAAGuO,KAAO,WACN,MAAOvO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAGjE3F,GAAGwO,KAAO,WACN,MAAOxO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAIjE3F,GAAGyO,OAAS,WACR,MAAOzO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,eAAgB,GAGnE3F,GAAGsO,IAAM,WAEL,MAAOhB,WAAUC,UAAU5H,QAAQ,WAAY,GACxC2H,UAAUC,UAAU5H,QAAQ,WAAY,GACxC2H,UAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAG0O,UAAY,WACX,MAAO1O,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,YAAa,GAGhE3F,GAAG2O,UAAY,WACX,MAAO3O,IAAGsO,QAAUtO,GAAG0O,aAAepB,UAAUC,UAAU5H,QAAQ,aAAc,GAGpF3F,GAAG4O,iBAAmB,WAClB,MAAO5O,IAAGsO,QAAUtO,GAAG0O,cAAgB1O,GAAG2O,aAM9C3O,GAAG6O,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxB/O,GAAGgP,UAAa,WACZ,GAAIC,GAAMtF,SAASC,cAAc,MACjC,OAAO,UAASsF,GACZD,EAAIE,UAAYD,CAChB,IAAIjP,GAAUgP,EAAI3L,UAElB,OADA2L,GAAI5N,YAAYpB,GACTA,MAKfD,GAAG+C,KAAO,SAASqM,EAAcC,GAC7B,GAAIC,GAAYC,CAEhB,IAAIH,EAEA,GAAIlK,OAAOsK,SAAWJ,EAAanI,cAAgB/B,OAAOsK,QACtD,IAAKF,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASD,EAAaK,IAAIH,GAAaF,EAAaM,QAAQN,EAAaK,IAAIH,KAClFC,KAAW,GAFoCD,SAStD,IAAItP,GAAG8G,QAAQsI,IAAiBpP,GAAGkH,WAAWkI,IAAiBpP,GAAGoH,WAAWgI,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GAFoCD,SAOtD,IAAItP,GAAGwH,SAAS4H,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASC,EAAYF,EAAaO,OAAOL,IAC9CC,KAAW,GAFoCD,SAQvD,KAAKA,IAAcF,GACf,GAAI3I,OAAOC,UAAUsG,eAAepG,KAAKwI,EAAcE,KACnDC,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GACX,OASxBvP,GAAG4P,KAAO,SAASC,EAASC,GACxB,GAAI9P,GAAG6G,WAAWgJ,GAAU,CACxB,GAAI7H,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,EAElD,OAAO,YACH,GAAI4H,GAAU/P,GAAG6B,UAAWmG,EAI5B,OAHIG,WAAUpC,SACVgK,EAAUA,EAAQC,OAAO/H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,aAEjD0H,EAAQI,MAAMH,EAASC,IAItC,KAAM,IAAIvO,OAAM,wCAmBpBxB,GAAGkQ,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQjO,KAAKiO,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAWpN,KACa,gBAAZuN,GACFzQ,GAAGkQ,QAAQO,EAASE,GAAU,GACe,sBAA5ClK,OAAOC,UAAUC,SAASC,KAAK6J,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAKpO,KAAKiO,GAAU,MAAMjO,KAAKiO,GAAS,GAAK,IAAM,IAC7DE,EAAWpN,KAAKkN,GAChBE,EAAWpN,KAAKlD,GAAGkQ,QAAQC,KACqB,mBAAxC1J,OAAOC,UAAUC,SAASC,KAAKuJ,IAA8C,SAARA,EAC7EnQ,GAAG+C,KAAKoN,EAAK,SAASnN,EAAKC,GACvBuN,EAAIvN,EAAKD,KAEU,SAARmN,GAAiC,OAARA,GAAiC,gBAARA,GACjEnQ,GAAG+C,KAAKoN,EAAK,SAAS/D,EAAMnJ,GACxBuN,EAAIvN,EAAKmJ,KAGbkE,EAAWpN,KAAK0N,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBhO,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7BvC,GAAG8Q,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAIjH,WAGnB9J,GAAG+C,KAAKoN,EAAK,SAASV,EAAKxM,GACvBwM,EAAMuB,EAAeA,EAAe,IAAMvB,EAAM,IAAMA,EAElDzP,GAAGuG,SAAStD,GACZjD,GAAG8Q,aAAa7N,EAAK8N,EAAUtB,GAE1BzP,GAAG6G,WAAW5D,GACnB8N,EAASxL,OAAOkK,EAAKxM,KAGrB8N,EAASxL,OAAOkK,EAAKxM,KAItB8N,GAGX/Q,GAAGiR,WAAa,SAASd,EAAKe,GAC1B,GAAIxH,EAeJ,OAbKwH,KACDA,EAAOvH,SAASC,cAAc,SAGlC5J,GAAG8Q,aAAaX,GACZ5K,OAAQ,SAASkK,EAAKxM,GAClByG,EAAQC,SAASC,cAAc,SAC/BF,EAAMyH,aAAa,OAAQ1B,GAC3B/F,EAAMyH,aAAa,QAASlO,GAC5BiO,EAAKE,YAAY1H,MAIlBwH,GAOXlR,GAAGqR,UAAY,SAASC,MAEpB,MAAIpM,QAAOqM,MAAQvR,GAAG6G,WAAW0K,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjCtR,GAAG0R,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAAS5L,OAAS6L,IAIzD5R,GAAG+R,YAAc,SAASC,GAGtB,MAAIhS,IAAG+I,QAAQiJ,GAEJA,EAAgBjL,MAAMxE,QAAQ,YAAa,IAE7CvC,GAAGuI,OAAOyJ,IACkB,OAA7BA,EAAgBC,UAAkD9N,SAA7B6N,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgBjQ,MAM3B/B,GAAGkS,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIX/R,OAAQ,WACJ,GAAI0H,GAAOG,SAEX9H,MAAKkS,YAAYvS,GAAGgI,EAAK,IAAI1H,OAAO2P,MAAM5P,KAAM4H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,MAI1FoK,YAAa,SAASC,GAClBL,EAAUjP,KAAKsP,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAOzS,MAGY,mBAAX2S,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAU5S,GAGjBD,OAAOC,GAAKA,MCRnB,WACG,YAEAA,IAAGwB,MAAQ,SAAS4E,GAChB/F,KAAK+F,QAAU,kBAAoBpG,GAAG6S,QAAU,KAAOzM,GAG3DpG,GAAGwB,MAAMkF,UAAY,GAAIlF,UCV7BxB,GAAG6S,QAAU,SCAb7S,GAAG8S,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAYrJ,SAASC,cAAc,SACnCoJ,EAAUzS,KAAO,OACjBP,GAAGgT,GAAW9S,OAEV8S,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQpT,GAAG+N,UAAY/N,GAAGgO,UAC+C7J,SAArEmJ,UAAUC,UAAU8F,MAAM,uCAIlC,QAASC,KACL,GAAIpO,OAAO+E,eAAgB,CAIvB,MAA+B9F,UAHrBnE,GAAG+J,oBAGFwJ,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiCrP,UAA1Be,OAAOuO,eAKlB,QAASC,KACL,QAAIJ,KAIGE,IAGX,QAASG,KAEL,MAA2DxP,UAApDwF,SAASC,cAAc,SAASgK,gBAG3C,QAASC,KACL,IACI,QAAS3O,OAAO4O,cAEZ9T,GAAG6G,WAAW3B,OAAO4O,aAAaC,SAE1C,MAAO5J,GAEH,OAAO,GAIf,QAAS6J,KACL,GAAIC,GAAOtK,SAASC,cAAc,OAElC,QAAQ,aAAeqK,IAAS,eAAiBA,IAAQ,UAAYA,MAChEjU,GAAGoO,YAAcpO,GAAGsO,MA1F7B,GAAI4F,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAzCAd,GAAoBnB,IAEpBsB,EAA4BH,GAAqBlU,GAAGyJ,uBAEpD0K,EAAyBE,IAA8BrU,GAAGyK,eAE1D2J,EAAmBC,GAA6BL,IAGhDM,EAAqBF,GAAqB,WACtC,GAAI1K,GAAQC,SAASC,cAAc,QAGnC,OADAF,GAAMnJ,KAAO,UACH,oBAAsBmJ,GAASC,SAAS9G,iBAAiB,oBAAoB,QAG3F0R,EAAmBF,GAA6BrU,GAAGwK,0BAEnDgK,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BjB,IAEtDsB,EAAqBR,IAA6C/P,SAAvBe,OAAO+P,aAA6BZ,GAE/EO,EAA4BtB,IAE5BqB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmDlQ,SAAtBe,OAAOwG,WAE5DsJ,EAA0B,WACtB,QAAIX,KACQrU,GAAGyK,iBAAmBzK,GAAG0O,iBAMrCwG,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiBvQ,OAAOwQ,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAcrW,GAAG6N,SACjByI,0BAA2BtW,GAAGsO,MAC9BiI,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxBzU,GAAG4W,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQ9W,GAAG6G,WAAWgQ,EAAaC,QAG9E9W,GAAG4L,QAAU,WACT,YAEA,IAAImL,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZpX,IAAG6B,OAAOxB,MACNyW,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiB/T,KAAKmU,GAEtBC,GACAJ,EAAiBhU,KAAKoU,IAGrBF,KAAU,EACfE,GAAaA,EAAUrH,MAAM,KAAM+G,GAE9BK,GACLA,EAAUpH,MAAM,KAAM8G,GAGnB1W,MAGXkX,KAAM,SAASlI,GAQX,MAPc,KAAV+H,EACAD,EAAcjU,KAAKmM,GAGnBA,EAASY,MAAM,KAAsB9L,SAAhB6S,EAA4BD,EAAcC,GAG5D3W,MAGXyL,QAAS,WAgBL,MAfAsL,GAAQ,EACRL,EAAc5O,UAEV8O,EAAiBlR,QACjB/F,GAAG+C,KAAKkU,EAAkB,SAASjU,EAAKqM,GACpCA,EAASY,MAAM,KAAM8G,KAIzBI,EAAcpR,QACd/F,GAAG+C,KAAKoU,EAAe,SAASnU,EAAKqM,GACjCA,EAASY,MAAM,KAAM8G,KAItB1W,MAGX2L,QAAS,WAgBL,MAfAoL,IAAQ,EACRJ,EAAc7O,UAEV+O,EAAiBnR,QACjB/F,GAAG+C,KAAKmU,EAAkB,SAASlU,EAAKqM,GACpCA,EAASY,MAAM,KAAM+G,KAIzBG,EAAcpR,QACd/F,GAAG+C,KAAKoU,EAAe,SAASnU,EAAKqM,GACjCA,EAASY,MAAM,KAAM+G,KAItB3W,SC3EnBL,GAAGwX,UAAY,SAASC,EAAeC,GACnC,YAEA1X,IAAG6B,OAAOxB,MACNoX,cAAeA,EAEfE,OAAQ,WACJ,MAAOD,GAASD,OCF5BzX,GAAG4X,aAAe,SAASC,GACvB,YA0CA,SAASC,KACL,GAAIpO,GAAQC,SAASC,cAAc,QAmEnC,OAjEAF,GAAMyH,aAAanR,GAAG4X,aAAaG,oBAAqBC,GACxDtO,EAAMyH,aAAa,QAAS8G,EAAQC,OAEpCC,EAAKC,YAAYH,EAAQpO,SAAUH,GAE/BuO,EAAQI,SAAWrY,GAAG8S,kBAAkB+C,iBAExCnM,EAAMyH,aAAa,kBAAmB,IAGtC8G,EAAQK,aACR5O,EAAMyH,aAAa,SAAU8G,EAAQK,aAGzC5O,EAAMyH,aAAa,OAAQ,QAC3BzH,EAAMyH,aAAa,OAAQ8G,EAAQlW,MAEnC/B,GAAG0J,GAAOpI,KACNiX,SAAU,WAIVC,MAAO,EACPC,IAAK,EACLC,WAAY,QASZC,SAAU3Y,GAAGqN,OAASrN,GAAGyN,MAAQ,SAAW,QAC5CmL,OAAQ,EACRC,QAAS,EACTC,OAAQ,UACRrX,QAAS,KAKZzB,GAAGwN,OAASxN,GAAG0J,GAAOpI,KAAKyX,OAAQ,SAEpCd,EAAQhY,QAAQmR,YAAY1H,GAE5BsP,EAAe1Y,OAAOoJ,EAAO,SAAU,WACnCuO,EAAQgB,SAASvP,KAIrBsP,EAAe1Y,OAAOoJ,EAAO,YAAa,WACtC1J,GAAGiY,EAAQhY,SAASoC,SAAS4V,EAAQiB,cAEzCF,EAAe1Y,OAAOoJ,EAAO,WAAY,WACrC1J,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQiB,cAG5CF,EAAe1Y,OAAOoJ,EAAO,QAAS,WAClC1J,GAAGiY,EAAQhY,SAASoC,SAAS4V,EAAQkB,cAEzCH,EAAe1Y,OAAOoJ,EAAO,OAAQ,WACjC1J,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQkB,cAGrCzP,EA5GX,GAgCIA,GAAOsO,EAhCPG,EAAO9X,KAEP2Y,EAAiB,GAAIhZ,IAAGkS,eAExB+F,GAEIK,YAAa,KAGbrY,QAAS,KAETkZ,WAAY,yBAGZd,SAAS,EAGTa,WAAY,yBAEZE,4BAA4B,EAG5BvP,UAAU,EAGV9H,KAAM,SAGNkX,SAAU,SAASvP,KAEnBwO,MAAO,KAKflY,IAAG6B,OAAOoW,EAASJ,GAEnBG,EAAWhY,GAAGiN,cA2EdjN,GAAGiY,EAAQhY,SAASqB,KAChBiX,SAAU,WACVc,SAAU,SAEVC,UAAW,QAIftZ,GAAG6B,OAAOxB,MACNkZ,SAAU,WACN,MAAO7P,IAGX8P,YAAa,WACT,MAAOxB,IAGXI,YAAa,SAASqB,EAAYC,GAC9B,GAAIhQ,GAAQgQ,GAAYrZ,KAAKkZ,UAKzBtB,GAAQmB,4BAA8BpZ,GAAGwO,SAAWxO,GAAG0O,aAAe1O,GAAG4O,oBACzElF,EAAMyH,aAAa,WAAY,IAI3BsI,EACA/P,EAAMyH,aAAa,WAAY,IAG/BzH,EAAMiQ,gBAAgB,aAKlCC,eAAgB,SAAStB,GACjBA,IAAgBL,EAAQK,aACxB5O,EAAMyH,aAAa,SAAUmH,IAIrCuB,MAAO,WACCnQ,EAAMvI,YACNnB,GAAG0J,GAAOtI,SAGdpB,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQkB,YACxCzP,EAAQ,KACRA,EAAQoO,OAIhBpO,EAAQoO,KAGZ9X,GAAG4X,aAAaG,oBAAsB,eCxLtC/X,GAAG8Z,WAAa,SAASC,GACrB,YAQA,SAASC,GAAaC,GAClB,GAAIja,GAAG8G,QAAQmT,GAAU,CACrB,GAAIC,KAMJ,OAJAla,IAAG+C,KAAKkX,EAAS,SAASjX,EAAKmX,GAC3BD,EAAQhX,KAAK8B,EAAKmV,MAGfD,EAGX,MAAOlV,GAAKiV,GAGhB,QAASG,GAAeC,GACpB,GAAIra,GAAG8G,QAAQuT,GAAQ,CACnB,GAAIH,KAMJ,OAJAla,IAAG+C,KAAKsX,EAAO,SAASrX,EAAKsX,GACzBJ,EAAQhX,KAAK8B,EAAKuV,EAAOD,OAGtBJ,EAGX,MAAOlV,GAAKuV,EAAOF,IAGvB,QAASG,GAAgBC,GACrB,GAAIC,MACAC,KAAc3K,OAAOyK,EAYzB,OAVAza,IAAG+C,KAAK4X,EAAU,SAASC,EAAOC,GAC9B,GAAIC,GAAsBC,EAASF,EAEP1W,UAAxB2W,GACA9a,GAAG+C,KAAK+X,EAAqB,SAASpK,EAAGsK,GACrCN,EAAcxX,KAAK8B,EAAKgW,QAK7BN,EAhDX,GAAI1V,MACAuV,KACAQ,KACAE,KACAC,IA+CJlb,IAAG6B,OAAOxB,MAgBN8a,QAAS,SAASC,GACd,GAAIX,GAASW,EAAKX,QAAUza,GAAGya,OAAOY,WAClClB,EAAKnV,EAAK9B,MACNnB,KAAMqZ,EAAKrZ,KACXuZ,aAAcF,EAAKrZ,KACnBuY,KAAMc,EAAKd,KACXiB,KAAmB,MAAbH,EAAKG,MAAe,EAAKH,EAAKG,KACpCd,OAAQA,EACRe,KAAMJ,EAAKI,OACV,CA+BT,OA7BIJ,GAAKK,UACLzW,EAAKmV,GAAIsB,QAAUL,EAAKK,QAEQtX,SAA5B+W,EAAUE,EAAKK,WACfP,EAAUE,EAAKK,aAEnBP,EAAUE,EAAKK,SAASvY,KAAKiX,IAG7BiB,EAAKM,eACL1W,EAAKmV,GAAIuB,aAAeN,EAAKM,aAEavX,SAAtC8W,EAAeG,EAAKM,gBACpBT,EAAeG,EAAKM,kBAExBT,EAAeG,EAAKM,cAAcxY,KAAKiX,IAG3CnV,EAAKmV,GAAIA,GAAKA,EACdI,EAAOa,EAAKd,MAAQH,EAEKhW,SAArB4W,EAASN,KACTM,EAASN,OAEbM,EAASN,GAAQvX,KAAKiX,GAEtBiB,EAAKO,sBAAwBP,EAAKO,qBAAqBxB,GACvDJ,EAAc6B,eAAezB,EAAI,KAAMM,GAEhCN,GAGX0B,SAAU,SAASC,GACf,MAAI9b,IAAGuG,SAASuV,IAAmB9W,EAAKe,OACV5B,SAAtB2X,EAAe3B,GACRH,EAAa8B,EAAe3B,IAGNhW,SAAxB2X,EAAexB,KACbF,EAAe0B,EAAexB,MAGhCwB,EAAerB,OACbD,EAAgBsB,EAAerB,QADrC,OAKEza,GAAG6B,UAAWmD,GAAM,IAInC+W,cAAe,SAAS5B,GACpB,GAAI6B,GAAShC,EAAaG,EAEtB6B,UACOA,GAAOR,MAItB3B,MAAO,WACH7U,KACAuV,KACAQ,KACAG,MAGJe,UAAW,SAAS9B,EAAI+B,GACpB,GAAIC,GAAYnX,EAAKmV,GAAIM,OACrB2B,EAAyBpc,GAAG2F,QAAQoV,EAASoB,GAAYhC,EAE7DY,GAASoB,GAAWE,OAAOD,EAAwB,GAEnDpX,EAAKmV,GAAIM,OAASyB,EAEU/X,SAAxB4W,EAASmB,KACTnB,EAASmB,OAEbnB,EAASmB,GAAWhZ,KAAKiX,GAEzBJ,EAAc6B,eAAezB,EAAIgC,EAAWD,IAGhDI,YAAa,SAASnC,EAAIoC,GACtB,GAAIC,GAAUxX,EAAKmV,GAAIG,IAEvBtV,GAAKmV,GAAIG,KAAOiC,EAChBhC,EAAOgC,GAAWpC,QACXI,GAAOiC,IAGlBC,WAAY,SAAStC,EAAIuC,GACrB1X,EAAKmV,GAAIpY,KAAO2a,GAGpBC,WAAY,SAASxC,EAAIyC,GACrB5X,EAAKmV,GAAIoB,KAAOqB,GAIpBC,YAAa,SAASC,EAAUC,GAC5B/X,EAAK8X,GAAUC,SAAWA,GAG9BC,mBAAoB,SAAS7C,GACzB,GAAIuB,GAAe1W,EAAKmV,GAAIuB,YAE5B,OAAIA,GACOT,EAAeS,OAK9BuB,cAAe,SAAS9C,GAGpB,MAAOe,GAFOlW,EAAKmV,GAAIsB,aAOnCzb,GAAGya,QACCY,WAAY,aACZ6B,UAAW,YACXC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,UAAW,YACXC,kBAAmB,oBACnBC,gBAAiB,kBACjBC,kBAAmB,oBACnBC,cAAe,gBACfC,cAAe,gBACfC,SAAU,WACVC,QAAS,WCpNZ,WACG,YAEA9d,IAAG+d,eAECC,SAAU,SAASC,EAAiBC,EAAQC,GACxC9d,KAAK+d,SAASH,EAAiBC,EAAQC,IAG3CE,gBAAiB,SAASC,GACtB,GAAInG,GAAO9X,IAEXL,IAAG+C,KAAKub,EAAgB,SAAS1D,EAAO2D,GACpCpG,EAAKqG,eAAeD,MAI5BH,SAAU,SAASpZ,EAAMkZ,EAAQC,GAC7B9d,KAAKoe,kCAEL,IAAIhD,GAAqC,IAA3Bpb,KAAKqe,WAAW3Y,OAAe/F,GAAGiN,cAAgB5M,KAAKse,gBAEjEC,EAAc5e,GAAG4P,KAAK,SAAStE,GAC3BjL,KAAKwe,gBACDvT,KAAMA,EACNvJ,KAAM1B,KAAKye,SAASC,MAAMC,aAC3BvD,EAASwD,IACb5e,MAEH6e,EAAkBlf,GAAG4P,KAAK,SAASuP,GAC/B9e,KAAKwe,eAAeM,EAAU1D,EAASwD,IACxC5e,MAEH+e,EAAgBpf,GAAG4P,KAAK,SAASvL,GAC7B,GAAIiH,GAAOtL,GAAGoE,aAAaC,EAE3BhE,MAAKwe,gBACDvT,KAAMA,EACNvJ,KAAM1B,KAAKye,SAASC,MAAMC,YAAc,QACzCvD,EAASwD,IACb5e,MAEHgf,EAAoBrf,GAAG4P,KAAK,SAAS0P,GACjC,GAAIC,GAAoBD,EAAW/a,SAAW+a,EAAW/a,QAAU,IAC/D+G,EAAOtL,GAAGoE,aAAakb,EAAWjb,OAAQib,EAAW/e,KAAMgf,EAE/Dlf,MAAKwe,gBACDvT,KAAMA,EACNvJ,KAAMud,EAAWvd,MAClB0Z,EAASwD,IACb5e,MAEHmf,EAAqBxf,GAAG4P,KAAK,SAAS6P,GAClC,GAAIzf,GAAG+I,QAAQ0W,IAAgBzf,GAAG8S,kBAAkBoC,cAAe,CAC/D,GAAIwK,GAAQzX,MAAMvB,UAAUwB,MAAMtB,KAAK6Y,EAAYC,OAC/CvH,EAAO9X,IAEXL,IAAG+C,KAAK2c,EAAO,SAAS1c,EAAKwY,GACzBrD,EAAK0G,eAAerD,EAAMC,EAASwD,SAIvC5e,MAAKwe,eAAeY,EAAahE,EAASwD,IAE/C5e,MAEHsf,EAAgB,WACR3f,GAAG0I,WAAW1D,KACdA,EAAOiD,MAAMvB,UAAUwB,MAAMtB,KAAK5B,IAEtCA,KAAUgL,OAAOhL,IAGrBmT,EAAO9X,KACP4e,IAEJ5e,MAAKse,gBAAkBlD,EAEnBzW,IACA2a,IAEA3f,GAAG+C,KAAKiC,EAAM,SAAShC,EAAK4c,GACpB5f,GAAG6I,cAAc+W,GACjBJ,EAAmBI,GAEd5f,GAAGuJ,OAAOqW,GACfhB,EAAYgB,GAEP5f,GAAGuG,SAASqZ,GACbA,EAActU,MAAQsU,EAAc7d,KACpCmd,EAAgBU,GAEXA,EAAcvb,QAAUub,EAAc7d,MAC3Csd,EAAkBO,GAGjBA,EAActW,SAAmD,WAAxCsW,EAActW,QAAQF,cACpDgW,EAAcQ,GAGdzH,EAAKhS,IAAIyZ,EAAgB,6CAA8C,UAI/Evf,KAAK8F,IAAI,YAAc8Y,EAAclZ,OAAS,WAC9C1F,KAAKwf,uBAAuBZ,EAAef,EAAQC,KAI3D2B,OAAQ,SAAS3F,GACb,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAE5C4F,IAAcA,EAAWtF,SAAWza,GAAGya,OAAO+C,kBAC9Cnd,KAAK8F,IAAInG,GAAG8H,OAAO,2DAA4DqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,SAGtG9Z,KAAK6f,SAASJ,OAAO3F,IAI7BgG,UAAW,WACP,GAAIC,MACAjI,EAAO9X,IAEXL,IAAG6B,OAAOue,EAAe/f,KAAKqe,YAC9B1e,GAAG+C,KAAKqd,EAAe,SAASpd,EAAKqd,GACjClI,EAAK2H,OAAOO,KAGhBhgB,KAAK6f,SAASC,aAGlBG,iBAAkB,WACdjgB,KAAKqe,eAGT6B,eAAgB,SAASpG,GACrB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAEhD,UAAKna,GAAG8S,kBAAkBmD,QAAU5V,KAAKye,SAASzJ,SAASmL,WAIvDT,EAAWtF,SAAWza,GAAGya,OAAO6C,QAChCjd,KAAK8F,IAAInG,GAAG8H,OAAO,yDAA0DqS,EAAI9Z,KAAK4f,QAAQ9F,KAC9F9Z,KAAKogB,YAAYtG,IACV,IAGP9Z,KAAK8F,IAAInG,GAAG8H,OAAO,sDAAuDqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,UAG9F,KAGXuG,WAAY,SAASvG,GACjB,MAAO9Z,MAAKsgB,gBAAgBxG,IAIhCyG,UAAW,SAASC,GAChB,MAAOxgB,MAAK6f,SAASY,QAAQD,IAOjCE,cAAe,SAASC,EAAQC,EAAaC,EAASC,EAAYC,GAC9D,GACIC,GAAWpJ,EADXqJ,EAAkB,GAAIthB,IAAG4L,OAqC7B,OAlCIvL,MAAKkhB,iBACLF,EAAYhhB,KAAKmhB,eAAeR,GAChC/I,GACImJ,qBAAsBA,EACtBF,QAASA,EAAU,EAAIA,EAAU,KACjCO,MAAOP,EAAU,IAKhBC,GAAcnhB,GAAG8S,kBAAkBgD,gBACpCuL,EAAYhhB,KAAKqhB,QAAQV,IAIZ,MAAbK,EACAC,EAAgBtV,SAAS2V,UAAWV,EAAa9W,MAAO,2BAGxD9J,KAAKkhB,gBAAgBK,SAASP,EAAWJ,EAAahJ,GAASnB,KAC3D,SAAiB+K,GACbP,EAAgBxV,QAAQ+V,IAG5B,SAAiBF,EAAWG,GACxBR,EAAgBtV,SAAS2V,UAAWA,EAAWxX,MAAO2X,GAAU,oCAM5ER,EAAgBtV,SAAS2V,UAAWV,EAAa9W,MAAO,mCAGrDmX,GAGXS,UAAW,SAASf,GAChB,MAAO3gB,MAAK2hB,WAAW3hB,KAAK4hB,qBAAqBjB,KAGrDkB,YAAa,SAASlB,GAClB,MAAO3gB,MAAK8hB,eAAeC,IAAIpB,IAGnCU,QAAS,SAASb,GACd,GACIwB,GADA7G,EAAOnb,KAAK6f,SAASwB,QAAQb,EAWjC,OARKrF,KACD6G,EAAmBhiB,KAAK2f,YAAYnE,UAAU1B,GAAI0G,IAE9CwB,IACA7G,EAAO6G,EAAiB7G,OAIzBA,GAAQ,MAGnB8G,cAAe,WACX,MAAOjiB,MAAK2f,YAAYnE,UACpBpB,QACIza,GAAGya,OAAO8C,UACVvd,GAAGya,OAAOgD,gBACVzd,GAAGya,OAAO2C,UAEfrX,QAGPka,QAAS,SAAS9F,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKpY,MAI/CwgB,YAAa,SAASpI,GAClB,GAAIqI,GAAkBniB,KAAKoiB,YAAYtI,GAAIA,IACvC4C,EAAW,IAQf,OANIyF,IACiCre,SAA7Bqe,EAAgBzF,WAChBA,EAAWyF,EAAgBzF,UAI5BA,GAGX2F,sBAAuB,WACnB,MAAOriB,MAAK6f,SAASwC,yBAGzBC,QAAS,SAASxI,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKoB,MAG/CqH,cAAe,WACX,MAAOviB,MAAKwiB,cAGhBC,yBAA0B,WACtB,GAAIC,GAAe1iB,KAAK2iB,iBAExB,OAAID,GAAe,EACRA,EAAe1iB,KAAK4iB,qBAGxB,MAGXR,WAAY,SAAS3G,GACjB,MAAOzb,MAAK2f,YAAYnE,SAASC,IAGrCoH,QAAS,SAAS/I,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKG,MAG/C6I,YAAa,SAAShJ,GAClB,MAAO9Z,MAAK6f,SAASkD,gBAAgBjJ,IAGzChU,IAAK,SAAS4B,EAAK1B,IACXhG,KAAKye,SAASuE,OAAWhd,GAAmB,SAAVA,EAG7BA,GAAmB,SAAVA,GACdrG,GAAGmG,IAAI,kBAAoBnG,GAAG6S,QAAU,KAAO9K,EAAK1B,GAHpDrG,GAAGmG,IAAI,kBAAoBnG,GAAG6S,QAAU,KAAO9K,IAQvDub,YAAa,SAASnJ,GAClB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAEhD,KAAKna,GAAG8S,kBAAkBmD,QAAU5V,KAAKye,SAASzJ,SAASmL,QACvD,OAAO,CAIX,IAAIxgB,GAAG2F,SAAS3F,GAAGya,OAAO8C,UAAWvd,GAAGya,OAAOgD,iBAAkBsC,EAAWtF,SAAW,EAAG,CACtF,GAAIpa,KAAK6f,SAASjK,MAAMkE,GAEpB,MADA9Z,MAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO6C,SAClC,CAGPjd,MAAK8F,IAAInG,GAAG8H,OAAO,mCAAoCqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,aAIlF9Z,MAAK8F,IAAInG,GAAG8H,OAAO,wDAAyDqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,QAGvG,QAAO,GAGX4B,cAAe,SAAS5B,GACpB9Z,KAAK6f,SAASqD,QAAQpJ,GACtB9Z,KAAK2f,YAAYjE,cAAc5B,IAGnCN,MAAO,WACHxZ,KAAK8F,IAAI,yBAET9F,KAAK6f,SAASrG,QACdxZ,KAAKqe,cACLre,KAAKmjB,gBACLnjB,KAAKojB,kBACLpjB,KAAKqjB,mBACLrjB,KAAKmhB,kBAELxhB,GAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjCA,EAAO/J,UAGXxZ,KAAKwjB,aAAahK,QAClBxZ,KAAK8hB,eAAetI,QACpBxZ,KAAK4iB,qBAAuB,EAC5B5iB,KAAKwiB,aAAe,EACpBxiB,KAAK2f,YAAYnG,QACjBxZ,KAAK4hB,wBAEL5hB,KAAKyjB,eAAiBzjB,KAAKyjB,cAAcjK,QACzCxZ,KAAKye,SAASiF,QAAQC,gBAAkB3jB,KAAK4jB,sBAE7C5jB,KAAK6jB,kCACL7jB,KAAK8jB,+BAEL9jB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAevK,QAE3CxZ,KAAKgkB,uBAAuBxK,SAGhCyK,MAAO,SAASnK,GACZ,MAAO9Z,MAAKkkB,aAAapK,IAG7BqK,WAAY,SAASrK,EAAIsK,GACrB,GAAItM,GAAO9X,IAEX,OAAOL,IAAG0kB,OAAOhe,UAAU8d,WAAWrK,EAAIsK,GACtCte,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvBuJ,QAAS1hB,GAAG4P,KAAKuI,EAAKuJ,QAASvJ,GAC/B4H,WAAY5H,EAAK6H,eAIzB2E,iBAAkB,SAASC,EAASzK,GAChC9Z,KAAKwkB,oBAAoBC,IAAIF,EAASzK,IAG1C4K,oBAAqB,SAAS5K,EAAInV,GAC9B3E,KAAKgkB,uBAAuBS,IAAI9f,EAAMmV,IAG1C6K,2BAA4B,SAASJ,EAASzK,GAC1C9Z,KAAK4kB,8BAA8BH,IAAIF,EAASzK,IAGpD+K,sBAAuB,SAAS/G,EAAUhE,GACtC9Z,KAAK8kB,yBAAyBL,IAAI3G,EAAUhE,IAGhDiL,oBAAqB,SAASlH,EAAQ/D,GAClC9Z,KAAKglB,uBAAuBP,IAAI5G,EAAQ/D,IAI5CmL,YAAa,SAASnH,EAAUhE,GAC5B9Z,KAAK8hB,eAAe2C,IAAI3G,EAAUhE,IAGtCoL,QAAS,SAASC,GACdnlB,KAAKolB,4BAA4BD,IAGrCE,aAAc,SAASC,GACnBtlB,KAAK2iB,kBAAoB2C,GAG7BC,QAAS,SAASzL,EAAIuC,GAClBrc,KAAK2f,YAAYvD,WAAWtC,EAAIuC,IAGpCmJ,UAAW,SAAS3H,EAAQ/D,GACxB9Z,KAAKwjB,aAAaiB,IAAI5G,EAAQ/D,IAGlC2L,QAAS,SAAS3L,EAAIoC,GAClB,MAAOlc,MAAK2f,YAAY1D,YAAYnC,EAAIoC,IAY5CN,UAAW,SAAS9B,EAAI+B,GAEpB,IADiB7b,KAAKoiB,YAAYtI,GAAIA,IAElC,KAAM,IAAIna,IAAGwB,MAAM2Y,EAAK,2BAG5B,QAAQ+B,GACJ,IAAKlc,IAAGya,OAAOqD,QACXzd,KAAK0lB,kBAAkB5L,EAAI,MAAM,EACjC,MACJ,KAAKna,IAAGya,OAAOmD,cACXvd,KAAK0lB,kBAAkB5L,EAAI,MAAM,EACjC,MACJ,SACI,GAAI6L,GAAe,+BAAiCjkB,KAAO,6BAA+Bma,CAE1F,MADA7b,MAAK8F,IAAI6f,GACH,GAAIhmB,IAAGwB,MAAMwkB,KAI/BC,kBAAmB,WACgB,IAA3B5lB,KAAKqe,WAAW3Y,OAChB1F,KAAK6lB,WAAW,gBAGhB7lB,KAAK8lB,uBAQjBnmB,GAAGomB,gBAEC5H,eAAgB,SAAS6H,GACrB,GAAIlO,GAAO9X,IAEX,OAAOA,MAAK2f,YAAY7E,SACpBb,KAAM+L,EAAY/L,KAClBvY,KAAMskB,EAAYtkB,KAClBwZ,KAAM8K,EAAY9K,KAClBd,OAAQza,GAAGya,OAAOiD,kBAClB/B,qBAAsB,SAASxB,GAC3BkM,EAAYC,oBAAsBnO,EAAK+M,sBAAsBmB,EAAYC,mBAAoBnM,GAC7FkM,EAAYE,kBAAoBpO,EAAKiN,oBAAoBiB,EAAYE,iBAAkBpM,GAEnFkM,EAAYG,eACZrO,EAAKqJ,eAAerH,GAAMkM,EAAYG,cAG1CrO,EAAK0K,eACL1K,EAAK8K,2BAKjBwD,sBAAuB,SAASjL,EAAMkL,GAC9B1mB,GAAGuI,OAAOiT,KACVA,EAAKmL,WAAatmB,KAAKumB,aAAaF,KAI5CG,YAAa,SAASzgB,GAClB/F,KAAKye,SAASgI,UAAUC,QAAQ,KAAM,KAAM3gB,EAASjC,SAGzD6iB,qBAAsB,WAClB,GAAI7O,GAAO9X,IAEX,OAAO,IAAIL,IAAGinB,yBACVC,OAAQ7mB,KAAKye,SAAS4B,WAAWwG,OAAOC,cACxCC,eAAgB/mB,KAAKye,SAASsI,eAC9BC,cAAehnB,KAAKye,SAASwI,QAAQC,SACrCC,cAAennB,KAAK4kB,8BACpBwC,YAAapnB,KAAKglB,uBAClBqC,cAAernB,KAAK8kB,yBACpBwC,KAAMtnB,KAAKye,SAAS6I,KACpBxhB,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvByP,SAAU,SAASzN,GACfhC,EAAK0P,UAAU1N,GACfhC,EAAK2G,SAASgI,UAAUc,SAASzN,IAErC2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,GACrC7P,EAAK4N,kBAAkB5L,EAAI4N,EAAUC,GACrC7P,EAAK2G,SAASgI,UAAUgB,iBAAiB3N,EAAI4N,EAAUC,OAMnEC,oBAAqB,WACjB,GAAI9P,GAAO9X,IAEX,OAAO,IAAIL,IAAGkoB,cACVC,cAAe9nB,KAAKye,SAASsJ,MAAMD,cACnCrB,WACI3gB,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvBkQ,cAAe,SAAS/c,GACpB6M,EAAKmQ,wBACDvmB,KAAM,kBACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAUyB,gBAAiBpQ,EAAM7M,GACjE+L,UAAWrX,GAAG4P,KAAKuI,EAAKqQ,oBAAqBrQ,EAAM7M,GACnDmd,WAAY,sBAOhCC,aAAc,SAASC,EAAcC,GACjC,GAAIC,MACAC,EAAWH,EACXI,KACAC,EAAiBJ,EACjBK,EAAO,SAASC,GACZ,MAAIlpB,IAAGuG,SAAS2iB,GACLlpB,GAAG6B,UAAWqnB,GAElBA,GAEXC,EAAoB,WAChB,MAAInpB,IAAG6G,WAAWmiB,GACPA,IAEJA,GAEXI,EAAwB,SAASjP,EAAIkP,GAC7BL,GAAkBhpB,GAAGuG,SAAS8iB,IAC9BrpB,GAAG6B,OAAOwnB,EAAUF,KAGpBJ,EAAoB5O,IACpBna,GAAG6B,OAAOwnB,EAAUN,EAAoB5O,IAIpD,QACI2K,IAAK,SAAS7hB,EAAKkX,GAEL,MAANA,GACA0O,KACAC,EAAWG,EAAKhmB,IAGhB4lB,EAAM1O,GAAM8O,EAAKhmB,IAIzBmf,IAAK,SAASjI,GACV,GAAImP,EAYJ,OARIA,GADM,MAANnP,GAAc0O,EAAM1O,GACX0O,EAAM1O,GAGN8O,EAAKH,GAGlBM,EAAsBjP,EAAImP,GAEnBL,EAAKK,IAGhBC,YAAa,SAASpP,EAAImP,GAElBtpB,GAAGuG,SAASsiB,KAED,OAAP1O,EACIna,GAAG6G,WAAWyiB,GACdN,EAAiBM,GAGjBN,EAAiBA,MACjBhpB,GAAG6B,OAAOmnB,EAAgBM,KAI9BP,EAAoB5O,GAAM4O,EAAoB5O,OAC9Cna,GAAG6B,OAAOknB,EAAoB5O,GAAKmP,MAK/CloB,OAAQ,SAAS4f,GACb,aAAc6H,GAAM7H,IAGxBnH,MAAO,WACHgP,KACAE,KACAD,EAAWH,KAKvBa,yBAA0B,WACtB,GAAIrR,GAAO9X,IAEX,OAAO,IAAIL,IAAG8Z,YACVmG,QAAS,SAAS9F,GACd,MAAOhC,GAAK8H,QAAQ9F,IAExB+I,QAAS,SAAS/I,GACd,MAAOhC,GAAK+K,QAAQ/I,IAExBwI,QAAS,SAASxI,GACd,MAAOhC,GAAKwK,QAAQxI,IAExByB,eAAgB,SAASzB,EAAIgC,EAAWD,GACpC/D,EAAKsR,sBAAsBtP,EAAIgC,EAAWD,GAC1C/D,EAAK2G,SAASgI,UAAUlL,eAAezB,EAAIgC,EAAWD,GACtD/D,EAAKuR,kBAAkBvP,EAAI+B,GAEvB/D,EAAKiM,gBACLuF,WAAW,WACPxR,EAAKiM,eAAexI,eAAezB,EAAIgC,EAAWD,IACnD,OAcnB0N,oBAAqB,SAASxO,GAM1B,QAASyO,KACL,QAAI7pB,GAAG8S,kBAAkBoC,kBAEjBiD,EAAK2G,SAASgL,YAAYC,gBAC1B/pB,GAAGsO,QACFtO,GAAGqO,QACJ8J,EAAK6R,oBAAoBC,EAAmB,WAK1B9lB,SAAlBiX,EAAKvR,SACEsO,EAAK2G,SAASjV,SAGlBuR,EAAKvR,WApBpB,GAGI+Z,GAHAzL,EAAO9X,KACPiY,EAAc8C,EAAK8O,QAAU7pB,KAAKye,SAASqL,WAAW7R,YACtD2R,EAAoB7O,EAAK6O,mBAAqB5pB,KAAKye,SAASqL,WAAWF,iBA6C3E,OArBArG,GAAS,GAAI5jB,IAAG4X,cACZU,YAAaA,EACbrY,QAASmb,EAAKnb,QACdkZ,WAAY9Y,KAAKye,SAASsL,QAAQC,YAClChS,QAAS+C,EAAK/C,QACda,WAAY7Y,KAAKye,SAASsL,QAAQE,YAClClR,2BAA4B/Y,KAAKye,SAASgL,YAAYS,iBACtD1gB,SAAUggB,IACV9nB,KAAM1B,KAAKye,SAASwI,QAAQkD,UAC5BvR,SAAU,SAASvP,GACfyO,EAAKsS,eAAe/gB,IAExBwO,MAAqB,MAAdkD,EAAKlD,MAAgB7X,KAAKye,SAASpb,KAAKgnB,eAAiBtP,EAAKlD,QAGzE7X,KAAKsqB,gBAAgBpY,YAAY,WAC7BqR,EAAOxR,YAGX+F,EAAKwL,SAASzgB,KAAK0gB,GAEZA,GAGXgH,qBAAsB,SAASC,EAAmBC,GAC9C,GAAI3S,GAAO9X,KACP0qB,KACA9S,GACIoL,MAAOhjB,KAAKye,SAASuE,MACrB+D,eAAgB/mB,KAAKye,SAASsI,eAC9BO,KAAMtnB,KAAKye,SAAS6I,KACpBF,YAAapnB,KAAKwjB,aAClB6D,cAAernB,KAAK8hB,eACpB9M,SAAUhV,KAAKye,SAASzJ,SACxBc,OAAQ9V,KAAKye,SAAS3I,OACtB4I,MAAO1e,KAAKye,SAASC,MACrB5Y,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvB6S,kBAAmB3qB,KAAKye,SAASwF,MAAM2G,6BACvCC,WAAY,SAAS/Q,EAAIpY,EAAMopB,EAAQC,GAC/BD,EAAS,GAAKC,EAAQ,IAItBL,EAAe5Q,GACX4Q,EAAe5Q,GAAIgR,SAAWA,GAAUJ,EAAe5Q,GAAIiR,QAAUA,IACrEjT,EAAKkT,YAAYlR,EAAIpY,EAAMopB,EAAQC,GACnCjT,EAAK2G,SAASgI,UAAUoE,WAAW/Q,EAAIpY,EAAMopB,EAAQC,KAIzDjT,EAAKkT,YAAYlR,EAAIpY,EAAMopB,EAAQC,GACnCjT,EAAK2G,SAASgI,UAAUoE,WAAW/Q,EAAIpY,EAAMopB,EAAQC,IAGzDL,EAAe5Q,IAAOgR,OAAQA,EAAQC,MAAOA,KAGjDE,WAAY,SAASnR,EAAIpY,EAAMY,EAAQ4oB,SAC5BR,GAAe5Q,EAEtB,IACI5K,GADAkL,EAAStC,EAAKsK,YAAYtI,GAAIA,IAAKM,MAOnCA,KAAWza,GAAGya,OAAOiD,mBAAqBjD,IAAWza,GAAGya,OAAOkD,gBAInEpO,EAAS4I,EAAKqT,YAAYrR,EAAIpY,EAAMY,EAAQ4oB,GAIxChc,YAAmBvP,IAAG4L,QACtB2D,EAAOgI,KAAK,WACRY,EAAK2G,SAASgI,UAAUwE,WAAWnR,EAAIpY,EAAMY,EAAQ4oB,KAIzDpT,EAAK2G,SAASgI,UAAUwE,WAAWnR,EAAIpY,EAAMY,EAAQ4oB,KAG7DE,SAAU,SAAStR,EAAIpY,EAAM2pB,GACzB,GAAI/f,GAAU,GAAI3L,IAAG4L,OAgBrB,OAdAuM,GAAKmQ,wBACDvmB,KAAM,WACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAU2E,SAAUtT,EAAMgC,EAAIpY,GAC9DuV,UAAW3L,EAAQK,QACnBqL,UAAW,WACPqU,EAAyB5U,KAAK,WAC1BqB,EAAKwT,UAAUxR,EAAIpY,KAGvB4J,EAAQG,WAEZ2c,WAAYtO,IAGTxO,GAEXigB,aAAc5rB,GAAG4P,KAAKvP,KAAKwrB,cAAexrB,MAC1CyrB,SAAU,SAAS3R,EAAIpY,GACnBoW,EAAK4T,UAAU5R,EAAIpY,EACnB,IAAIiqB,GAAiB7T,EAAK2G,SAASgI,UAAUgF,SAAS3R,EAAIpY,EAE1D,OAAI/B,IAAG4W,iBAAiBoV,IACpB7T,EAAKhS,IAAInG,GAAG8H,OAAO,+DAAgEqS,IAC5E6R,IAGJ,GAAIhsB,IAAG4L,SAAUE,WAE5BmgB,cAAe,SAAS9R,EAAIpY,EAAMmqB,GAC9B/T,EAAKgU,eAAehS,EAAI+R,EACxB,IAAIE,GAAsBjU,EAAK2G,SAASgI,UAAUmF,cAAc9R,EAAIpY,EAAMmqB,EAE1E,OAAIlsB,IAAG4W,iBAAiBwV,IACpBjU,EAAKhS,IAAInG,GAAG8H,OAAO,uEAAwEqS,EAAI+R,EAAUG,YAClGD,IAGJ,GAAIpsB,IAAG4L,SAAUE,WAE5BwgB,qBAAsB,SAASnS,EAAI+R,EAAWvpB,EAAQ4oB,GAClDpT,EAAKoU,sBAAsBpS,EAAI+R,GAC/B/T,EAAK2G,SAASgI,UAAUwF,qBAAqBrc,MAAMkI,EAAMhQ,YAE7DqkB,SAAU,SAASrS,EAAIpY,EAAMmqB,EAAWO,GACpC,MAAOtU,GAAK2G,SAASgI,UAAU0F,SAASrS,EAAIpY,EAAMmqB,EAAWO,IAEjEC,YAAa,SAASvS,EAAIpY,EAAM4qB,EAAcpB,GAC1C,MAAOpT,GAAKyU,aAAa3c,MAAMkI,EAAMhQ,YAEzC0kB,cAAe,SAAS1S,EAAIoC,GACxBpE,EAAKhS,IAAI,sCAAwCgS,EAAK+K,QAAQ/I,GAAM,SAAWoC,EAAU,KACzFpE,EAAK2N,QAAQ3L,EAAIoC,IAErB0D,QAASjgB,GAAG4P,KAAKuI,EAAK8H,QAAS9H,GAC/B+K,QAASljB,GAAG4P,KAAKuI,EAAK+K,QAAS/K,GAC/BwK,QAAS3iB,GAAG4P,KAAKuI,EAAKwK,QAASxK,GAC/B2U,QAAS9sB,GAAG4P,KAAKuI,EAAK4U,SAAU5U,GAChC6U,cAAe,SAAS1S,GACpB,MAAOnC,GAAKsK,YAAYnI,KAAMA,KAElC2S,SAAU,SAAS9S,GACf,GAAIM,GAAStC,EAAKsK,YAAYtI,GAAIA,IAAKM,MACvC,OAAOA,KAAWza,GAAGya,OAAO2C,QACxB3C,IAAWza,GAAGya,OAAOyC,WACrBzC,IAAWza,GAAGya,OAAOgD,iBACrBhD,IAAWza,GAAGya,OAAO6C,QAE7BN,mBAAoB7E,EAAK6H,YAAYhD,mBACrCC,cAAe9E,EAAK6H,YAAY/C,cAChCiQ,aAAc,SAAS/S,GACnB,MAAOhC,GAAKsK,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAO8C,WAE1D4P,oBAAqBntB,GAAG4P,KAAKuI,EAAKiV,qBAAsBjV,GACxD8D,UAAW,SAAS9B,EAAIM,GACpBtC,EAAK6H,YAAY/D,UAAU9B,EAAIM,IAgB3C,OAZAza,IAAG+C,KAAK1C,KAAKye,SAASwI,QAAS,SAASlb,EAAMnJ,GAC1CgV,EAAQ7L,GAAQnJ,IAGpBgV,EAAQuP,cAAgBnnB,KAAKwkB,oBAEzBgG,GACA7qB,GAAG+C,KAAK8nB,EAAmB,SAASpb,EAAKxM,GACrCgV,EAAQxI,GAAOxM,IAIhB,GAAIjD,IAAGqtB,wBAAwBpV,EAAS6S,IAGnDwC,oBAAqB,SAASnT,GAC1B9Z,KAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO0C,WAG7CoQ,YAAa,SAASriB,GAClB,GAAc,IAAVA,EACA,MAAOA,GAAQ7K,KAAKye,SAASpb,KAAK8pB,YAAY,EAElD,IAAI9c,IAAI,CACR,GACIxF,IAAgB,IAChBwF,UACKxF,EAAQ,IAEjB,OAAOvJ,MAAK8rB,IAAIviB,EAAO,IAAKwiB,QAAQ,GAAKrtB,KAAKye,SAASpb,KAAK8pB,YAAY9c,IAK5Eid,0BAA2B,WACvB,GAAIxV,GAAO9X,IAEXA,MAAKutB,qBAEL5tB,GAAG+C,KAAK1C,KAAKye,SAAS+O,aAAc,SAAS7qB,EAAK8qB,GAC9C,GAAIjkB,GAAWikB,EAAuBjkB,SAClCsgB,EAAanqB,GAAG6B,UAAWsW,EAAK2G,SAASqL,YAAY,GACrD4D,EAAkB/tB,GAAG6B,UAAWisB,EAEnB3pB,UAAb0F,IACAA,EAAWsO,EAAK2G,SAASjV,UAGzBkkB,EAAgB5D,YAChBnqB,GAAG6B,OAAOsoB,EAAY2D,EAAuB3D,YAAY,GAG7DnqB,GAAG6B,OAAOksB,GACNlkB,SAAUA,EACVsgB,WAAYA,IACb,GAEHhS,EAAK6V,iBAAiBD,MAI9B/L,WAAY,SAAShK,GACjB,GAAIiW,GAAmB5tB,KAAKutB,kBAAkB5V,EAE9C,OAAIiW,GACOA,EAAiBhuB,QAEnB+X,IAAa3X,KAAK6tB,iBAChB7tB,KAAKye,SAAS8E,OADpB,QAYTgD,aAAc,SAASuH,GACnB,GAAIC,GAAQC,EACRC,EAAkBH,CAQtB,IALIG,YAA2BtuB,IAAGwX,YAC9B8W,EAAkBA,EAAgB7W,eAIlC6W,IAAoBtuB,GAAGuJ,OAAO+kB,GAAkB,CAChD,GAAItuB,GAAGuI,OAAO+lB,GACV,MAAOA,GAAgB3H,UAEtB,IAA8C,UAA1C2H,EAAgBhlB,QAAQF,eACU,SAAvCklB,EAAgB/tB,KAAK6I,cAErB,MAAOklB,GAAgBpqB,aAAalE,GAAG4X,aAAaG,oBAYxD,IATAqW,EAASE,EAAgBxrB,qBAAqB,SAE9C9C,GAAG+C,KAAKqrB,EAAQ,SAASprB,EAAK0G,GAC1B,GAAmC,SAA/BA,EAAMxF,aAAa,QAEnB,MADAmqB,GAAY3kB,GACL,IAIX2kB,EACA,MAAOA,GAAUnqB,aAAalE,GAAG4X,aAAaG,uBAK1DqV,qBAAsB,SAASpM,GAC3B,MAAO3gB,MAAKgkB,uBAAuBjC,IAAIpB,IAG3CuN,gBAAiB,WACb,MAAOluB,MAAK2f,YAAYnE,UACpBpB,QACIza,GAAGya,OAAO8C,UACVvd,GAAGya,OAAOgD,gBACVzd,GAAGya,OAAO2C,OACVpd,GAAGya,OAAOY,WACVrb,GAAGya,OAAOyC,UACVld,GAAGya,OAAO6C,UAEfvX,QAKPyoB,mBAAoB,SAASxW,GACzB,GAAI+V,GAAkB1tB,KAAKutB,kBAAkB5V,EAE7C,OAAO+V,GAAkBA,EAAgB5D,WAAa9pB,KAAKye,SAASqL,YAGxEsE,yBAA0B,SAASC,GAC/B,MAAIA,GAAYlT,eAAgBxb,IAAGwX,WAE3BzV,KAAM/B,GAAG+R,YAAY2c,EAAYlT,KAAK/D,eACtC8D,KAAMmT,EAAYlT,KAAK/D,cAAc8D,OAKzCxZ,KAAM1B,KAAKoiB,YAAYtI,GAAIuU,EAAYvU,KAAKpY,KAC5CwZ,KAAMlb,KAAKoiB,YAAYtI,GAAIuU,EAAYvU,KAAKoB,OAIpDoT,0BAA2B,SAASC,GAChC,GAAIzW,GAAO9X,KACPwuB,IAMJ,OAJA7uB,IAAG+C,KAAK6rB,EAAc,SAAS5rB,EAAK0rB;gCAChCG,EAAgB3rB,KAAKiV,EAAKsW,yBAAyBC,MAGhDG,GAIXC,oBAAqB,WACjB,GAAIzuB,KAAKye,SAASiQ,OAAOzgB,KAAOtO,GAAGsO,MAAO,CACtC,GACIsV,GAASvjB,KAAKye,SAASiQ,OAAOnL,OAC9B5L,EAAW4L,EAASvjB,KAAKumB,aAAahD,GAAUvjB,KAAK6tB,iBACrDc,EAAa3uB,KAAKye,QAGlB9G,IAAYA,IAAa3X,KAAK6tB,mBAC9Bc,EAAa3uB,KAAKutB,kBAAkB5V,IAIxCgX,EAAWnlB,UAAW,EAGoB,OAAtCmlB,EAAW7E,WAAW7R,YACtB0W,EAAW7E,WAAW7R,YAfJ,yBAkBlB0W,EAAW7E,WAAW7R,aAAe,0BAIzCtY,GAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjC,GAAIA,EAAOpK,gBAAkBxB,EAIzB,MAHA4L,GAAOxL,YAAY4W,EAAWnlB,UAC9B+Z,EAAOhK,eAAeoV,EAAW1W,cAE1B,MAMvBgQ,uBAAwB,SAAS2G,GAC7B,GAAI9W,GAAO9X,KACP6uB,EAAiBD,EAAQ5f,UAE7B,OAAIrP,IAAG4W,iBAAiBsY,IACpB7uB,KAAK8F,IAAI8oB,EAAQltB,KAAO,kBAAoBktB,EAAQltB,KAAO,gCAAkCktB,EAAQxG,YAC9FyG,EAAepY,KAClB,SAASqY,GACLhX,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,YAC1DwG,EAAQ5X,UAAU8X,IAEtB,WACQF,EAAQ3X,WACRa,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,YAC1DwG,EAAQ3X,aAGRa,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,gBAKtEyG,KAAmB,EACnBD,EAAQ5X,UAAU6X,GAGdD,EAAQ3X,WACRjX,KAAK8F,IAAI8oB,EAAQltB,KAAO,mCAAqCktB,EAAQxG,WAAa,iCAClFwG,EAAQ3X,aAGRjX,KAAK8F,IAAI8oB,EAAQltB,KAAO,mCAAqCktB,EAAQxG,WAAa,wBAInFyG,IAIXrQ,eAAgB,SAASrD,EAAMC,EAAS2T,GACpC,GAAIjX,GAAO9X,KACPia,EAAOta,GAAGiN,cACVsO,GAAO,EACPxZ,EAAO/B,GAAG+R,YAAYyJ,GACtB6T,EAAa7T,EAAKlQ,MAAQkQ,EAC1B8T,EAAUjvB,KAAKkvB,sBACXlvB,KAAKkvB,sBACLvvB,GAAG4P,KAAKuI,EAAKqX,sBAAuBrX,IAEvCnY,GAAG+I,QAAQsmB,IAAeA,EAAW9T,MAAQ,IAC9CA,EAAO8T,EAAW9T,MAGtB+T,EAAQD,EAAYttB,EAAMuY,EAAMiB,EAAM6T,EAAoB3T,EAASpb,KAAKye,SAASwI,QAAQC,UACrFxH,WAAY5H,EAAK6H,YACjByH,YAAatP,EAAK0L,aAClB4L,iBAAkB,SAAStV,EAAIqB,GAC3BrD,EAAK+H,SAAS1P,IAAI2J,EAAIqB,GACtBrD,EAAK8K,uBACL9K,EAAKuX,aAAavV,OAK9BqV,sBAAuB,SAAShU,EAAMzZ,EAAMuY,EAAMiB,EAAMoU,EAAUlU,GAC9D,GAAItB,GAAK9Z,KAAK2f,YAAY7E,SACtBb,KAAMA,EACNvY,KAAMA,EACNwZ,KAAMA,EACNE,QAASA,EACTD,KAAMA,GAGVnb,MAAK6f,SAAS1P,IAAI2J,EAAIqB,GAEtBnb,KAAKqvB,aAAavV,GAElB9Z,KAAK4iB,uBAEL0M,EAASzsB,MAAMiX,GAAIA,EAAIqB,KAAMA,KAGjCgN,oBAAqB,SAASld,EAAMskB,GAChC,GAAIC,GAAYvkB,EAAK/K,KAAKmF,MAAM,KAAK,GACjC3D,EAAO6tB,CAGC,OAAR7tB,IACAA,EAAO1B,KAAKye,SAASsJ,MAAMpJ,aAG/Bjd,GAAQ,IAAM8tB,EAEdxvB,KAAK+d,UACDrc,KAAMA,EACNuJ,KAAMA,KAIdwkB,qBAAsB,SAAS3V,GAC3B,GAAI9Z,KAAKoiB,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAOqD,QAAS,CACxD,GAAI/b,GAAO1B,KAAK4f,QAAQ9F,EAExB9Z,MAAK4iB,uBACL5iB,KAAKwiB,eACLxiB,KAAK6f,SAASqD,QAAQpJ,GACtB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOqD,SACzCzd,KAAK8F,IAAI,uBAAyBpE,EAAO,sBAIjDguB,oBAAqB,SAAS5V,EAAI4N,GAC9B,GAAIhmB,GAAO1B,KAAK4f,QAAQ9F,EAExB9Z,MAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOmD,eACzCvd,KAAK8F,IAAI,uBAAyBpE,EAAO,gBAAiB,SAKrDgmB,GAAyC5jB,SAA7B4jB,EAASxU,gBAItBlT,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,4CAA8CgmB,EAAStN,OAAQsN,GAHzG1nB,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,wBAAyBgmB,IAQ3EiG,iBAAkB,SAAS5S,GACvB,GAAIwI,GAASvjB,KAAKupB,qBACdM,OAAQ9O,EAAK+O,WAAW7R,YACxB2R,kBAAmB7O,EAAK+O,WAAWF,kBACnChqB,QAASmb,EAAKnb,QACdoY,QAAS+C,EAAK/C,QACdxO,SAAUuR,EAAKvR,SACfqO,MAAOkD,EAAKsP,gBAGhBrqB,MAAKutB,kBAAkBhK,EAAOpK,eAAiB4B,GAGnD4U,0BAA2B,WACvB3vB,KAAK4vB,aAAejwB,GAAGkwB,aAAe,GAAIlwB,IAAGkwB,YACzC7vB,KAAKye,SAAS5N,KAAMlR,GAAG4P,KAAKvP,KAAK4lB,kBAAmB5lB,MAAOL,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OAG7EA,KAAK4vB,cAAgB5vB,KAAK4vB,aAAaE,gBACvC9vB,KAAKwjB,aAAexjB,KAAKqoB,aACrBroB,KAAKye,SAASwI,QAAQpJ,OAAS7d,KAAK4vB,aAAaG,uBAGrD/vB,KAAKye,SAASuR,WAAahwB,KAAK4vB,aAAaK,cACzCjwB,KAAK4vB,aAAaM,cAClBlwB,KAAKye,SAASwI,QAAQnJ,SAAW9d,KAAK4vB,aAAaM,cAIvDlwB,KAAKwjB,aAAexjB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQpJ,SAIpEsS,kBAAmB,WACf,SAAKxwB,GAAGinB,0BAA4B5mB,KAAKye,SAAS4B,WAAWF,YAIzDngB,KAAKye,SAAS6I,KAAK8I,aACfzwB,GAAG8S,kBAAkB0C,sBAIrBxV,GAAG8S,kBAAkByC,oBAAqBlV,KAAKye,SAAS6I,KAAK+I,aAUzE1G,oBAAqB,SAAS2G,EAAS1e,GACnC,GAAI2e,IAAQ,CAEZ,QAAKD,EAAQ5qB,SAIb/F,GAAG+C,KAAK4tB,EAAS,SAAS3tB,EAAK6tB,GAK3B,GAAI7wB,GAAGwH,SAASqpB,GAAa,CAEzB,GAAIC,GAAW,GAAI5uB,QAAO,MAAQ2uB,EAAa,IAAK,IAEpD,IAAgC,MAA5B5e,EAASoB,MAAMyd,GAEf,MADAF,IAAQ,GACD,KAKZA,IAWX1K,WAAY,SAAS6K,EAAMC,EAAkB1pB,GASzC,QAAS6F,GAAEpL,EAAMkvB,GAAe7qB,EAAUA,EAAQ7D,QAAQR,EAAMkvB,GARhE,GAMIC,GAAsBC,EANtB/qB,EAAU/F,KAAKye,SAASsS,SAASL,GACjC9G,KACAoH,KAAWrhB,OAAOghB,GAClBjvB,EAAOsvB,EAAM,GACbrZ,EAAW3X,KAAKumB,aAAatf,GAC7BgqB,EAAiBjxB,KAAKmuB,mBAAmBxW,EA+B7C,OA1BAhY,IAAG+C,KAAKuuB,EAAerH,kBAAmB,SAASjnB,EAAKuuB,GAKhDvxB,GAAGwH,SAAS+pB,IACZtH,EAAkB/mB,KAAKquB,KAI/BL,EAAuBjH,EAAkBpZ,KAAK,MAAMzH,cAEpD+D,EAAE,SAAU9M,KAAKye,SAAS0S,eAAezvB,IACzCoL,EAAE,eAAgB+jB,GAClB/jB,EAAE,cAAe9M,KAAKktB,YAAY+D,EAAeG,YACjDtkB,EAAE,iBAAkB9M,KAAKktB,YAAY+D,EAAeI,eAEpDP,EAAmB/qB,EAAQiN,MAAM,cACR,OAArB8d,GACAnxB,GAAG+C,KAAKouB,EAAkB,SAASnuB,EAAK2uB,GACpCxkB,EAAEwkB,EAAaN,EAAMruB,MAI7B3C,KAAKye,SAASgI,UAAUC,QAAQ,KAAMhlB,EAAMqE,EAASjC,QAE9CiC,GAYXme,aAAc,SAASpK,EAAI9K,GACvB,GAAIhP,KAAKuxB,qBAAqBzX,GAW1B,MAVA9Z,MAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOgD,iBAErCpO,EACAA,EAAS8K,GAGT9Z,KAAK6f,SAASoE,MAAMnK,IAGjB,GAIfuP,kBAAmB,SAASvP,EAAIM,GAC5B,GAAItC,GAAO9X,KACPwxB,EAAcxxB,KAAKkuB,iBAEnB9T,KAAWza,GAAGya,OAAOiD,kBACrBrd,KAAK6jB,+BAA+BhhB,KAAKiX,GAEpCM,IAAWza,GAAGya,OAAOkD,eAC1Btd,KAAK8jB,4BAA4BjhB,KAAKiX,GAGtB,IAAhB0X,IACCxxB,KAAK6jB,+BAA+Bne,QAAU1F,KAAK8jB,4BAA4Bpe,SAEhF4jB,WAAW,WACPxR,EAAK2Z,eAAe3Z,EAAK+L,+BAAgC/L,EAAKgM,8BAC/D,IAIX1F,iCAAkC,WAC9B,GAAItG,GAAO9X,IAEX,IAAIA,KAAKye,SAASgL,YAAYiI,mBAAqB/xB,GAAGyO,UAAYzO,GAAG2O,YAIjE,KAHAgb,YAAW,WACPzkB,OAAO8sB,MAAM7Z,EAAK2G,SAASsS,SAASa,+BACrC,GACG,GAAIjyB,IAAGwB,MAAMnB,KAAKye,SAASsS,SAASa,+BAIlDC,8BAA+B,SAAS/X,EAAIpY,EAAMowB,EAAU5G,GAGxD,IAAK4G,EAASrmB,QACV,GAAIyf,GAAsB,MAAfA,EAAI9Q,SAAmB0X,EAAShoB,MACvC9J,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,8BAAgCwpB,EAAI9Q,OAAQ8Q,OAErF,CACD,GAAI6G,GAAcD,EAAShoB,MAAQgoB,EAAShoB,MAAQ9J,KAAKye,SAASpb,KAAK2uB,oBACvEhyB,MAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAMqwB,EAAa7G,KAKnE+G,6CAA8C,SAASC,EAAWjoB,EAAOsQ,EAAOsD,EAAQC,GACpF,GAAIhG,GAAO9X,IAEX,IAAIiK,EAAMvE,OAAS6U,EACf,GAAI2X,IAAclyB,KAAKye,SAASqL,WAAWqI,uBAEvC7I,WAAW,WACP,GAAI8I,GAAuBta,EAAKsW,yBAAyBnkB,EAAMsQ,IAC3D5C,EAAWG,EAAKyO,aAAatc,EAAMsQ,GAAOY,MAC1CoI,EAASzL,EAAK6J,WAAWhK,EAE7BG,GAAKmQ,wBACDvmB,KAAM,aACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAU4L,WAAYva,EAAMsa,EAAsB7O,GAClFvM,UAAWrX,GAAG4P,KAAKuI,EAAKwa,2BAA4Bxa,EAAM7N,EAAOsQ,EAAOsD,EAAQC,GAChF7G,UAAWtX,GAAG4P,KAAKuI,EAAKya,2BAA4Bza,EAAM7N,EAAOsQ,EAAOsD,EAAQC,GAChFsK,WAAY,SAAWgK,EAAqB1wB,KAAO,YAAc0wB,EAAqBlX,QAE3F,OAEF,KAAKgX,EACN,KAAO3X,EAAQtQ,EAAMvE,OAAQ6U,IACzBzC,EAAKmV,oBAAoBhjB,EAAMsQ,GAAOT,KAMtD2X,eAAgB,SAASe,EAAYC,GACjCzyB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAe2O,cAAcF,EAAYC,EAAQzyB,KAAKqjB,iBAElFrjB,KAAKye,SAASgI,UAAUiM,cAAc/yB,GAAG6B,UAAWgxB,GAAa7yB,GAAG6B,UAAWixB,IAE/EzyB,KAAK6jB,kCACL7jB,KAAK8jB,gCAeTyI,aAAc,SAASzS,EAAIpY,EAAM4qB,EAAcpB,EAAKlc,GAChD,GAAI8I,GAAO9X,IAIX,IAFA8X,EAAKuL,gBAAgBvJ,GAAMwS,EAAaxU,EAAK2G,SAASwF,MAAM2G,8BAExD9S,EAAK6a,iBAAiB7Y,GAAK,CAC3B,GAAI8Y,GAAyD,IAAvC9a,EAAK2G,SAASwF,MAAM4O,gBAkB1C,OAhBA/a,GAAK+Z,8BAA8BjiB,MAAMkI,EAAMhQ,WAC/CgQ,EAAK2G,SAASgI,UAAU4F,YAAYvS,EAAIpY,EAAMoW,EAAKqL,aAAarJ,IAChEhC,EAAKgb,mBAAmBhZ,EAAIpY,GAE5BoW,EAAK6H,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOgD,iBACzCtF,EAAKsL,eAAetJ,GAAMwP,WAAW,WACjCxR,EAAKhS,IAAI,sBAAwBpE,EAAO,OAEpCsN,EACAA,EAAS8K,GAGThC,EAAK+H,SAASoE,MAAMnK,IAEzB8Y,IAEI,IAIfE,mBAAoB,SAAShZ,EAAIpY,GAC7B1B,KAAK8F,IAAI,WAAa9F,KAAKye,SAASwF,MAAM4O,iBAAmB,4BAA8BnxB,EAAO,QAItG6vB,qBAAsB,SAASzX,GAC3B,GACIlI,GADAmhB,EAAY/yB,KAAK2iB,iBAGrB,OAAI3iB,MAAKqjB,gBAAgBvJ,IACrB9Z,KAAK8F,IAAI,gCAAkCgU,EAAI,SACxC,GAEF9Z,KAAK6f,SAASY,QAAQ3G,IAC3BlI,EAAW5R,KAAK4f,QAAQ9F,GAEpB9Z,KAAKye,SAASgI,UAAUuM,cAAclZ,EAAIlI,MAAc,IAIxDmhB,EAAY,GAAK/yB,KAAK4iB,qBAAuB,EAAImQ,GACjD/yB,KAAK6lB,WAAW,0BACT,IAGX7lB,KAAK8F,IAAI,wBAA0B8L,EAAW,UAAYkI,EAAK,SACxD,MAGP9Z,KAAK8F,IAAI,IAAMgU,EAAK,2BAA4B,UACzC,IAIfwR,UAAW,SAASxR,EAAIpY,GACpB1B,KAAK4iB,uBAELqQ,aAAajzB,KAAKojB,eAAetJ,GAEjC,IAAIoZ,GAAkBvzB,GAAG2F,QAAQtF,KAAKqe,WAAYvE,IAC7C9Z,KAAKye,SAASuR,YAAckD,GAAmB,GAChDlzB,KAAKqe,WAAWrC,OAAOkX,EAAiB,GAG5ClzB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO4C,WAG7CmO,YAAa,SAASrR,EAAIpY,EAAMY,EAAQ4oB,GAoBpC,MAnBK5oB,GAAOmJ,SASJnJ,EAAO6jB,eACPnmB,KAAKmhB,eAAerH,GAAMxX,EAAO6jB,cAGrCnmB,KAAKwiB,eACLxiB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOiD,qBAbzCrd,KAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOkD,eAErChb,EAAOtC,KAAKye,SAASwF,MAAM2G,iCAAkC,IAC7D5qB,KAAKqjB,gBAAgBvJ,IAAM,IAYnC9Z,KAAK6xB,8BAA8B/X,EAAIpY,EAAMY,EAAQ4oB,KAE9C5oB,EAAOmJ,SAGlB+b,UAAW,SAAS1N,GAChB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOoD,WAG7CkI,kBAAmB,SAAS5L,EAAI4N,EAAUC,GAC3B3nB,KAAK4f,QAAQ9F,EAEpB6N,GACA3nB,KAAK0vB,oBAAoB5V,EAAI4N,GAG7B1nB,KAAKyvB,qBAAqB3V,IAIlCsQ,eAAgB,SAAS/gB,GACrB,GAAI8pB,EAEJ,IAAIxzB,GAAG8S,kBAAkBoC,cAAe,CACpC,IAAKse,EAAY,EAAGA,EAAY9pB,EAAMgW,MAAM3Z,OAAQytB,IAChDnzB,KAAKomB,sBAAsB/c,EAAMgW,MAAM8T,GAAY9pB,EAGvDrJ,MAAK+d,SAAS1U,EAAMgW,WAGfhW,GAAM3C,MAAMhB,OAAS,GAC1B1F,KAAK+d,SAAS1U,EAGlB1J,IAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjCA,EAAO/J,WAIfwR,YAAa,SAASlR,EAAIpY,EAAMopB,EAAQC,GACpC/qB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAeqP,qBAAqBtZ,EAAIgR,EAAQC,IAGhFsI,UAAW,SAASvZ,EAAIpY,KAIxB4xB,yBAA0B,SAASxZ,EAAIpY,GACnC1B,KAAKqzB,UAAUzjB,MAAM5P,KAAM8H,WAC3B9H,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOyC,WACzC7c,KAAKuzB,aAAa3jB,MAAM5P,KAAM8H,WAE1B9H,KAAKye,SAASuR,YACdhwB,KAAKye,SAASgI,UAAU+M,YAAY5jB,MAAM5P,KAAM8H,WAChD9H,KAAKogB,YAAYtG,KAGjB9Z,KAAKyzB,eAAe3Z,GACpB9Z,KAAKye,SAASgI,UAAU+M,YAAY5jB,MAAM5P,KAAM8H,aAIxDwY,gBAAiB,SAASxG,EAAI4Z,EAAmBC,GAC7C,GACIC,GADA3Z,EAAOja,KAAK6iB,QAAQ/I,EAOxB,OAJI4Z,KACAE,EAA4Bj0B,GAAG4P,KAAKmkB,EAAmB1zB,KAAM8Z,EAAIG,EAAM0Z,IAGvE3zB,KAAKmwB,qBACLnwB,KAAKioB,wBACDvmB,KAAM,iBACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAUoN,eAAgB7zB,KAAM8Z,GAChE9C,UAAW4c,GACPj0B,GAAG4P,KAAKvP,KAAK8zB,eAAeC,WAAY/zB,KAAM8Z,EAAIG,EAAM0Z,GAC5DvL,WAAYtO,KAET,IAGP9Z,KAAK8F,IAAI,iCAAmCgU,EAAK,wHACuB,SACjE,IAIfyZ,aAAc,SAASzZ,KAIvBka,iBAAkB,SAASlJ,EAAQC,GAC/B/qB,KAAKye,SAASgI,UAAUwN,gBAAgBnJ,EAAQC,IAGpDS,cAAe,SAAS1R,KAIxB4R,UAAW,SAAS5R,EAAIpY,GACpB1B,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO8C,YAG7C4O,eAAgB,SAAShS,EAAI+R,KAI7BK,sBAAuB,SAASpS,EAAI+R,IAC3B7rB,KAAKqjB,gBAAgBvJ,IAAO9Z,KAAKye,SAASwF,MAAMiQ,aACjDl0B,KAAKmjB,aAAarJ,GAAM,IAIhCsP,sBAAuB,SAAStP,EAAIgC,EAAWD,GAEvCA,IAAclc,GAAGya,OAAO6C,QACxBgW,aAAajzB,KAAKojB,eAAetJ,KAIzCqa,gCAAiC,SAAS5F,GACtC,GAAIzW,GAAO9X,IAEXL,IAAG+C,KAAK6rB,EAAc,SAAS5rB,EAAK0rB,GAChCvW,EAAKmV,oBAAoBoB,EAAYvU,OAI7Csa,gCAAiC,SAASC,EAAuBpqB,EAAO4T,EAAQC,EAAUyF,GACtF,GAAIoC,GACAoN,EAAY/yB,KAAK2iB,kBACjB2R,EAAmCt0B,KAAK4iB,oBAE1B,KAAdmQ,GAAmBuB,GAAoCvB,EACnD9oB,EAAMvE,OAAS,EACf1F,KAAKioB,wBACDvmB,KAAM,aACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAU4L,WAAYryB,KAAMq0B,EAAsB,GAAI9Q,GACtFvM,UAAWrX,GAAG4P,KAAKvP,KAAKsyB,2BAA4BtyB,KAAMiK,EAAO,EAAG4T,EAAQC,GAC5E7G,UAAWtX,GAAG4P,KAAKvP,KAAKuyB,2BAA4BvyB,KAAMiK,EAAO,EAAG4T,EAAQC,GAC5EsK,WAAY,SAAWne,EAAM,GAAGkR,KAAKzZ,KAAO,YAAcuI,EAAM,GAAGkR,KAAKD,OAI5Elb,KAAK6lB,WAAW,iBAIpB7lB,KAAKm0B,gCAAgClqB,GACrC0b,EAAe3lB,KAAKye,SAASsS,SAASwD,kBACjCryB,QAAQ,gBAAiBoyB,GACzBpyB,QAAQ,iBAAkB6wB,GAC/B/yB,KAAKwmB,YAAYb,KAIzB4M,2BAA4B,SAAStoB,EAAOsQ,EAAOsD,EAAQC,GACvD,GAAI0W,GAAYja,EAAQ,CAExBva,MAAKitB,oBAAoBhjB,EAAMsQ,GAAOT,GAAI7P,EAAMsQ,GAAOY,KAAKzZ,MAE5D1B,KAAKiyB,8CAA6C,EAAOhoB,EAAOuqB,EAAW3W,EAAQC,IAGvFwU,2BAA4B,SAASroB,EAAOsQ,EAAOsD,EAAQC,GACvD,GAAIhG,GAAO9X,KACPw0B,EAAYja,EAAQ,EACpB6X,EAAuBpyB,KAAKouB,yBAAyBnkB,EAAMsQ,GAE/Dva,MAAKy0B,wBAAwBxqB,EAAMsQ,GAAQ6X,GACtC3b,KACD,WACIqB,EAAK4c,QAAQzqB,EAAMsQ,GAAOT,GAAI+D,EAAQC,GACtChG,EAAKma,8CAA6C,EAAMhoB,EAAOuqB,EAAW3W,EAAQC,IAEtF,WACIhG,EAAKma,8CAA6C,EAAOhoB,EAAOuqB,EAAW3W,EAAQC,MAK/F0B,uBAAwB,SAASvV,EAAO4T,EAAQC,GAC5C,GAAqB,IAAjB7T,EAAMvE,OAEN,WADA1F,MAAK6lB,WAAW,eAIpB,IAAIwO,GAAwBr0B,KAAKsuB,0BAA0BrkB,GACvD0N,EAAW3X,KAAKumB,aAAatc,EAAM,GAAGkR,MACtCoI,EAASvjB,KAAK2hB,WAAWhK,EAE7B3X,MAAKioB,wBACDvmB,KAAM,kBACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAUkO,gBAAiB30B,KAAMq0B,EAAuB9Q,GACxFvM,UAAWrX,GAAG4P,KAAKvP,KAAKo0B,gCAAiCp0B,KAAMq0B,EAAuBpqB,EAAO4T,EAAQC,EAAUyF,GAC/GtM,UAAWtX,GAAG4P,KAAKvP,KAAKm0B,gCAAiCn0B,KAAMiK,GAC/Dme,WAAY,sBAIpBwM,wBAAyB,WACrB,GAAI9c,GAAO9X,IAEXA,MAAKsqB,gBAAgBrqB,OAAO4E,OAAQ,eAAgB,SAAS4J,GACzD,GAAIqJ,EAAKmK,gBAKL,MAJAxT,GAAIA,GAAK5J,OAAOgwB,MAEhBpmB,EAAEC,YAAcoJ,EAAK2G,SAASsS,SAAS+D,QAEhChd,EAAK2G,SAASsS,SAAS+D,WAQ1ClR,oBAAqB,WACjB,GAAI9L,GAAO9X,KACP4X,EAAU5X,KAAKye,SAASiF,OAGxB/jB,IAAGo1B,SAA6C,MAAlC/0B,KAAKye,SAASiF,QAAQ5F,WAC/B9d,KAAKg1B,WACNr1B,GAAG6B,OAAOoW,GAAU0P,KAAMtnB,KAAKye,SAAS6I,OAExC1P,EAAQ9R,IAAMnG,GAAG4P,KAAKvP,KAAK8F,IAAK9F,MAChC4X,EAAQqd,cAAgBt1B,GAAG4P,KAAKvP,KAAKme,eAAgBne,MAErDA,KAAKg1B,SAAW,GAAIr1B,IAAGo1B,QAAQnd,IAGnC0R,WAAW,WACPxR,EAAKkd,SAASE,UAAUze,KAAK,SAASqb,EAAUpK,GAC5C5P,EAAKqd,0BACLrd,EAAK2G,SAASgI,UAAU2O,yBAAyBtD,GAAU,EAAMpK,IAElE,SAASoK,EAAUpK,GAElB5P,EAAK2G,SAASgI,UAAU2O,yBAAyBtD,GAAU,EAAOpK,MAEvE,KAIXyN,wBAAyB,aAEzBzI,SAAU,SAAS5S,EAAIyC,GACnBvc,KAAK2f,YAAYrD,WAAWxC,EAAIyC,GAChCvc,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAesR,UAAUvb,IAGzD6Y,iBAAkB,SAAS7Y,GACvB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAGhD,WAAK9Z,KAAKqjB,gBAAgBvJ,IACnB9Z,KAAKye,SAASwF,MAAMiQ,YACpBxU,EAAWtF,SAAWza,GAAGya,OAAO6C,SAELnZ,SAA1B9D,KAAKmjB,aAAarJ,KAClB9Z,KAAKmjB,aAAarJ,GAAM,GAGxB9Z,KAAKmjB,aAAarJ,GAAM9Z,KAAKye,SAASwF,MAAMqR,oBAC5Ct1B,KAAKmjB,aAAarJ,IAAO,GAClB,IAOnB2Z,eAAgB,SAAS3Z,GACrB9Z,KAAKqe,WAAWxb,KAAKiX,IAIzBuV,aAAc,SAASvV,GACnB,GAAInC,EAGAA,GADAhY,GAAG8S,kBAAkBoC,cACV7U,KAAK6f,SAASwB,QAAQvH,GAAIwM,WAG1BtmB,KAAKumB,aAAavmB,KAAK6f,SAAS3G,SAASY,IAGpDnC,IACA3X,KAAK4hB,qBAAqB9H,GAAMnC,IAIxCyN,4BAA6B,SAASmQ,GAClCv1B,KAAKye,SAAS5N,KAAKjR,QAAU21B,EAE7Bv1B,KAAK4vB,aAAejwB,GAAGkwB,aAAe,GAAIlwB,IAAGkwB,YACrC7vB,KAAKye,SAAS5N,KAAMlR,GAAG4P,KAAKvP,KAAK4lB,kBAAmB5lB,MAAOL,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OAGjFA,KAAK4vB,cAAgB5vB,KAAK4vB,aAAaE,iBACvC9vB,KAAKwjB,aAAa0F,YAAY,KAAMlpB,KAAK4vB,aAAaG,uBAEtD/vB,KAAKye,SAASuR,WAAahwB,KAAK4vB,aAAaK,cACzCjwB,KAAK4vB,aAAaM,aAClBlwB,KAAKilB,YAAYjlB,KAAK4vB,aAAaM,eAK/CwE,QAAS,SAAS5a,EAAI+D,EAAQC,GAC1B,GAAIpc,GAAO1B,KAAK4f,QAAQ9F,EAEpB+D,IACA7d,KAAKwlB,UAAU3H,EAAQ/D,GAGvBgE,GACA9d,KAAKilB,YAAYnH,EAAUhE,GAG/B9Z,KAAKioB,wBACDvmB,KAAM,WACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAU+O,SAAUx1B,KAAM8Z,EAAIpY,GAC9DsV,UAAWrX,GAAG4P,KAAKvP,KAAKszB,yBAA0BtzB,KAAM8Z,EAAIpY,GAC5DuV,UAAWtX,GAAG4P,KAAKvP,KAAKitB,oBAAqBjtB,KAAM8Z,EAAIpY,GACvD0mB,WAAYtO,KAIpBsG,YAAa,SAAStG,GACb9Z,KAAK6f,SAASlW,OAAOmQ,IACtB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO2C,SAIjD+I,mBAAoB,WAIhB,IAHA,GAAI2P,GAAYC,EACZ5d,EAAO9X,KAEJA,KAAKqe,WAAW3Y,QACnB+vB,EAAaz1B,KAAKqe,WAAWpM,QAC7BjS,KAAKogB,YAAYqV,EAIrBC,GAAkB11B,KAAKoiB,YAAYhI,OAAQza,GAAGya,OAAOY,aAAatV,OAC9DgwB,IACA/1B,GAAGmG,IAAI,qBAAuB4vB,EAAkB,yEAChDpM,WAAW,WACPxR,EAAKgO,sBACN,OAYX2O,wBAAyB,SAASpG,EAAa+D,GAC3C,GAAIta,GAAO9X,KACPmb,EAAQ,WACJ,MAAIkT,GAAYlT,eAAgBxb,IAAGwX,UACxBkX,EAAYlT,KAAK/D,cAErBiX,EAAYlT,QAEvBzZ,EAAO0wB,EAAqB1wB,KAC5BwZ,EAAOkX,EAAqBlX,KAC5BvD,EAAW3X,KAAKumB,aAAa8H,EAAYlT,MACzC8V,EAAiBjxB,KAAKmuB,mBAAmBxW,GACzCge,EAAkB,GAAIh2B,IAAG4L,OAQ7B,OANAoqB,GAAgBlf,KACZ,aACA,WACIqB,EAAKmV,oBAAoBoB,EAAYvU,GAAIpY,KAG7C/B,GAAG6I,cAAc2S,KAAUnb,KAAK2pB,oBAAoBsH,EAAerH,kBAAmBloB,IACtF1B,KAAK6lB,WAAW,YAAankB,EAAMyZ,GAC5Bwa,EAAgBhqB,WAGtB3L,KAAKye,SAASqL,WAAW8L,YAAuB,IAAT1a,EAKxCA,EAAO,GAAK+V,EAAeG,WAAalW,EAAO+V,EAAeG,WAC9DpxB,KAAK6lB,WAAW,YAAankB,EAAMyZ,GAC5Bwa,EAAgBhqB,WAGvBuP,EAAO,GAAKA,EAAO+V,EAAeI,cAClCrxB,KAAK6lB,WAAW,eAAgBnkB,EAAMyZ,GAC/Bwa,EAAgBhqB,YAGvBhM,GAAGk2B,iBAAmBl2B,GAAG8S,kBAAkBgD,eAAiB9V,GAAGuI,OAAOiT,GACtE,GAAIxb,IAAGk2B,gBAAgB1a,EAAMxb,GAAG4P,KAAKuI,EAAKhS,IAAKgS,IAAOge,SAAS7E,EAAe8E,OAAOtf,KACjFkf,EAAgBlqB,QAChB,SAASuqB,GACLle,EAAK+N,WAAWmQ,EAAY,aAAct0B,EAAMyZ,GAChDwa,EAAgBhqB,YAKxBgqB,EAAgBlqB,UAGbkqB,IA3BH31B,KAAK6lB,WAAW,aAAcnkB,EAAMyZ,GAC7Bwa,EAAgBhqB,YA6B/BsqB,eAAgB,WACZ,GAAIne,GAAMoe,EAAcnqB,CAExB+L,GAAO9X,KAEPk2B,EAAe,SAASx0B,EAAMsN,EAAUrH,GACpC,GAAIwuB,EAEJ,KACI,MAAOnnB,GAASY,MAAMkI,EAAMnQ,GAEhC,MAAOyuB,GACHD,EAAWC,EAAUrwB,SAAWqwB,EAAU9vB,WAC1CwR,EAAKhS,IAAI,wBAA0BpE,EAAO,gBAAkBy0B,EAAU,UAK9E,KAAKpqB,IAAQ/L,MAAKye,SAASgI,WACtB,WACG,GAAI4P,GAAcC,CAClBD,GAAetqB,EACfuqB,EAAexe,EAAK2G,SAASgI,UAAU4P,GACvCve,EAAK2G,SAASgI,UAAU4P,GAAgB,WACpC,MAAOH,GAAaG,EAAcC,EAAcxuB,oBCr7DvE,WACG,YAEAnI,IAAG42B,kBAAoB,SAAS/e,GAC5B,GAAIM,GAAO9X,IAGXA,MAAKye,UACDuE,OAAO,EACPO,OAAQ,KACR/Z,UAAU,EACVud,eAAgB,EAChByP,6BAA6B,EAC7BxG,YAAY,EACZyG,kBAAkB,EAElBxP,SACIE,iBACArJ,SAAU,iBACV4Y,cAAe,aACfC,gBAAgB,EAChBxM,UAAW,SACXtD,OAAQ,OACR+P,mBAAmB,EACnB/Y,UACAgZ,cAAc,EACdC,oBAAoB,EACpBC,kBAAmB,kBACnB7P,SAAU,UAGd4C,YACIF,qBACAwH,UAAW,EACXC,aAAc,EACd0B,UAAW,EACXZ,wBAAwB,EACxBla,YAAa,KACb8d,OACIiB,UAAW,EACXC,SAAU,EACVC,UAAW,EACXC,SAAU,GAEdvB,YAAY,GAGhBnP,WACI+O,SAAU,SAAS1b,EAAIpY,KACvB8xB,YAAa,SAAS1Z,EAAIpY,KAC1BupB,WAAY,SAASnR,EAAIpY,EAAM4qB,EAAc8K,KAC7C1E,cAAe,SAASF,EAAYC,KACpCrH,SAAU,SAAStR,EAAIpY,KACvB+pB,SAAU,SAAS3R,EAAIpY,KACvBkqB,cAAe,SAAS9R,EAAIpY,EAAMmqB,KAClCI,qBAAsB,SAASnS,EAAI+R,EAAWS,EAAcpB,KAC5DiB,SAAU,SAASrS,EAAIlI,EAAUia,EAAWO,KAC5CvB,WAAY,SAAS/Q,EAAIpY,EAAMopB,EAAQC,KACvCkJ,gBAAiB,SAASnJ,EAAQC,KAClCrE,QAAS,SAAS5M,EAAIpY,EAAM+f,EAAQ4V,KACpChL,YAAa,SAASvS,EAAIpY,EAAM41B,KAChCtE,cAAe,SAASlZ,EAAIpY,KAC5BizB,gBAAiB,SAAS4C,KAC1BlF,WAAY,SAASkF,KACrB1D,eAAgB,SAAS/Z,KACzByN,SAAU,SAASzN,KACnB2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,KACzCO,gBAAiB,SAASjd,KAC1BsQ,eAAgB,SAASzB,EAAIgC,EAAWD,KACxCuZ,yBAA0B,SAAStD,EAAUrmB,EAASic,MAG1DqJ,UACIyG,UAAW,qEACXC,UAAW,yDACXC,aAAc,4DACdC,WAAY,yDACZC,aAAc,sBACdrD,kBAAmB,6EACnBsD,oBAAqB,qBACrBC,mBAAoB,qBACpBC,oBAAqB,4BACrBC,mBAAoB,4BACpBC,sBAAuB,mDACvBnD,QAAS,8EACTlD,6BAA8B,6KAGlC3N,OACIiQ,YAAY,EACZoB,gBAAiB,EACjBzC,iBAAkB,EAClBjI,6BAA8B,gBAGlCb,SACIE,YAAa,yBACbD,YAAa,0BAGjBhV,UACImL,SAAS,EACT+X,YACI/X,SAAS,GAEbgY,WAAW,EACXC,YACIpM,UAAW,cACXqM,eAAgB,mBAChBC,UAAW,cACXC,cAAe,kBACfC,WAAY,gBAEhBC,SAAU,SAAS3e,GACf,MAAO,MAGXrO,SACIqS,SAAU,KAEVyG,QAAS,SAASzK,GACd,MAAO,OAGX4e,aAAa,EAEb7R,OAAQ,OAERhJ,OAAQ,SAAS/D,GACb,MAAO,OAGX6e,mBAIR7iB,QACIqK,SAAS,EACTyY,gBAAiB,EACjBR,YACIS,SAAU,YAEdC,WAAY,SAASnY,GACjB,WAIRwQ,eAAgB,SAAS4H,GACrB,MAAOA,IAGX11B,MACI2uB,qBAAsB,gCACtB3H,eAAgB,aAChB8C,aAAc,KAAM,KAAM,KAAM,KAAM,KAAM,OAGhD9M,YACIF,SAAS,EACT0G,OAAQ,SACR/I,SAAU,iBACVqJ,iBACAtJ,WAGJyJ,MACI8I,UAAU,EACV4I,iBAAiB,EACjB3I,UAAU,GAGd3R,OACIC,YAAa,aAGjBoJ,OACID,cAAe,KACfnJ,YAAa,gBAGjB+P,QACIzgB,KAAK,EAGLsV,OAAQ,MASZiK,gBAIA9J,SACI5F,SAAU,KACVD,UACAsJ,iBACAxD,gBAAgB,GAIpB9S,MAEIjR,QAAS,UAGTowB,YAAY,EAGZiJ,iBAAiB,GAIrBljB,SACImjB,cAAe,KAGfC,cAAc,EAGdC,QAAQ,EAIRC,YAAa,KAEbC,eAAgB,GAEhBC,YAAa,kBAEbC,aAAa,EAGbC,UAGJhQ,aACIC,gBAAgB,EAChBgI,mBAAmB,EACnBxH,kBAAkB,IAK1BvqB,GAAG6B,OAAOxB,KAAKye,SAAUjH,GAAG,GAE5BxX,KAAKsjB,YACLtjB,KAAKutB,qBACLvtB,KAAK4hB,wBAEL5hB,KAAKi2B,iBACLj2B,KAAKsqB,gBAAmB,GAAI3qB,IAAGkS,eAE/B7R,KAAKqe,cACLre,KAAKmjB,gBACLnjB,KAAKojB,kBACLpjB,KAAKqjB,mBACLrjB,KAAKmhB,kBAELnhB,KAAK4iB,qBAAuB,EAC5B5iB,KAAKwiB,aAAe,EACpBxiB,KAAK2f,YAAc3f,KAAKmpB,2BAExBnpB,KAAK2vB,4BAEL3vB,KAAKwkB,oBAAsBxkB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQE,eACnEnnB,KAAK4kB,8BAAgC5kB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAW8G,eAEhFnnB,KAAKglB,uBAAyBhlB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAWxC,QAEzE7d,KAAK8hB,eAAiB9hB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQnJ,UAC9D9d,KAAK8kB,yBAA2B9kB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAWvC,UAE3E9d,KAAK6f,SAAW7f,KAAKuqB,uBAErBvqB,KAAK8zB,eAAiBn0B,GAAGinB,yBAA2B5mB,KAAK2mB,uBAErD3mB,KAAKye,SAAS8E,SACdvjB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKye,SAAS8E,OACvB1L,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGPnZ,KAAKstB,4BAELttB,KAAKyuB,sBAEDzuB,KAAKye,SAASsJ,MAAMD,gBAChBnoB,GAAGkoB,aACH7nB,KAAKyjB,cAAgBzjB,KAAK4nB,sBAG1B5nB,KAAK8F,IAAI,iCAAkC,UAInD9F,KAAKye,SAASgY,kBAAoBz2B,KAAK40B,0BAEvC50B,KAAKkhB,gBAAkBvhB,GAAG+5B,gBAAkB,GAAI/5B,IAAG+5B,eAAe/5B,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OACpFA,KAAK4jB,sBAEL5jB,KAAK6jB,kCACL7jB,KAAK8jB,+BAEL9jB,KAAK25B,QAAWh6B,GAAG0kB,QAAU,GAAI1kB,IAAG0kB,OAAOrkB,KAAKye,SAAS1I,QAASpW,GAAG4P,KAAKvP,KAAK8F,IAAK9F,WAChFA,KAAK25B,QAAQxZ,UACbngB,KAAKkvB,sBAAwBvvB,GAAG4P,KAAKvP,KAAK25B,QAAQC,cAAe55B,KAAK25B,UAGtEh6B,GAAGk6B,eAAiBl6B,GAAG8S,kBAAkBoD,cACzC7V,KAAK+jB,eAAiB,GAAIpkB,IAAGk6B,cACzBl6B,GAAG4P,KAAKvP,KAAKg0B,iBAAkBh0B,MAE/B,SAAS8Z,GACL,GAAIggB,GAAQhiB,EAAK6H,YAAYnE,UAAU1B,GAAIA,GAC3C,OAAQggB,IAASA,EAAM5e,MAAS,KAK5Clb,KAAK2iB,kBAAoB3iB,KAAKye,SAASqL,WAAWiJ,UAElD/yB,KAAKgkB,uBAAyBhkB,KAAKqoB,gBAIvC1oB,GAAG42B,kBAAkBlwB,UAAY1G,GAAG+d,cACpC/d,GAAG6B,OAAO7B,GAAG42B,kBAAkBlwB,UAAW1G,GAAGomB,mBC3UjDpmB,GAAGo6B,cAAgB,SAASviB,GACxB,YA2CA,SAASwiB,KACL,MAAOr6B,IAAG2F,SAAS,MAAO,OAAQ,QAASsS,EAAQiP,SAAW,EAMlE,QAASoT,GAAyB1V,GAC9B,GAAI2V,IAAoB,CASxB,OAPAv6B,IAAG+C,KAAKw3B,EAAmB,SAASv3B,EAAKw3B,GACrC,GAAIx6B,GAAG2F,SAAS,SAAU,kBAAmB,mBAAoB,gBAAiB60B,GAAU,EAExF,MADAD,IAAoB,GACb,IAIRA,EAGX,QAASE,GAAMlP,GAEX,MAAOtT,GAAQ0P,KAAK8I,UAAoCtsB,SAAxBonB,EAAIhY,gBAIxC,QAASmnB,KACL,GAAI3S,EAeJ,QAbI7iB,OAAO+E,gBAAkB/E,OAAOgF,iBAChC6d,EAAW/nB,GAAG+J,oBAEmB5F,SAA7B4jB,EAASxU,kBACTwU,EAAW,GAAItU,gBAEfsU,EAASlc,OAAS,aAClBkc,EAAShc,QAAU,aACnBgc,EAAS4S,UAAY,aACrB5S,EAAS6S,WAAa,eAIvB7S,EAIX,QAAS8S,GAAY1gB,EAAI2gB,GACrB,GAAI/S,GAAWgT,EAAY5gB,IAAO4gB,EAAY5gB,GAAIoR,GAkBlD,OAhBKxD,KAEGA,EADA+S,EACWA,EAGP7iB,EAAQ0P,KAAK8I,SACFiK,IAGA16B,GAAG+J,oBAItBgxB,EAAY5gB,GAAIoR,IAAMxD,GAGnBA,EAIX,QAASiT,GAAQ7gB,GACb,GAEI8gB,GAFAvqB,EAAI1Q,GAAG2F,QAAQu1B,EAAO/gB,GACtBsT,EAAMxV,EAAQmP,qBAGX2T,GAAY5gB,GACnB+gB,EAAM7e,OAAO3L,EAAG,GAEZwqB,EAAMn1B,QAAU0nB,GAAO/c,EAAI+c,IAC3BwN,EAASC,EAAMzN,EAAM,GACrB0N,EAAYF,IAIpB,QAAS3P,GAAWnR,EAAIihB,GACpB,GAAI7P,GAAMsP,EAAY1gB,GAClB+M,EAASjP,EAAQiP,OACjBc,EAAUoT,KAAa,CAE3BJ,GAAQ7gB,GAEJ6N,EACA7hB,EAAI+gB,EAAS,gBAAkB/M,EAAK,cAAe,SAE7CsgB,EAAMlP,IAAS8P,EAAqB9P,EAAI9Q,UAC9CuN,GAAU,EACV7hB,EAAI+gB,EAAS,gBAAkB/M,EAAK,+BAAiCoR,EAAI9Q,OAAQ,UAGrFxC,EAAQqT,WAAWnR,EAAIoR,EAAKvD,GAGhC,QAASsT,GAAUnhB,GACf,GAEI+D,GAFAqd,EAAiBR,EAAY5gB,GAAIqhB,iBACjCC,EAAiBxjB,EAAQwjB,cAqB7B,OAlBIxjB,GAAQwP,YAAYrF,MACpBlE,EAASjG,EAAQwP,YAAYrF,IAAIjI,IAGjCohB,GACAv7B,GAAG+C,KAAKw4B,EAAgB,SAASx5B,EAAMkB,GACnCib,EAASA,MACTA,EAAOnc,GAAQkB,IAInBw4B,GACAz7B,GAAG+C,KAAK04B,EAAgB,SAAS15B,EAAMkB,GACnCib,EAASA,MACTA,EAAOnc,GAAQkB,IAIhBib,EAGX,QAASid,GAAYhhB,EAAIuhB,GACrB,GAIIC,GAJApQ,EAAMsP,EAAY1gB,EAAIuhB,GACtBxU,EAASjP,EAAQiP,OACjBhJ,EAASod,EAAUnhB,GACnByhB,EAAUb,EAAY5gB,GAAIyhB,OA+C9B,OA5CA3jB,GAAQ4jB,OAAO1hB,GAEfwhB,EAAMG,EAAU3hB,EAAI+D,EAAQ6c,EAAY5gB,GAAI4hB,uBAGxCtB,EAAMlP,IACNA,EAAI1f,OAASmwB,EAAkB7hB,GAC/BoR,EAAIxf,QAAUkwB,EAAmB9hB,IAGjCoR,EAAI2Q,mBAAqBC,EAA8BhiB,GAG3DiiB,EAA0BjiB,GAG1BoR,EAAI8Q,KAAKnV,EAAQyU,GAAK,GAIlB1jB,EAAQ0P,KAAK8I,UAAYxY,EAAQ0P,KAAK0R,kBAAoBoB,EAAMlP,KAChEA,EAAIhY,iBAAkB,GAG1B+oB,EAAWniB,GAEXhU,EAAI,WAAa+gB,EAAS,gBAAkB/M,GAExCyhB,EACArQ,EAAIgR,KAAKX,GAEJY,IAAgCte,EACrCqN,EAAIgR,OAECre,GAAUjG,EAAQwkB,aAAexkB,EAAQwkB,YAAYrzB,cAAczD,QAAQ,sCAAwC,EACxH4lB,EAAIgR,KAAKv8B,GAAGkQ,QAAQgO,EAAQ,KAEvBA,GAAUjG,EAAQwkB,aAAexkB,EAAQwkB,YAAYrzB,cAAczD,QAAQ,qBAAuB,EACvG4lB,EAAIgR,KAAKhrB,KAAKmrB,UAAUxe,IAGxBqN,EAAIgR,KAAKre,GAGNqN,EAGX,QAASuQ,GAAU3hB,EAAI+D,EAAQ6d,GAC3B,GAAI5d,GAAWlG,EAAQyP,cAActF,IAAIjI,GACrCwiB,EAAY5B,EAAY5gB,GAAIwiB,SAehC,OAZiBx4B,SAAbw4B,IACAxe,GAAY,IAAMwe,GAGlBH,GAA+Bte,IAC/BC,EAAWne,GAAGkQ,QAAQgO,EAAQC,IAG9B4d,IACA5d,EAAWne,GAAGkQ,QAAQ6rB,EAAuB5d,IAG1CA,EAKX,QAASge,GAA8BhiB,GACnC,MAAO,YACgC,IAA/B0gB,EAAY1gB,GAAIyiB,YAChBtR,EAAWnR,IAKvB,QAASiiB,GAA0BjiB,GAC/B,GAAI+Q,GAAajT,EAAQiT,UAErBA,KACA2P,EAAY1gB,GAAInQ,OAAO4wB,WAAa,SAAS9rB,GACrCA,EAAE+tB,kBACF3R,EAAW/Q,EAAIrL,EAAEqc,OAAQrc,EAAEsc,SAQ3C,QAAS4Q,GAAkB7hB,GACvB,MAAO,YACHmR,EAAWnR,IAMnB,QAAS8hB,GAAmB9hB,GACxB,MAAO,YACHmR,EAAWnR,GAAI,IAIvB,QAASmiB,GAAWniB,GAChB,GAAIoR,GAAMsP,EAAY1gB,GAClBqN,EAAgBvP,EAAQuP,cACxBsV,EAAkB/B,EAAY5gB,GAAI4iB,sBAClC7V,EAASjP,EAAQiP,OACjB8V,IAGCvC,GAAMlP,KACPtT,EAAQglB,cAAgB1R,EAAI2R,iBAAiB,SAAUjlB,EAAQglB,cAG3DhlB,EAAQklB,qCAKHllB,EAAQ0P,KAAK8I,UAAc4J,MAAoBC,EAAyB9S,KACzE+D,EAAI2R,iBAAiB,mBAAoB,kBACzC3R,EAAI2R,iBAAiB,gBAAiB,eAI1CjlB,EAAQwkB,aAA2B,SAAXvV,GAAgC,QAAXA,GAC7CqE,EAAI2R,iBAAiB,eAAgBjlB,EAAQwkB,aAGjDz8B,GAAG6B,OAAOm7B,EAAYh9B,GAAG6G,WAAW2gB,GAAiBA,EAAcrN,GAAMqN,GACzExnB,GAAG6B,OAAOm7B,EAAYF,GAEtB98B,GAAG+C,KAAKi6B,EAAY,SAASj7B,EAAMkB,GAC/BsoB,EAAI2R,iBAAiBn7B,EAAMkB,MAKvC,QAASo4B,GAAqB+B,GAC1B,MAAOp9B,IAAG2F,QAAQsS,EAAQolB,wBAAwBplB,EAAQiP,QAASkW,IAAiB,EAGxF,QAASE,GAAcnjB,EAAIuhB,EAAQiB,EAAWnB,EAAkBO,EAAuBgB,EAAmBnB,GAYtG,GAXAb,EAAY5gB,IACRwiB,UAAWA,EACXnB,iBAAkBA,EAClBO,sBAAuBA,EACvBgB,kBAAmBA,EACnBnB,QAASA,GAGHV,EAAMh4B,KAAKiX,IAGVlC,EAAQmP,eACf,MAAO+T,GAAYhhB,EAAIuhB,GA7U/B,GAAIv1B,GAAKq2B,EACLtB,KACAH,KACA9iB,GACIglB,aAAc,KACdM,cAAe,QAAS,OAAQ,OAChCrW,OAAQ,OACRuV,YAAa,oCACbrV,eAAgB,EAChBI,iBACAE,iBACAD,eACAgU,kBACA0B,oCAAoC,EACpCE,yBACIG,QAAS,IAAK,IAAK,KACnBC,OAAQ,IAAK,IAAK,IAAK,IAAK,KAC5BC,MAAO,IAAK,IAAK,IAAK,IAAK,KAC3BC,KAAM,IAAK,IAAK,IAAK,IAAK,KAC1BC,KAAM,MAEVjW,MACI8I,UAAU,EACV4I,iBAAiB,GAErBlzB,IAAK,SAAS4B,EAAK1B,KACnBw1B,OAAQ,SAAS1hB,KACjBmR,WAAY,SAASnR,EAAI4N,EAAUC,KACnCkD,WAAY,KAMpB,IAHAlrB,GAAG6B,OAAOoW,EAASJ,GACnB1R,EAAM8R,EAAQ9R,IAEVnG,GAAG2F,QAAQsS,EAAQslB,aAActlB,EAAQiP,QAAU,EACnD,KAAM,IAAI1lB,OAAM,IAAMyW,EAAQiP,OAAS,wDA8S3CsV,GAAiD,QAAnBvkB,EAAQiP,QAAuC,WAAnBjP,EAAQiP,OAElElnB,GAAG6B,OAAOxB,MAENw9B,cAAe,SAAS1jB,GACpB,GAAI2jB,GAAM5f,EAAQ0G,EAASgX,EAASmC,EAAahC,CAEjD,QAEIiC,SAAU,SAASC,GAEf,MADAH,GAAOG,EACA59B,MAOX69B,WAAY,SAAS1C,GAEjB,MADAtd,GAASsd,EACFn7B,MAGX89B,gBAAiB,SAASC,GAEtB,MADArC,GAAwBqC,EACjB/9B,MAIXg+B,YAAa,SAAStB,GAElB,MADAnY,GAAUmY,EACH18B,MAIXi+B,YAAa,SAASC,GAElB,MADA3C,GAAU2C,EACHl+B,MAIXm+B,gBAAiB,WAEb,MADAT,IAAc,EACP19B,MAIXk8B,KAAM,SAASb,GAKX,MAJIqC,IAAe/9B,GAAG2F,SAAS,MAAO,UAAWsS,EAAQiP,SAAW,IAChEhJ,EAAOugB,aAAc,GAAIC,OAAOC,WAG7BrB,EAAcnjB,EAAIuhB,EAAQoC,EAAM5f,EAAQ6d,EAAuBnX,EAASgX,MAK3FgD,SAAU,SAASzkB,GACf6gB,EAAQ7gB,OC1YpBna,GAAG6+B,cAAgB,SAASzjB,GACxB,YAEA,IAAI0jB,GAAQ1jB,EAAK0jB,MACbC,KACAtT,EAAWqT,EAAMrT,SACjBxL,EAAU6e,EAAM7e,OAEpBjgB,IAAG6B,OAAOxB,MACNmQ,IAAK,SAAS2J,EAAI6kB,GACdD,EAAU5kB,GAAM6kB,EAChBD,EAAU5kB,GAAI/J,SAGlB0P,OAAQ,SAAS3F,GACb,GAAIhC,GAAO9X,KACPqrB,EAA2B,GAAI1rB,IAAG4L,OACjB6f,GAAStR,EAAI8F,EAAQ9F,GAAKuR,GAEhC5U,KAAK,WACZqB,EAAK2I,QAAQ3G,KACb4kB,EAAU5kB,GAAIykB,UAAW,EACzBzmB,EAAKoL,QAAQpJ,IAEjBuR,EAAyB5f,aAIjCyX,QAAS,SAASpJ,SACP4kB,GAAU5kB,IAGrB8kB,oBAAqB,SAAS9kB,GAC1B,MAAO4kB,GAAU5kB,GAAI1K,KAGzBqR,QAAS,SAAS3G,GACd,MAAyBhW,UAAlB46B,EAAU5kB,IAGrBN,MAAO,WACHklB,MAGJG,cAAe,SAAS/kB,GACpB,MAAO4kB,GAAU5kB,IAGrBglB,qBAAsB,SAAShlB,EAAIilB,GAC/BL,EAAU5kB,GAAI1K,IAAM2vB,GAGxBC,aAAc,SAASllB,GACnB,QAAS4kB,EAAU5kB,GAAIykB,aCpDnC5+B,GAAGqtB,wBAA0B,SAASxV,EAAGiT,GACrC,YAEA,IAGcwU,GAAsBn5B,EAAKmpB,EAHrCiQ,EAAal/B,KACbm/B,GAAmB,EACnBC,GAA6B,EAGjCxnB,GACIwP,eACAL,eAAgB,EAChB/R,UACImL,SAAS,EACT3W,UACI2W,SAAS,IAGjBra,IAAK,SAAS4B,EAAK1B,KACnB6kB,WAAY,SAAS/Q,EAAIlI,EAAUkZ,EAAQC,KAC3CE,WAAY,SAASnR,EAAIlI,EAAUkgB,EAAU5G,KAC7CE,SAAU,SAAStR,EAAIlI,KACvB2Z,aAAc,SAASzR,KACvB2R,SAAU,SAAS3R,EAAIlI,KACvBga,cAAe,SAAS9R,EAAIlI,EAAUia,KACtCI,qBAAsB,SAASnS,EAAI+R,EAAWiG,EAAU5G,KACxDmB,YAAa,SAASvS,EAAIlI,EAAUkgB,EAAU5G,KAC9CiB,SAAU,SAASrS,EAAIlI,EAAUia,EAAWO,KAC5CI,cAAe,SAAS1S,EAAIoC,KAC5B0D,QAAS,SAAS9F,KAClB2S,QAAS,SAAS3S,EAAIyC,KACtBqQ,SAAU,SAAS9S,KACnB6C,mBAAoB,SAAS7C,KAC7B8C,cAAe,SAAS9C,KACxB+S,aAAc,SAAS/S,MAG3BulB,GAEInoB,KAAM,SAAS4C,EAAIwlB,EAAUxN,EAAU5G,GACnC,GAAIW,GAAYoD,EAAQsQ,cAAczlB,EAAIwlB,EAE1CrQ,GAAQ4P,cAAc/kB,GAAI0lB,kBAAmB,QAEtCvQ,GAAQ4P,cAAc/kB,GAAI/J,KAAK0vB,cAAcH,GACpDrQ,EAAQ4P,cAAc/kB,GAAIgR,QAAUe,EAAU3Q,KAE9CtD,EAAQqU,qBAAqBnS,EAAImV,EAAQyQ,yBAAyB7T,GAAYiG,EAAU5G,IAK5FyU,SAAU,SAAS7lB,GACf,GAAIoB,GAAOtD,EAAQ0K,QAAQxI,GACvBpY,EAAOkW,EAAQgI,QAAQ9F,EAE3BhU,GAAI,qCAAuCgU,EAAK,qBAChDmV,EAAQ2Q,eAAe9lB,GAAIrD,KACvB,SAASqb,EAAU5G,GACfplB,EAAI,2BAA6BgU,EAEjC,IAAI+lB,GAAoBl2B,EAAOm2B,kBAAkBhO,GAAU,EAE3Dla,GAAQiT,WAAW/Q,EAAIpY,EAAMwZ,EAAMA,GACnC+T,EAAQ8Q,+BAA+BjmB,GACvCnQ,EAAOq2B,QAAQlmB,EAAI+lB,EAAmB3U,IAE1C,SAAS4G,EAAU5G,GACf,GAAI+U,GAAqBt2B,EAAOm2B,kBAAkBhO,GAAU,EAE5DhsB,GAAI,yCAA2CgU,EAAK,MAAQmmB,EAAmBn2B,MAAO,UAGlFm2B,EAAmBzmB,OAClB0R,GAAOtT,EAAQ5C,SAASvJ,QAAQktB,cAAcrzB,QAAQ4lB,EAAI9Q,SAAW,IAEtEilB,EAAQ7lB,MAAMM,GAGblC,EAAQyU,YAAYvS,EAAIpY,EAAMu+B,EAAoB/U,IACnDvhB,EAAOq2B,QAAQlmB,EAAImmB,EAAoB/U,MAMvDgV,cAAe,SAASZ,EAAUxlB,EAAIgY,EAAU5G,GAC5C,GAAIxpB,GAAOkW,EAAQgI,QAAQ9F,EAE3BhU,GAAI,qCAAuCgU,EAAK,WAAawlB,GAE7DrQ,EAAQkR,iBAAiBrmB,EAAIwlB,EAE7B,IACIc,GADAC,EAAmB12B,EAAOm2B,kBAAkBhO,GAAU,EAG1D,IAAIuO,EAAiB7mB,MACjB6lB,EAAQ7lB,MAAMM,OAEb,CACD,GAAIwmB,GAAwBrR,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,UAE/DH,GAAgBE,EAAwB3gC,GAAG2F,QAAQg7B,EAAuBhB,IAAY,EAClFc,GAAiB,IACjBnR,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,WAAWvkB,OAAOokB,EAAe,GACpEnR,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAUC,QAAQnB,IAMxDrQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,gBAG5BtB,IACAnQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,eAAgB,EAE/C56B,EAAInG,GAAG8H,OAAO,mFAAoFyJ,KAAKmrB,UAAUj2B,OAAOu6B,KAAK1R,EAAQ2R,SAAS9mB,KAAO5I,KAAKmrB,UAAUpN,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,cACvM5gC,GAAG+C,KAAKusB,EAAQ2R,SAAS9mB,GAAK,SAAS+mB,EAAMC,GACzCh7B,EAAInG,GAAG8H,OAAO,sDAAuDqS,EAAI+mB,EAAMC,EAAMvE,aACrFuE,EAAMC,QAGND,EAAME,YAAa,IAIvB/R,EAAQgS,0BAA0BnnB,GAIlConB,EAAkBC,KAAKrnB,GAAI,IAG1BlC,EAAQyU,YAAYvS,EAAIpY,EAAM2+B,EAAkBnV,IAIjDvhB,EAAOq2B,QAAQlmB,EAAIumB,EAAkBnV,KAKjDkW,aAAc,SAAStnB,GACnB,QAASmV,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAU96B,QAG1D27B,SAAU,SAASvnB,GACf,GAAIwnB,GAAUrS,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAUvuB,OAM3D,OAJIqvB,IAAWrS,EAAQsS,gBAAgBznB,KACnCwnB,EAAU,MAGPA,GAGX9nB,MAAO,SAASM,GACZhU,EAAI,8FAAgGgU,EAAI,SAExGmV,EAAQ8Q,+BAA+BjmB,GACvCmV,EAAQuS,mBAAmB1nB,GAC3BmV,EAAQ4P,cAAc/kB,GAAIgR,OAAS,EACnCmE,EAAQ4P,cAAc/kB,GAAI0lB,kBAAmB,GAGjDiC,SAAU,SAAS3nB,GACf,GAAIoB,GAAOtD,EAAQ0K,QAAQxI,GACvBpY,EAAOkW,EAAQgI,QAAQ9F,GACvBwlB,EAAWD,EAAQgC,SAASvnB,GAC5B+R,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCZ,EAAYzP,EAAQ4P,cAAc/kB,GAClC+e,EAAW6F,EAAUc,iBACrBkC,EAAmBhD,EAAU1pB,SAASurB,cAe1C,IAbwB,MAApB7B,EAAU5T,SACV4T,EAAU5T,OAAS,GAInB+N,GAAYjhB,EAAQuU,SAASrS,EAAIpY,EAAMmqB,EAAW6S,EAAUtS,qBAAsB,IAClFiT,EAAQ7lB,MAAMM,GACdwlB,EAAWD,EAAQgC,SAASvnB,GAC5B+R,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCzG,GAAW,GAIC,MAAZyG,GAAgD,IAA5BoC,EAAiBh8B,OACrC25B,EAAQM,SAAS7lB,OAIhB,CACD4nB,EAAiB7+B,KAAKy8B,GACtBrQ,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,WAAamB,EAE5CtC,GACA8B,EAAkBlF,KAAKliB,EAAIwlB,GAG3BF,GAA8B8B,EAAkBS,aAAe1S,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAU96B,QAC5G25B,EAAQoC,SAAS3nB,GAGO,IAAxB+R,EAAU5gB,KAAKiQ,OACfpV,EAAInG,GAAG8H,OAAO,+DAAgE63B,EAAUxlB,GAAK,SAC7FulB,EAAQa,cAAcZ,EAAUxlB,EAAI,8BAA+B,MAG5ClC,GAAQgU,cAAc9R,EAAIpY,EAAMutB,EAAQyQ,yBAAyB7T,IAEvEpV,KACjB,SAASmrB,GACL,GAAKhqB,EAAQiV,aAAa/S,GAGrB,CACDhU,EAAInG,GAAG8H,OAAO,oEAAqEqS,EAAIwlB,EAAUzT,EAAUphB,MAAQ,EAAGohB,EAAUnhB,IAAKwQ,GAErI,IAAI2mB,IACAvC,SAAUA,EACVxlB,GAAIA,EACJgoB,UAAWF,EACX/I,SAAUA,EAGd5J,GAAQ8S,YAAYF,GAAiBprB,KAEjC,SAAiBqb,EAAU5G,GACvBplB,EAAI,wCAA0CgU,EAAK,WAAawlB,GAEhErQ,EAAQkR,iBAAiBrmB,EAAIwlB,EAE7B,IAAIoC,GAAmBzS,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,eACtDF,EAAmB12B,EAAOm2B,kBAAkBhO,GAAU,GACtDkQ,EAAqBriC,GAAG2F,QAAQo8B,EAAkBpC,EAEtDx5B,GAAInG,GAAG8H,OAAO,8CAA+C63B,EAAUxlB,IAEvEulB,EAAQnoB,KAAK4C,EAAIwlB,EAAUe,EAAkBnV,GAEzC8W,GAAsB,GACtBN,EAAiB1lB,OAAOgmB,EAAoB,GAGhD/S,EAAQgT,0BAA0BnoB,GAE7BulB,EAAQ+B,aAAatnB,IAAmC,IAA5B4nB,EAAiBh8B,OAGzC25B,EAAQ+B,aAAatnB,GAC1BulB,EAAQoC,SAAS3nB,GAGjBhU,EAAInG,GAAG8H,OAAO,oGAAqGqS,EAAI5I,KAAKmrB,UAAUqF,KANtIrC,EAAQM,SAAS7lB,IAWzB,SAAiBgY,EAAU5G,GACvBmU,EAAQa,cAAcZ,EAAUxlB,EAAIgY,EAAU5G,KAGjDhU,KAAK,WACF+X,EAAQiT,SAASpoB,EAAIwlB,SAlD7Bx5B,GAAInG,GAAG8H,OAAO,6EAA8EqS,EAAIwlB,KAuDxG,SAASx1B,GACLu1B,EAAQa,cAAcZ,EAAUxlB,EAAIhQ,EAAO,WAO/Do3B,GACIiB,SACAC,eACAC,YAEAV,UAAW,WACP,GAAIvU,GAAMxV,EAAQmP,eACdub,EAAwB,EACxBC,EAAkB,CAOtB,OALA5iC,IAAG+C,KAAKw+B,EAAkBkB,YAAa,SAASzhB,EAAQ6hB,GACpDF,IACAC,GAAmBC,EAAiB98B,SAGjC0nB,GAAO8T,EAAkBiB,MAAMz8B,OAAS48B,EAAwBC,IAM3EpB,KAAM,SAASrnB,EAAI2oB,GACf,GAGI7H,GAHA8H,GAAaD,EACbE,EAAehjC,GAAG2F,QAAQ47B,EAAkBmB,SAAUvoB,GACtD8oB,EAAmBjjC,GAAG2F,QAAQ47B,EAAkBiB,MAAOroB,SAGpDonB,GAAkBkB,YAAYtoB,GAEjCnQ,EAAOk5B,eAAe/oB,YAAena,IAAGwX,YACxCrR,EAAI,uCAAyCgU,EAAK,qCAC3CmV,GAAQ4P,cAAc/kB,GAAIqB,MAIjCwnB,GAAgB,EAChBzB,EAAkBmB,SAASrmB,OAAO2mB,EAAc,GAG3CD,GAAaE,GAAoB,IACtC1B,EAAkBiB,MAAMnmB,OAAO4mB,EAAkB,GAEjDhI,EAASsG,EAAkBmB,SAASpwB,QAChC2oB,GAAU,IACVsG,EAAkBiB,MAAMt/B,KAAK+3B,GAC7BjxB,EAAOc,MAAMmwB,MAKzBkI,sBAAuB,WACnB,GAAIC,KAqBJ,OAjBApjC,IAAG+C,KAAKw+B,EAAkBkB,YAAa,SAASzhB,EAAQqiB,GAChDA,GAAUA,EAAOt9B,QACjBq9B,EAAmBlgC,KAAKogC,SAAStiB,MAMzChhB,GAAG+C,KAAKw+B,EAAkBiB,MAAO,SAASx/B,EAAKge,GACtCugB,EAAkBkB,YAAYzhB,IAC/BoiB,EAAmBlgC,KAAKogC,SAAStiB,MAKzCoiB,EAAqBA,EAAmBpzB,OAAOuxB,EAAkBmB,WAKrEa,kBAAmB,SAASppB,GACxB,MAAOna,IAAG2F,QAAQ47B,EAAkBiB,MAAOroB,IAAO,GAGtDkiB,KAAM,SAASliB,EAAIwlB,GAKf,MAJgB,OAAZA,GACA4B,EAAkBmB,SAASx/B,KAAKiX,KAGhConB,EAAkBS,cACF,MAAZrC,GACA4B,EAAkBmB,SAASc,MAC3BjC,EAAkBiB,MAAMt/B,KAAKiX,IAG5B,WACG,GAAIspB,GAAkBlC,EAAkBkB,YAAYtoB,MACpDspB,GAAgBvgC,KAAKy8B,GACrB4B,EAAkBkB,YAAYtoB,GAAMspB,MAIrC,IAMf5pB,MAAO,WACH0nB,EAAkBmB,YAClBnB,EAAkBiB,WAI1BkB,GACInH,KAAM,SAASpiB,EAAIpY,GACf,GAAIg9B,GAAYzP,EAAQ4P,cAAc/kB,EAEtC,KAAK4kB,EAED,WADA54B,GAAI,yEAA2EgU,EAAI,OAIvF4kB,GAAU5T,OAAS,EAEnBhlB,EAAI,qCAAuCgU,GAC3CmV,EAAQqU,WAAWxpB,GAAIrD,KACnB,SAASqb,EAAUuJ,GACfv1B,EAAI,uCAAyCgU,EAE7C,IAAIumB,GAAmB12B,EAAOm2B,kBAAkBhO,GAAU,GACtD5W,EAAOtD,EAAQ0K,QAAQxI;+CAE3BlC,GAAQiT,WAAW/Q,EAAIpY,EAAMwZ,EAAMA,GACnCvR,EAAO45B,aAAazpB,EAAIumB,GACxB12B,EAAOq2B,QAAQlmB,EAAIumB,EAAkBhF,IAGzC,SAASvJ,EAAUuJ,GACfv1B,EAAI,oCAAsCgU,EAE1C,IAAIumB,GAAmB12B,EAAOm2B,kBAAkBhO,GAAU,EAErDla,GAAQyU,YAAYvS,EAAIpY,EAAM2+B,EAAkBhF,IACjD1xB,EAAOq2B,QAAQlmB,EAAIumB,EAAkBhF,OAOzD1xB,GACI8V,OAAQ,SAAS3F,GACbhU,EAAI,cAAgBgU,GACpBlC,EAAQwP,YAAYrmB,OAAO+Y,GAC3BonB,EAAkBC,KAAKrnB,IAG3BkmB,QAAS,SAASlmB,EAAIgY,EAAUuJ,GAC5B,GAAI35B,GAAOkW,EAAQgI,QAAQ9F,EAE3BlC,GAAQqT,WAAWnR,EAAIpY,EAAMowB,EAAUuJ,GAEnCpM,EAAQ4P,cAAc/kB,IACtBmV,EAAQuU,YAAcvU,EAAQuU,WAAW1pB,GAG7ConB,EAAkBC,KAAKrnB,IAK3B+oB,eAAgB,SAAS/oB,GACrB,MAAQmV,GAAQwU,UAAYxU,EAAQwU,SAAS3pB,IACxCmV,EAAQ5N,SAAW4N,EAAQ5N,QAAQvH,IAG5C4pB,YAAa,WAITzU,EAAU,IAHQxE,EAAY9qB,GAAG8qB,GAAa9qB,GAAGgkC,cACtBhkC,GAAG8S,kBAAkBoC,cAAgB,MAAQ,QAEvB,iBAC7C+C,GAEIkV,oBAAqBlV,EAAQkV,oBAC7BH,cAAe/U,EAAQ+U,cACvB/M,QAAShI,EAAQgI,QACjB0C,QAAS1K,EAAQ0K,QACjBO,QAASjL,EAAQiL,QACjB/c,IAAKA,EACLslB,SAAUxT,EAAQwT,SAClBP,WAAYjT,EAAQiT,WACpB2B,cAAe5U,EAAQ4U,cACvBoX,aAAc,SAAS9pB,GACnBlC,EAAQgE,UAAU9B,EAAIna,GAAGya,OAAO+C,sBAKxC8R,EAAQ4U,+BACR5U,EAAQ4U,iCAIhBC,4BAA6B,SAAShqB,GAClC,MAAOlC,GAAQgV,SAAS9S,IAM5BiqB,WAAY,SAASjqB,EAAI7O,GAIrB,MAAIA,KAASgkB,EAAQ5N,QAAQvH,IAAO7O,YAAgBtL,IAAGwX,WAKnDS,EAAQ2T,aAAazR,GAErBhU,EAAI,+CAAiDgU,GACrD7O,EAAKqM,SAASb,KAAK,SAASutB,GACxBl+B,EAAI,mCAAqCgU,GAGzCmV,EAAQgV,WAAWnqB,EAAIkqB,GAGvBpsB,EAAQ6U,QAAQ3S,EAAIkqB,EAAc9oB,MAGlC+T,EAAQuS,mBAAmB1nB,GAE3BnQ,EAAOu6B,uBAAuBpqB,IAIlC,SAAS6L,GACL,GAAIwe,KAEAxe,KACAwe,EAAcr6B,MAAQ6b,GAG1B7f,EAAInG,GAAG8H,OAAO,yDAA0DqS,EAAI6L,GAAe,SAE3F/N,EAAQqT,WAAWnR,EAAIlC,EAAQgI,QAAQ9F,GAAKna,GAAG6B,OAAO2iC,EAAelF,GAAuB,MAC5Ft1B,EAAOu6B,uBAAuBpqB,GAC9BonB,EAAkBC,KAAKrnB,MAOxB,GAHInQ,EAAOu6B,uBAAuBpqB,IAO7CoqB,uBAAwB,SAASpqB,GAC7B,GAAIsqB,GAAaxsB,EAAQ+E,mBAAmB7C,GACxCuqB,GAAiB,CAoBrB,OAlBID,IAAcA,EAAW1+B,QACzBI,EAAI,0CAA4CgU,GAEhDna,GAAG+C,KAAK0hC,EAAY,SAASzhC,EAAK2hC,GAC9B,GAAI36B,EAAOm6B,4BAA4BQ,IAAgBrV,EAAQ5N,QAAQijB,GACnED,EAAiBC,IAAcxqB,EAC/BnQ,EAAO46B,IAAID,OAEV,IAAI36B,EAAOm6B,4BAA4BQ,GACxC,OAAO,MAKfD,GAAiB,EACjB16B,EAAO46B,IAAIzqB,IAGRuqB,GAGXd,aAAc,SAASzpB,EAAIgY,GACEhuB,SAArBguB,EAAS5V,SACTtE,EAAQ4U,cAAc1S,EAAIgY,EAAS5V,UAO3C4jB,kBAAmB,SAAS0E,EAAkBhS,GAC1C,GAAIV,GAAW0S,CAcf,OAVK7kC,IAAGuG,SAASs+B,KACb1S,KAEInyB,GAAGwH,SAASq9B,KAAsBhS,IAClCV,EAAShoB,MAAQ06B,IAIzB1S,EAASrmB,QAAU+mB,EAEZV,GAGXyS,IAAK,SAASzqB,GACV,GAAIpY,GAAOkW,EAAQgI,QAAQ9F,EAE3B,KAAKolB,EAAWze,QAAQ3G,GACpB,KAAM,IAAIna,IAAGwB,MAAM2Y,EAAK,qCAG5BlC,GAAQ6T,SAAS3R,EAAIpY,GAAM+U,KACvB,SAASqb,GACDA,GAAYA,EAASlc,OACrBgC,EAAQgE,UAAU9B,EAAIna,GAAGya,OAAO6C,QAChCgS,EAAQrZ,MAAMkE,GACdonB,EAAkBC,KAAKrnB,IAGnBqlB,GAAoBlQ,EAAQwV,qBAAqB3qB,GACjDulB,EAAQoC,SAAS3nB,GAGjBupB,EAAOnH,KAAKpiB,EAAIpY,IAK5B,SAASoI,GAKL,GAJAA,EAAQA,MAERhE,EAAIgU,EAAK,qEAAuEhQ,EAAO,UAElF8N,EAAQyU,YAAYvS,EAAIpY,EAAMoI,EAAMwiB,kBAAqB,CAC1D,GAAIwF,GAAWnoB,EAAOm2B,kBAAkBh2B,EAAMwiB,cAAc,EAC5D3iB,GAAOq2B,QAAQlmB,EAAIgY,OAMnCrnB,MAAO,SAASqP,GACZ,GAAI4qB,GAAe/6B,EAAOk5B,eAAe/oB,EAEzC,OAAI4qB,GACO/6B,EAAOo6B,WAAWjqB,EAAI4qB,IAG7B/6B,EAAO46B,IAAIzqB,IACJ,IAKnBna,IAAG6B,OAAOxB,MAINmQ,IAAK,SAAS2J,EAAIqB,GACd8T,EAAQ9e,IAAIP,MAAM5P,KAAM8H,YAM5B6B,OAAQ,SAASmQ,GACb,QAAIonB,EAAkBlF,KAAKliB,IAChBnQ,EAAOc,MAAMqP,IAK5BmK,MAAO,SAASnK,GAWZ,MANIslB,KACAnQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,eAAgB,GAK/CQ,EAAkBgC,kBAAkBppB,GAC7BnQ,EAAOc,MAAMqP,GAObolB,EAAWv1B,OAAOmQ,IAOjC2F,OAAQ,SAAS3F,GACb,GAAI6qB,GAAe1V,EAAQxP,OAAO3F,EAE9Bna,IAAG4W,iBAAiBouB,GACpBA,EAAaluB,KAAK,WACd9M,EAAO8V,OAAO3F,KAGb6qB,KAAiB,GACtBh7B,EAAO8V,OAAO3F,IAOtBgG,UAAW,WACP,GACIzP,GADA0yB,EAAqB7B,EAAkB4B,uBAK3C,IAAIC,EAAmBr9B,OACnB,IAAK2K,EAAI0yB,EAAmBr9B,OAAS,EAAG2K,GAAK,EAAGA,IAC5C6uB,EAAWzf,OAAOsjB,EAAmB1yB,GAI7C6wB,GAAkB1nB,SAKtB6H,QAAS,SAASvH,GACd,MAAImV,GAAQwU,UAAYxU,EAAQwU,SAAS3pB,GAC9BmV,EAAQwU,SAAS3pB,GAAI1C,cAGzB6X,EAAQ5N,SAAW4N,EAAQ5N,QAAQvH,IAI9C8qB,UAAW,SAAS9qB,GAChB,SAAUmV,EAAQwU,WAAYxU,EAAQwU,SAAS3pB,KAGnDZ,SAAU,SAASY,GACf,GAAImV,EAAQ/V,SACR,MAAO+V,GAAQ/V,SAASY,IAIhCN,MAAO,WACH1T,EAAI,4BACJo5B,EAAWpf,YACXohB,EAAkB1nB,QAClByV,EAAQzV,SAGZ0J,QAAS,SAASpJ,GACd,GAAIolB,EAAWze,QAAQ3G,GACnB,MAAOmV,GAAQ/L,QAAQpJ,IAO/B2G,QAAS,SAAS3G,GACd,MAAOmV,GAAQxO,QAAQ3G,IAG3BiJ,gBAAiB,SAASjJ,GACtB,GAAI1K,GAAM6f,EAAQxO,QAAQ3G,IACtBmV,EAAQ4V,oBACR5V,EAAQ4V,mBAAmB/qB,EAE/B,SAAI1K,KACSqE,aAAapE,QAAQD,IAMtCiT,sBAAuB,WACnB,MAAI4M,GAAQ5M,sBACD4M,EAAQ5M,4BAavBuc,oBAAqB,SAAS9kB,GAC1B,GAAIolB,EAAWze,QAAQ3G,GACnB,MAAOmV,GAAQ2P,oBAAoB9kB,IAS3ClE,MAAO,SAASkE,GACZ,SAAIolB,EAAWpc,YAAYhJ,IAAOmV,EAAQrZ,OAASspB,EAAWze,QAAQ3G,IAAOmV,EAAQrZ,MAAMkE,MACvFonB,EAAkBC,KAAKrnB,GACvBmV,EAAQgS,0BAA0BnnB,IAC3B,IAKfgrB,mBAAoB,SAAShrB,GACzB,QAASmV,EAAQ6V,oBAAsB7V,EAAQ6V,mBAAmBhrB,IAItEgJ,YAAa,SAAShJ,GAClB,QAASmV,EAAQnM,aAAemM,EAAQnM,YAAYhJ,MAI5Dna,GAAG6B,OAAOoW,EAASJ,GACnB1R,EAAM8R,EAAQ9R,IACdq5B,EAAmBvnB,EAAQ5C,SAASmL,SAAWxgB,GAAG8S,kBAAkBuC,SACpEoqB,EAA6BD,GAAoBvnB,EAAQ5C,SAASkjB,WAAW/X,QAE7E8e,EAAwB,WACpB,GAAInN,KAIJ,OAFAA,GAASla,EAAQ+S,oBAAqB,EAE/BmH,KAGXnoB,EAAO+5B,eC1zBX/jC,GAAGolC,qBAAuB,SAASvtB,GAC/B,YAEA,IAAII,IACI9R,IAAK,SAASC,EAASC,MAE3Bg/B,IAEJrlC,IAAG6B,OAAOoW,EAASJ,GAEnB7X,GAAG6B,OAAOxB,MACNilC,eAAgB,SAASnrB,EAAI9K,GACzB,GAAIk2B,GAA2B,SAASrQ,GAChC7lB,EAAS6lB,EAAMlwB,MAGnBE,QAAO+P,YACPowB,EAAyBlrB,GAAMna,GAAGkF,QAAQ5E,OAAO,UAAWilC,GAG5Dp/B,IAAI,wDAAyD,UAIrEq/B,sBAAuB,SAASrrB,GAC5B,GAAIjV,OAAO+P,YAAa,CACpB,GAAIwwB,GAAWJ,EAAyBlrB,EACpCsrB,IACAA,SCvBpBzlC,GAAG0lC,kBAAoB,SAAStqB,GAC5B,YAoBA,SAASuqB,GAAYxrB,SACVyrB,GAAiBzrB,GAKpB0rB,IACAvS,aAAawS,EAA0B3rB,UAChC2rB,GAA0B3rB,GACjC4rB,EAAoBP,sBAAsBrrB,GAG9C,IAAI6rB,GAASr8B,SAASs8B,eAAe3W,EAAQ4W,eAAe/rB,GACxD6rB,KAIAA,EAAO70B,aAAa,MAAO,qBAE3BnR,GAAGgmC,GAAQ5kC,UAQnB,QAAS+kC,GAAuBC,GAC5B,MAAOA,GAAW1gC,MAAM,KAAK,GAUjC,QAAS2gC,GAAoBtkC,GACzB,GAAIikC,GAAShmC,GAAGgP,UAAU,yCAA2CjN,EAAO,OAO5E,OALAikC,GAAO70B,aAAa,KAAMpP,GAE1BikC,EAAO7lC,MAAMC,QAAU,OACvBuJ,SAAS28B,KAAKl1B,YAAY40B,GAEnBA,EAUX,QAASO,GAA4BP,EAAQ32B,GACzC,GAAI+2B,GAAaJ,EAAO7rB,GACpB6G,EAASmlB,EAAuBC,EAGpCI,GAFWtjB,EAAQlC,IAEK3R,EAIxBu2B,EAAiB5kB,GAAUhhB,GAAGgmC,GAAQ1lC,OAAO,OAAQ,WAC7CgvB,EAAQ/V,SAASyH,KACjB7a,EAAI,mEAAqEigC,EAAa,KAEtFN,EAA0BM,GAAczc,WAAW,WAC/C,GAAI3D,GAAe,gEAAkEogB,CACrFjgC,GAAI6f,EAAc,SAClB3W,GACIlF,MAAO6b,KAEZ,QAMX+f,EAAoBT,eAAec,EAAY,SAAShgC,GACpDD,EAAI,2CAA6CC,EAAU,IAC3D,IAGIqgC,GAFAtU,GADSgU,EAAuBC,GACrB9W,EAAQoX,mBAAmBtgC,IACtCkU,EAAO6X,EAAS7X,IAGhBA,IAAQksB,EAAgBlsB,IACxBnU,EAAI,qCAAuCigC,GAC3C9S,aAAawS,EAA0BM,UAChCN,GAA0BM,GAEjC9W,EAAQqX,iBAAiBP,GAEzBK,EAAiBD,EAAgBlsB,SAE1BksB,GAAgBlsB,GACvByrB,EAAoBP,sBAAsBY,GAC1CK,EAAetU,IAET7X,GACNnU,EAAI,IAAMC,EAAU,2CAxHhC,GAAI6R,GAAUmD,EAAKnD,QACfqX,EAAUjvB,KACVy+B,EAAQ1jB,EAAK0jB,MACb8H,EAAwB5mC,GAAGiN,cAC3Bu5B,KACAZ,KACAE,KACAD,EAAS5tB,EAAQ4tB,OACjBrb,EAAYvS,EAAQuS,UACpBtH,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,IACZ4/B,EAAsB,GAAI/lC,IAAGolC,sBAAsBj/B,IAAKA,GAkH5DnG,IAAG6B,OAAOxB,KAAM,GAAIL,IAAG6+B,cAAczjB,IAErCpb,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OAIIgE,IAAK,SAAS2J,EAAIkU,GACd7hB,EAAOgE,IAAI2J,GAAKzQ,MAAO2kB,IAEvBA,EAAUld,aAAa,OAAQqZ,GAG3B6D,EAAUltB,YACVnB,GAAGquB,GAAWjtB,UAItBmiB,QAAS,SAASpJ,GACdwrB,EAAYxrB,GACZ3N,EAAO+W,QAAQpJ,IAGnB2G,QAAS,SAAS3G,GACd,MAAO3N,GAAOsU,QAAQ3G,IACkBhW,SAApCmrB,EAAQ4P,cAAc/kB,GAAIzQ,UAK1C1J,GAAG6B,OAAOxB,MACNkZ,SAAU,SAASY,GACf,MAAOmV,GAAQ4P,cAAc/kB,GAAIzQ,OAWrCm9B,iBAAkB,SAASb,EAAQ32B,GAE/B,GAAIy3B,EAEAjB,GACAU,EAA4BP,EAAQ32B,GAGpCu2B,EAAiBI,EAAO7rB,IAAMna,GAAGgmC,GAAQ1lC,OAAO,OAAQ,WAMpD,GALA6F,EAAI,yBAA2B6/B,EAAO7rB,IAKjC6rB,EAAO7kC,WAAZ,CAIA,IAEI,GAAI6kC,EAAOe,iBACPf,EAAOe,gBAAgBT,MACkB,SAAzCN,EAAOe,gBAAgBT,KAAKn3B,UAK5B,OAGR,MAAOhF,GAEHhE,EAAI,8EAAgFgE,EAAM/D,QAAU,IAAK,SACzG0gC,GAAsBh7B,SAAS,GAGnCuD,EAASy3B,OAWrBE,cAAe,SAAS7sB,GAGpB,MAAOksB,GAFU/W,EAAQ4W,eAAe/rB,KAU5CwsB,iBAAkB,SAASxsB,GACMhW,SAAzByhC,EAAiBzrB,KACjByrB,EAAiBzrB,WACVyrB,GAAiBzrB,KAQhC+rB,eAAgB,SAASllB,GACrB,MAAOA,GAAS,IAAM4lB,GAY1BK,mBAAoB,SAAS7rB,GACzB,GAAI8L,GAAS9L,EAAK8L,OACd/I,EAAW/C,EAAK+C,SAChBD,EAAS9C,EAAK8C,OACdgZ,EAAe9b,EAAK8b,aACpBgQ,EAAa9rB,EAAK8rB,WAClBh2B,EAAOlR,GAAGgP,UAAU,iBAAmBkY,EAAS,2CAChDyU,EAAMxd,CAcV,OAZI+Y,GACAl3B,GAAGiR,WAAWiN,EAAQhN,GAGtByqB,EAAM37B,GAAGkQ,QAAQgO,EAAQC,GAG7BjN,EAAKC,aAAa,SAAUwqB,GAC5BzqB,EAAKC,aAAa,SAAU+1B,GAC5Bh2B,EAAK/Q,MAAMC,QAAU,OACrBuJ,SAAS28B,KAAKl1B,YAAYF,GAEnBA,GAOXw1B,mBAAoB,SAASS,GACzB,GAAIhV,KAEJ,KACIA,EAAWnyB,GAAGqR,UAAU81B,GAE5B,MAAOh9B,GACHhE,EAAI,0DAA4DgE,EAAM/D,QAAU,IAAK,SAGzF,MAAO+rB,OCnSnBnyB,GAAGonC,iBAAmB,SAAShsB,GAC3B,YAqCA,SAASgmB,GAAMjnB,GACXna,GAAG+C,KAAKusB,EAAQ2R,SAAS9mB,GAAK,SAASktB,EAAO9b,GAC1C,GAAI+b,GAAgBhY,EAAQiY,kBAAkBptB,EAAIktB,EAElD9b,GAAI2Q,mBAAqB,KACzB3Q,EAAIvhB,OAAO4wB,WAAa,KACxBrP,EAAI6V,QACJkG,GAAiBA,EAAc1I,UAAY0I,EAAc1I,SAASzkB,KA1C1E,GAAImV,GAAUjvB,KACVyqB,EAAY1P,EAAKnD,QAAQ6S,UACzBgU,EAAQ1jB,EAAK0jB,MACbzpB,EAAW+F,EAAKnD,QAAQ5C,SACxBmyB,EAAe,SAASrtB,GACpB,GAAI4kB,GAAYzP,EAAQ4P,cAAc/kB,EAEtC,IAAI4kB,EAAUpG,UACV,MAAOoG,GAAUpG,SAIjB,IAAIA,GAAYtjB,EAASyjB,QAOzB,OALI94B,IAAG6G,WAAW8xB,KACdA,EAAYA,EAAUxe,EAAIwI,EAAQxI,KAGtC4kB,EAAUpG,UAAYA,EACfA,GAGfxiB,EAASiF,EAAKnD,QAAQ9B,OACtBsxB,EAAapyB,GAAY+F,EAAKnD,QAAQ5C,SAASmL,SAAWxgB,GAAG8S,kBAAkBuC,SAC/EqyB,EAAgBvxB,GAAUiF,EAAKnD,QAAQ9B,OAAOqK,SAAWinB,GAAcznC,GAAG8S,kBAAkBqD,OAC5F8J,EAAU6e,EAAM7e,QAChB0C,EAAUmc,EAAMnc,QAChBO,EAAU4b,EAAM5b,QAChBhB,EAAc4c,EAAM5c,YACpB8K,EAAgB8R,EAAM9R,cACtBH,EAAgBiS,EAAMjS,cACtB3B,EAAa4T,EAAM5T,WACnB/kB,EAAM24B,EAAM34B,IACZgnB,EAAsB2R,EAAM3R,mBAahCntB,IAAG6B,OAAOxB,KAAM,GAAIL,IAAG6+B,cAAczjB,IAErCpb,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OAIIgE,IAAK,SAAS2J,EAAIwtB,GACd,GAAI3nC,GAAGuI,OAAOo/B,IAAgB3nC,GAAGuJ,OAAOo+B,GACpCn7B,EAAOgE,IAAI2J,GAAKqB,KAAMmsB,QAErB,CAAA,KAAIA,YAAuB3nC,IAAGwX,WAI/B,KAAM,IAAIhW,OAAM,2CAHhBgL,GAAOgE,IAAI2J,GAAK2kB,MAAO6I,IAM3BrY,EAAQsY,eAAeztB,GACvButB,GAAiBpY,EAAQuY,uBAAuB1tB,IAGpDoJ,QAAS,SAASpJ,GACdinB,EAAMjnB,GACNmV,EAAQ8Q,+BAA+BjmB,GACvCmV,EAAQuU,WAAW1pB,GACnB3N,EAAO+W,QAAQpJ,OAK3Bna,GAAG6B,OAAOxB,MAENmgC,iBAAkB,SAASrmB,EAAIwlB,GAC3B,GAAIZ,GAAYzP,EAAQ4P,cAAc/kB,EAElC4kB,UACOA,GAAU3uB,KAAK03B,aAAanI,IAI3C4C,SAAU,SAASpoB,EAAIwlB,GACnB,GAAIoI,GAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAEtC23B,GAAUC,YACHD,GAAUC,KAAKrI,GAEtBoI,EAAUE,sBACHF,GAAUE,eAAetI,IAMxCM,eAAgB,SAAS9lB,EAAI+tB,GACzB,GAAIC,GAAe7Y,EAAQsS,gBAAgBznB,GAAM,EAC7CoR,EAAM+D,EAAQ8Y,QAAQjuB,EAAIguB,EAE9B,OAAID,IACO,GAAIloC,IAAG4L,SAAUE,QAAQo8B,EAAe3c,GAAMA,IAGlD,GAAIvrB,IAAG4L,SAAUE,WAAYyf,IAGxC7J,QAAS,SAASvH,GACd,MAAOmV,GAAQxO,QAAQ3G,IAAOmV,EAAQ4P,cAAc/kB,GAAIqB,MAG5DsoB,SAAU,SAAS3pB,GACf,MAAOmV,GAAQxO,QAAQ3G,IAAOmV,EAAQ4P,cAAc/kB,GAAI2kB,OAO5Dpc,sBAAuB,WACnB,GAAI2lB,KAuBJ,OArBA/Y,GAAQgZ,sBAAsB,SAAS74B,EAAKsQ,GACxCuP,EAAQgS,0BAA0B,KAAMvhB,EAAW1K,SAASurB,WAAa7gB,EAAW1K,SAASwrB,UAE7F,IAAI77B,IACAjD,KAAMge,EAAWhe,KACjB8+B,UAAW9gB,EAAW1K,SAASwrB,UAC/BtlB,KAAMwE,EAAWxE,KACjBjB,KAAMyF,EAAWzF,KAGjByF,GAAWtQ,MACXzK,EAAKyK,IAAMsQ,EAAWtQ,KAGtBsQ,EAAW0M,mBACXznB,EAAKynB,iBAAmB1M,EAAW0M,kBAGvC4b,EAAmBnlC,KAAK8B,KAGrBqjC,GAGXlD,mBAAoB,SAAShrB,GACzB,MAAOmV,GAAQ4P,cAAc/kB,GAAI0lB,kBAGrC1c,YAAa,SAAShJ,GAClB,QAAS9E,GAAYia,EAAQxO,QAAQ3G,KAChCmV,EAAQ4P,cAAc/kB,GAAIouB,cAGnCjH,0BAA2B,SAASnnB,EAAIquB,EAAeC,GACnD,GAAI1J,GAAYzP,EAAQ4P,cAAc/kB,OAClCuuB,EAAiB3J,EAAU1pB,aAC3BurB,EAAa4H,GAAiBE,EAAc9H,WAC5CC,EAAY4H,GAAgBC,EAAc7H,SAE1CD,KACAz6B,EAAInG,GAAG8H,OAAO,yDAA0DyJ,KAAKmrB,UAAUkE,KACvFA,EAAW+H,UACX3oC,GAAG+C,KAAK69B,EAAY,SAAS59B,EAAK28B,GAC9BkB,EAAUC,QAAQnB,KAEtBiB,EAAW76B,OAAS,IAI5BkQ,MAAO,SAASkE,GACZ,GAAImV,EAAQxO,QAAQ3G,GAIhB,MAHAhU,GAAInG,GAAG8H,OAAO,4DAA6DqS,EAAI8F,EAAQ9F,KACvFmV,EAAQ4P,cAAc/kB,GAAIyuB,QAAS,EACnCxH,EAAMjnB,IACC,GAIf0nB,mBAAoB,SAAS1nB,GACzB,GAAI9E,GAAYia,EAAQxO,QAAQ3G,GAAK,CACjC,GACI0uB,GACAn4B,EAFA0G,EAAQkY,EAAQ4P,cAAc/kB,EAQlC,UAJO/C,GAAM/B,SAEb+B,EAAM/B,YACNwzB,EAAcvZ,EAAQsS,gBAAgBznB,GAClC0uB,EAAc,GAAKxzB,EAASmjB,UAAW,CAKvC,IAJAphB,EAAM/B,SAASmL,SAAU,EACzBpJ,EAAM/B,SAASyzB,MAAQD,EACvBzxB,EAAM/B,SAASwrB,aAEVnwB,EAAI,EAAGA,EAAIm4B,EAAan4B,IACzB0G,EAAM/B,SAASwrB,UAAU39B,KAAKwN,EAGlC4e,GAAQsY,eAAeztB,OAGvB/C,GAAM/B,SAASmL,SAAU,IAKrC8jB,WAAY,SAASnqB,EAAI4uB,GACjBzZ,EAAQxO,QAAQ3G,KAChBmV,EAAQ4P,cAAc/kB,GAAIqB,KAAOutB,IAIzClF,WAAY,SAAS1pB,GACjB,GAAI4tB,GAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAE1CpQ,IAAG+C,KAAKglC,EAAUE,eAAgB,SAASe,SAChCjB,GAAUE,eAAee,KAGpChpC,GAAG+C,KAAKglC,EAAUC,KAAM,SAASgB,SACtBjB,GAAUC,KAAKgB,MAW9BC,WAAY,SAAS9uB,EAAI+uB,GACrB,MAAO5Z,GAAQ6Z,aAAahvB,EAAI+uB,EAAalpC,GAAG+J,sBAGpDw9B,kBAAmB,SAASptB,EAAI+uB,GAC5B,GAAIvJ,GAA0B,MAAfuJ,GAAsB,EAAKA,CAC1C,OAAO5Z,GAAQ4P,cAAc/kB,GAAI/J,KAAK63B,eAAetI,IAGzDC,cAAe,SAASzlB,EAAIivB,GACxB,GAAIzQ,GAAY6O,EAAartB,GACzBkvB,EAAW1mB,EAAQxI,GACnBtP,EAAaykB,EAAQ5N,QAAQvH,GAC7BmvB,EAAa3Q,EAAYyQ,EACzBG,EAAWD,EAAa3Q,GAAa0Q,EAAWA,EAAWC,EAAa3Q,EACxEkQ,EAAcvZ,EAAQsS,gBAAgBznB,GACtC2tB,EAAeznC,KAAK6+B,cAAc/kB,GAAI/J,KAAK03B,aAI3Cx8B,EAAOw8B,EAAasB,IAAeppC,GAAG4K,UAAUC,EAAYy+B,EAAYC,EAI5E,OAFAzB,GAAasB,GAAc99B,GAGvBk+B,KAAMJ,EACNt+B,MAAOw+B,EACPv+B,IAAKw+B,EACLE,MAAOZ,EACPv9B,KAAMA,EACNiQ,KAAMguB,EAAWD,IAIzBvJ,yBAA0B,SAAS7T,GAC/B,OACIG,UAAWH,EAAUsd,KACrBE,UAAWxd,EAAUphB,MAAQ,EAC7B6+B,QAASzd,EAAUnhB,IACnB8tB,WAAY3M,EAAUud,QAQ9BvE,mBAAoB,SAAS/qB,GACzB,GACIpY,GAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,GACfwe,EAAY6O,EAAartB,GACzBgE,EAAW+D,EAAY/H,GACvBgf,EAAahjB,EAAOgjB,WAAWhf,GAC/ByvB,EAAiB5pC,GAAG8H,OAAO,2BAA4BgjB,EANvC,MAMiE/oB,EAAMwZ,EAAMod,EAAWxa,EAM5G,OAJAgb,GAAW0Q,QAAQ,SAASp6B,GACxBm6B,GAAkB,IAAMn6B,IAGrBm6B,GAGXE,aAAc,SAAS3vB,GACnB,MAAOmV,GAAQ5N,QAAQvH,GAAI5Z,MAG/BwpC,oBAAqB,SAAS5vB,GAC1B,MAAOmV,GAAQ4P,cAAc/kB,GAAI9E,UAOrCusB,gBAAiB,SAASznB,GACtB,GAAI9E,EAAU,CACV,GAAIg0B,GAAW1mB,EAAQxI,GACnBwe,EAAY6O,EAAartB,EAE7B,OAAOxY,MAAKqoC,KAAKX,EAAW1Q,KAIpCyP,QAAS,SAASjuB,EAAI+uB,GAClB,GAAIvJ,GAA0B,MAAfuJ,GAAsB,EAAKA,CAC1C,OAAO5Z,GAAQ4P,cAAc/kB,GAAI/J,KAAK43B,KAAKrI,IAG/CsB,SAAU,SAAS9mB,GACf,MAAOmV,GAAQ4P,cAAc/kB,GAAI/J,KAAK43B,MAK1CM,sBAAuB,SAASj5B,GACxBq4B,GACA1nC,GAAG+C,KAAK+Q,aAAc,SAASrE,EAAKnI,GAChC,GAAwD,IAApDmI,EAAI9J,QAAQ3F,GAAG8H,OAAO,aAAcgjB,IAAmB,CAEvDzb,EAASI,EADQ8B,KAAKC,MAAMlK,QAO5CsgC,eAAgB,SAASztB,GACrBmV,EAAQ4P,cAAc/kB,GAAI/J,MACtB63B,kBACAnI,iBACAkI,QACAF,kBAIRmC,kBAAmB,SAAS9vB,GACxBmV,EAAQ4P,cAAc/kB,GAAIouB,cAAe,GAK7CnI,+BAAgC,SAASjmB,GACrC,GAAIyvB,EAEJ,UAAIlC,GAAiBpY,EAAQnM,YAAYhJ,KACrCyvB,EAAiBta,EAAQ4V,mBAAmB/qB,GAExCyvB,GAAkB91B,aAAapE,QAAQk6B,OACvC91B,aAAao2B,WAAWN,IACjB,IASnB/B,uBAAwB,SAAS1tB,GAC7B,GACIyvB,GAAgBO,EADhB/yB,EAAQkY,EAAQ4P,cAAc/kB,EAK9ButB,IAA+BvjC,SAAdiT,EAAM3H,MACvBm6B,EAAiBta,EAAQ4V,mBAAmB/qB,GAC5CgwB,EAAgBr2B,aAAapE,QAAQk6B,GAGjCO,IACAA,EAAgB54B,KAAKC,MAAM24B,GAIvBnd,EAAcmd,EAAc7vB,MAC5BgV,EAAQ2a,kBAAkB9vB,IAG1BhU,EAAInG,GAAG8H,OAAO,0DAA2DqS,EAAI8F,EAAQ9F,KAErF0S,EAAc1S,EAAIgwB,EAAc7vB,MAEhClD,EAAM3H,IAAM06B,EAAc16B,IAC1B2H,EAAM/B,SAAW80B,EAAc90B,SAC/B+B,EAAM+T,OAASgf,EAAchf,OAC7B/T,EAAMqV,iBAAmB0d,EAAc1d,iBACvCrV,EAAMyoB,kBAAmB,EAEzBvQ,EAAQgS,0BAA0BnnB,OAOlDmoB,0BAA2B,SAASnoB,GAChC,GACIyvB,GAAgBO,EADhB/yB,EAAQkY,EAAQ4P,cAAc/kB,EAIlC,IAAIutB,GAAiBpY,EAAQnM,YAAYhJ,GAAK,CAC1C,GAAIsS,GAAmBU,EAAoBhT,EAE3CyvB,GAAiBta,EAAQ4V,mBAAmB/qB,GAE5CgwB,GACIpoC,KAAMke,EAAQ9F,GACdoB,KAAMoH,EAAQxI,GACdG,KAAM4I,EAAQ/I,GACd1K,IAAK2H,EAAM3H,IACX4F,SAAU+B,EAAM/B,SAChB8V,OAAQ/T,EAAM+T,OACdif,YAAa1L,KAAKkG,OAGlBnY,IACA0d,EAAc1d,iBAAmBA,EAGrC,KACI3Y,aAAaC,QAAQ61B,EAAgBr4B,KAAKmrB,UAAUyN,IAExD,MAAOhgC,GACHhE,EAAInG,GAAG8H,OAAO,0DAA2DqS,EAAIhQ,EAAMxD,YAAa,WAK5G0jC,yBAA0B,SAASlwB,EAAIwlB,EAAUhH,GAC7C,GAAIpN,GAAM+D,EAAQ8Y,QAAQjuB,EAAIwlB,GAC1B59B,EAAOke,EAAQ9F,GACfmwB,GACI5G,OAAQ,SAASvY,EAAQC,GACrB,GAAIie,GAAW1mB,EAAQxI,EAEnBgR,KAAWC,EACXF,EAAW/Q,EAAIpY,EAAMsnC,EAAUA,GAG/Bne,EAAW/Q,EAAIpY,EAAOopB,GAAUke,EAAWA,EAAW,EAAIle,EAASke,IAI3E3J,QAAS,SAASvU,EAAQC,GACtB,GAAI0U,GAAgBxQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK0vB,cAC/CyK,EAAiCjb,EAAQ4P,cAAc/kB,GAAIgR,OAC3Dqf,EAAmBrf,EACnBsf,EAAkBrf,EAClBwN,EAAgBjW,EAAQxI,GACxBuwB,EAAuBF,GAAoBC,EAAkB9R,GAC7DgS,EAAqBJ,CAEzBzK,GAAcH,GAAY+K,EAE1B1qC,GAAG+C,KAAK+8B,EAAe,SAASH,EAAUiL,GACtCD,GAAsBC,IAG1B1f,EAAW/Q,EAAIpY,EAAM4oC,EAAoB/R,IAIrDrN,GAAIvhB,OAAO4wB,WAAa,SAAS9rB,GAC7B,GAAIA,EAAE+tB,iBAAkB,CAGpByN,EADwB,MAAb3R,EAAoB,SAAW,WACjB7pB,EAAEqc,OAAQrc,EAAEsc,UAcjD+d,aAAc,SAAShvB,EAAI+uB,EAAa3d,EAAKsf,GACzC,GAAIC,GAAwB,MAAf5B,GAAsB,EAAKA,EACpCnB,EAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAW1C,OATA23B,GAAUC,KAAOD,EAAUC,SAC3BD,EAAUE,eAAiBF,EAAUE,mBAErCF,EAAUC,KAAK8C,GAAUvf,EAErBsf,IACA9C,EAAUE,eAAe6C,GAAUD,GAGhCtf,GAIX2Y,8BAA+B,WAC3B,GAAI6G,GAAiB50B,EAAO8iB,eAE5B3J,GAAQgZ,sBAAsB,SAAS74B,EAAKsQ,GACxC,GAAIirB,GAAiB,GAAItM,MAAK3e,EAAWqqB,YAGzCY,GAAeC,QAAQD,EAAeE,UAAYH,GAE9CC,EAAerM,WAAaD,KAAKkG,QACjCz+B,EAAI,2CAA6CsJ,GACjDqE,aAAao2B,WAAWz6B,OAWpCq1B,qBAAsB,SAAS3qB,GAC3B,GAAI/C,GAAQkY,EAAQ4P,cAAc/kB,EAGlC,IAAI/C,EAKA,MAJKA,GAAM/B,UACPia,EAAQuS,mBAAmB1nB,GAGxB/C,EAAM/B,SAASmL,YCziBtCxgB,GAAGinB,wBAA0B,SAASpP,GAClC,YAqBA,SAASszB,KACL,MAAqC,SAAjClzB,EAAQiP,OAAOC,eAEXikB,QAAS,aAtBrB,GAAIC,GACApzB,GACIiP,OAAQ,SACRG,cAAe,SACfK,iBACAN,eAAgB,EAChBI,cAAe,SAASrN,GAAK,UAC7BsN,eACAE,MACI8I,UAAU,EACV4I,iBAAiB,GAErBlzB,IAAK,SAAS4B,EAAK1B,KACnBuhB,SAAU,SAASzN,KACnB2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,KAGjDhoB,IAAG6B,OAAOoW,EAASJ,GAYnBwzB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdM,cAAe,OAAQ,UACvBrW,OAAQjP,EAAQiP,OAChBQ,cAAezP,EAAQyP,cACvBD,YAAaxP,EAAQwP,YACrBgU,eAAgB0P,IAChB/jB,eAAgBnP,EAAQmP,eACxBI,cAAe,SAASrN,GACpB,MAAOlC,GAAQuP,cAAcpF,IAAIjI,IAErChU,IAAK8R,EAAQ9R,IACb01B,OAAQ5jB,EAAQ2P,SAChB0D,WAAYrT,EAAQ6P,iBACpBH,KAAM1P,EAAQ0P,QAGlB3nB,GAAG6B,OAAOxB,MACN+zB,WAAY,SAASja,EAAIG,EAAM0Z,GAC3B,GAAInJ,GAAoBmJ,KAExB/b,GAAQ9R,IAAI,sCAAwCgU,GAE7B,WAAnBlC,EAAQiP,OACRmkB,EAAUxN,cAAc1jB,GACnB6jB,SAAS1jB,GACT4jB,WAAWrT,GACX0R,QAGL1R,EAAkB5S,EAAQoP,eAAiB/M,EAC3C+wB,EAAUxN,cAAc1jB,GACnB+jB,WAAWrT,GACX0R,YCpDrB,WAMI,QAAS+O,GAAkBC,GACvB,GAGIC,GAHAC,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTvnC,EAASsF,SAASC,cAAc,SAGpC,OAAI6hC,GAAKE,EAAK,UACVtnC,EAAOwnC,MAAQxnC,EAAO0U,OAAS,EAC/ByyB,EAAMnnC,EAAOynC,WAAW,MACxBN,EAAIO,UAAUR,GAAME,EAAK,EAAG,GAIoB,IAAzCD,EAAIQ,aAAa,EAAG,EAAG,EAAG,GAAGhnC,KAAK,IAUjD,QAASinC,GAAqBV,EAAKE,EAAIE,GACnC,GAIIH,GAAKxmC,EAAMknC,EAAOC,EAJlB9nC,EAASsF,SAASC,cAAc,UAChCwiC,EAAK,EACLC,EAAKV,EACLW,EAAKX,CAUT,KAPAtnC,EAAOwnC,MAAQ,EACfxnC,EAAO0U,OAAS4yB,EAChBH,EAAMnnC,EAAOynC,WAAW,MACxBN,EAAIO,UAAUR,EAAK,EAAG,GACtBvmC,EAAOwmC,EAAIQ,aAAa,EAAG,EAAG,EAAGL,GAAI3mC,KAG9BsnC,EAAKF,GACRF,EAAQlnC,EAAgB,GAAVsnC,EAAK,GAAS,GACd,IAAVJ,EACAG,EAAKC,EAELF,EAAKE,EAETA,EAAMD,EAAKD,GAAO,CAItB,OADAD,GAASG,EAAKX,EACI,IAAVQ,EAAe,EAAIA,EAM/B,QAASI,GAAqBhB,EAAKjgC,EAAM2M,EAASu0B,GAC9C,GAAInoC,GAASsF,SAASC,cAAc,UAChCtF,EAAO2T,EAAQ3T,MAAQ,aACvBqH,EAAU,GAAI3L,IAAG4L,OASrB,OAPA6gC,GAAoBlB,EAAKjgC,EAAMjH,EAAQ4T,EAASu0B,GAC3C11B,KAAK,WACFnL,EAAQG,QACJzH,EAAOI,UAAUH,EAAM2T,EAAQ1T,SAAW,OAI/CoH,EAGX,QAAS+gC,GAAoCtxB,GAGzC,IAAKpb,GAAGsO,MACJ,KAAM,IAAItO,IAAGwB,MAAM,kEAGvB,IAAI4Z,EAAKuxB,WAAavxB,EAAKwxB,UANX,OAOZ,OACIC,UAAWlrC,KAAKC,MAAMD,KAAKmrC,KARnB,QAQqC1xB,EAAKuxB,WAAavxB,EAAKwxB,aACpEG,SAAUprC,KAAKC,MAAMD,KAAKmrC,KATlB,QASoC1xB,EAAKwxB,UAAYxxB,EAAKuxB,eAQ9E,QAASF,GAAoBlB,EAAKjgC,EAAMjH,EAAQ4T,EAASu0B,GACrD,GAMIQ,GANAvB,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTC,EAAQ5zB,EAAQ4zB,MAChB9yB,EAASd,EAAQc,OACjByyB,EAAMnnC,EAAOynC,WAAW,MACxBngC,EAAU,GAAI3L,IAAG4L,OAKrB,OAFA4/B,GAAIyB,OAEAh1B,EAAQi1B,OACDC,GACH7hC,KAAMA,EACNjH,OAAQA,EACR+xB,MAAOmV,EACP6B,YAAazB,EACb0B,WAAY5B,EACZ6B,YAAar1B,EAAQq1B,YACrBJ,OAAQj1B,EAAQi1B,OAChBK,aAAcx0B,EACdy0B,YAAa3B,KAIhB7rC,GAAG8S,kBAAkBwD,2BACtB02B,EAAqBN,GACjBE,UAAWf,EACXc,WAAY5zB,IAGZi0B,IACAhtC,GAAGmG,IAAInG,GAAG8H,OAAO,iFACb+jC,EAAO9yB,EAAQi0B,EAAmBD,SAAUC,EAAmBH,WAC/D,QAEJhB,EAAQmB,EAAmBD,SAC3Bh0B,EAASi0B,EAAmBH,YAIpCY,EAAoBppC,EAAQwnC,EAAO9yB,EAAQd,EAAQq1B,aAI/CttC,GAAGsO,MACF,WACOg9B,EAAkBC,KAClBE,GAAM,EACNE,GAAM,EAGV,IAOI+B,GAAQC,EAAIC,EAPZC,EAAI,KACJC,EAAYnkC,SAASC,cAAc,UACnCmkC,EAAkBvB,EAAWP,EAAqBV,EAAKE,EAAIE,GAAM,EACjEqC,EAAKrsC,KAAKqoC,KAAK6D,EAAIhC,EAAQJ,GAC3BwC,EAAKtsC,KAAKqoC,KAAK6D,EAAI90B,EAAS4yB,EAAKoC,GACjC3B,EAAK,EACL8B,EAAK,CAMT,KAHAJ,EAAUjC,MAAQiC,EAAU/0B,OAAS80B,EACrCH,EAASI,EAAUhC,WAAW,MAEvBM,EAAKT,GAAI,CAGZ,IAFAgC,EAAK,EACLC,EAAK,EACED,EAAKlC,GACRiC,EAAOS,UAAU,EAAG,EAAGN,EAAGA,GAC1BH,EAAO3B,UAAUR,GAAMoC,GAAKvB,GAC5BZ,EAAIO,UAAU+B,EAAW,EAAG,EAAGD,EAAGA,EAAGD,EAAIM,EAAIF,EAAIC,GACjDN,GAAME,EACND,GAAMI,CAEV5B,IAAMyB,EACNK,GAAMD,EAEVzC,EAAI4C,UACJN,EAAYJ,EAAS,QAIzBlC,EAAIO,UAAUR,EAAK,EAAG,EAAGM,EAAO9yB,GAGpC1U,EAAOgqC,iBAAmBhqC,EAAOgqC,kBACjC1iC,EAAQG,UAEDH,GAGX,QAASwhC,GAAqCmB,GAC1C,GAAIhjC,GAAOgjC,EAAWhjC,KAClB8qB,EAAQkY,EAAWlY,MACnBgX,EAAckB,EAAWlB,YACzBC,EAAaiB,EAAWjB,WACxBC,EAAcgB,EAAWhB,YACzB3hC,EAAU,GAAI3L,IAAG4L,QACjBshC,EAASoB,EAAWpB,OACpBqB,EAAe5kC,SAASC,cAAc,UACtC4kC,EAAsBD,EAAazC,WAAW,MAC9C2C,EAAeH,EAAWjqC,OAC1BkpC,EAAee,EAAWf,aAC1BC,EAAcc,EAAWd,WAyB7B,OAvBAC,GAAoBc,EAAclB,EAAYD,EAAaE,GAE3DmB,EAAa11B,OAASw0B,EACtBkB,EAAa5C,MAAQ2B,EAErBgB,EAAoBzC,UAAU3V,EAAO,EAAG,GAExC8W,GACI5hC,KAAMA,EACNyN,OAAQw0B,EACRnX,MAAOA,EACPmY,aAAcA,EACdE,aAAcA,EACd5C,MAAO2B,IAEN12B,KACG,WACI23B,EAAaJ,iBAAmBI,EAAaJ,kBAC7C1iC,EAAQG,WAEZH,EAAQK,SAGTL,EAOX,QAAS8hC,GAAoBppC,EAAQwnC,EAAO9yB,EAAQu0B,GAChD,OAAQA,GACJ,IAAK,GACL,IAAK,GACL,IAAK,GACL,IAAK,GACDjpC,EAAOwnC,MAAQ9yB,EACf1U,EAAO0U,OAAS8yB,CAChB,MACJ,SACIxnC,EAAOwnC,MAAQA,EACfxnC,EAAO0U,OAASA,EAExB,GAAIyyB,GAAMnnC,EAAOynC,WAAW,KAC5B,QAAQwB,GACJ,IAAK,GAED9B,EAAIkD,UAAU7C,EAAO,GACrBL,EAAI/pB,OAAM,EAAI,EACd,MACJ,KAAK,GAED+pB,EAAIkD,UAAU7C,EAAO9yB,GACrByyB,EAAImD,OAAOhtC,KAAKitC,GAChB,MACJ,KAAK,GAEDpD,EAAIkD,UAAU,EAAG31B,GACjByyB,EAAI/pB,MAAM,GAAG,EACb,MACJ,KAAK,GAED+pB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAI/pB,MAAM,GAAG,EACb,MACJ,KAAK,GAED+pB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAIkD,UAAU,GAAI31B,EAClB,MACJ,KAAK,GAEDyyB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAIkD,UAAU7C,GAAQ9yB,GACtByyB,EAAI/pB,OAAM,EAAI,EACd,MACJ,KAAK,GAED+pB,EAAImD,QAAO,GAAOhtC,KAAKitC,IACvBpD,EAAIkD,WAAW7C,EAAO,IAUlC,QAASgD,GAAaC,EAAUC,GAC5B,GAAI52B,GAAO9X,IAEP6E,QAAOO,MAAQqpC,YAAoBrpC,OAClC,WACG,GAAI8lC,GAAM,GAAIyD,OACVC,EAAM/pC,OAAO+pC,KAAO/pC,OAAO+pC,IAAIC,gBAAkBhqC,OAAO+pC,IACpD/pC,OAAOiqC,WAAajqC,OAAOiqC,UAAUD,gBAAkBhqC,OAAOiqC,UAAY,IAClF,KAAKF,EAAO,KAAMztC,OAAM,uDACxB+pC,GAAI6D,IAAMH,EAAIC,gBAAgBJ,GAC9B32B,EAAK7M,KAAOwjC,EACZA,EAAWvD,KAGduD,EAASpD,cAAiBoD,EAASlD,gBACpCkD,EAASjjC,OAAS,WACd,GAAIwjC,GAAYl3B,EAAKm3B,kBACjBD,KACAl3B,EAAKm3B,mBAAqB,KAG1B3lB,WAAW,WACP,IAAK,GAAIjZ,GAAI,EAAG3D,EAAMsiC,EAAUtpC,OAAQ2K,EAAI3D,EAAK2D,IAC7C2+B,EAAU3+B,MAEf,KAGXo+B,EAAS/iC,QAAUgjC,EACnB1uC,KAAKivC,uBAETjvC,KAAKyuC,SAAWA,EAMpBD,EAAanoC,UAAU6oC,OAAS,SAASjjC,EAAQ2L,GAC7CA,EAAUA,KAEV,IASIu3B,GATAr3B,EAAO9X,KACPovC,EAAWpvC,KAAKyuC,SAASpD,aACzBgE,EAAYrvC,KAAKyuC,SAASlD,cAC1BC,EAAQ5zB,EAAQ4zB,MAChB9yB,EAASd,EAAQc,OACjBue,EAAWrf,EAAQqf,SACnBD,EAAYpf,EAAQof,UACpBmV,GAAYnsC,KAAKiL,MAA2B,eAAnBjL,KAAKiL,KAAK/K,KACnC+I,EAAUgD,EAAOhD,QAAQF,aAG7B,IAAI/I,KAAKivC,mBAEL,WADAjvC,MAAKivC,mBAAmBpsC,KAAK,WAAaiV,EAAKo3B,OAAOjjC,EAAQ2L,IAI9D4zB,KAAU9yB,EACVA,EAAU22B,EAAY7D,EAAQ4D,GAAa,EACpC12B,IAAW8yB,EAClBA,EAAS4D,EAAW12B,EAAS22B,GAAc,GAE3C7D,EAAQ4D,EACR12B,EAAS22B,GAETpY,GAAYuU,EAAQvU,IACpBuU,EAAQvU,EACRve,EAAU22B,EAAY7D,EAAQ4D,GAAa,GAE3CpY,GAAate,EAASse,IACtBte,EAASse,EACTwU,EAAS4D,EAAW12B,EAAS22B,GAAc,GAG/CF,GAAQ3D,MAAOA,EAAO9yB,OAAQA,GAC9B/Y,GAAG+C,KAAKkV,EAAS,SAAS03B,EAAYC,GAClCJ,EAAIG,GAAcC,IAGN,QAAZtmC,EACC,WACG,GAAIumC,GAAevjC,EAAO8iC,GAC1B7C,GAAqBp0B,EAAK22B,SAAU32B,EAAK7M,KAAMkkC,EAAKhD,GAC/C11B,KAAK,SAASpS,GACX4H,EAAO8iC,IAAM1qC,EACbmrC,IAAiBvjC,EAAO8iC,KAAO9iC,EAAOT,cAG/B,WAAZvC,GACPmjC,EAAoBpsC,KAAKyuC,SAAUzuC,KAAKiL,KAAMgB,EAAQkjC,EAAKhD,GAElC,kBAAlBnsC,MAAKyvC,UACZzvC,KAAKyvC,SAASxjC,IAItBtM,GAAG6uC,aAAeA,KCtYtB7uC,GAAG+5B,eAAiB,SAAS5zB,GACzB,YAEA,SAAS4pC,GAAMC,GACX,MAAoC,QAA7BA,EAAG1mC,QAAQF,cAGtB,QAAS6mC,GAASD,GACd,MAAoC,WAA7BA,EAAG1mC,QAAQF,cAGtB,QAAS8mC,KACL,MAAmC/rC,WAA5B,GAAI6qC,QAAQmB,YAGvB,QAASC,KACL,GAAI/rC,GAASsF,SAASC,cAAc,SAEpC,OAAOvF,GAAOynC,YAAcznC,EAAOynC,WAAW,MAMlD,QAASuE,GAAwBC,GAE7B,GAAIC,GAAeD,EAAa5qC,MAAM,KAClC3D,EAAOwuC,EAAaA,EAAaxqC,OAAS,GAAGL,MAAM,KAAK,GACxDmqB,EAAY7vB,GAAG0R,aAAa3P,EAIhC,QAFA8tB,EAAYA,GAAaA,EAAUzmB,eAG/B,IAAK,OACL,IAAK,MACD,MAAO,YACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,OACL,IAAK,MACD,MAAO,cASnB,QAASonC,GAAc7U,GACnB,GACI8U,GAAgBC,EAAgBC,EADhCC,EAAejnC,SAASC,cAAc,IAS1C,OANAgnC,GAAaC,KAAOlV,EAEpB8U,EAAiBG,EAAaE,SAC9BH,EAAaC,EAAaG,KAC1BL,EAAiBE,EAAaI,SAE1BP,EAAernC,gBAAkBlE,OAAO+rC,SAASH,SAAS1nC,gBAI1DsnC,EAAetnC,gBAAkBlE,OAAO+rC,SAASD,SAAS5nC,eAK1DunC,IAAezrC,OAAO+rC,SAASF,OAAS/wC,GAAGqN,MAOnD,QAAS6jC,GAAyB3F,EAAK5/B,GACnC4/B,EAAI1/B,OAAS,WACT0/B,EAAI1/B,OAAS,KACb0/B,EAAIx/B,QAAU,KACdJ,EAAQG,QAAQy/B,IAGpBA,EAAIx/B,QAAU,WACVw/B,EAAI1/B,OAAS,KACb0/B,EAAIx/B,QAAU,KACd5F,EAAI,6BAA8B,SAClCwF,EAAQK,QAAQu/B,EAAK,+BAI7B,QAAS4F,GAAgC9sC,EAAQsH,GAO7CtH,EAAOgqC,gBAAkB,WACrB1iC,EAAQG,QAAQzH,IAQxB,QAAS+sC,GAAkCnwB,EAAatV,GACpD,GAAI0lC,GAAatB,EAAM9uB,IAAgBgvB,EAAShvB,EAahD,OAXI8uB,GAAM9uB,GACNiwB,EAAyBjwB,EAAatV,GAEjCskC,EAAShvB,GACdkwB,EAAgClwB,EAAatV,IAG7CA,EAAQK,QAAQiV,GAChB9a,EAAInG,GAAG8H,OAAO,iDAAkDmZ,EAAY3X,SAAU,UAGnF+nC,EAKX,QAASC,GAAKzmC,EAAY8W,EAAW1J,GACjC,GAAIs5B,GAAc,GAAIvxC,IAAG4L,QACrB6c,EAAa,GAAIzoB,IAAGwxC,SAAS3mC,EAAY1E,GACzC+a,EAAUjJ,EAAQiJ,QAElBuY,EAA2B,MAAlBxhB,EAAQwhB,QAAwBxhB,EAAQwhB,OACjDgY,EAAsB,WAClB9vB,EAAU5V,QAAU,KACpB4V,EAAU9V,OAAS,KACnB1F,EAAI,mDAAoD,SACxDorC,EAAYvlC,QAAQ2V,EAAW,gCAiDvC,OA9CA8G,GAAWipB,gBAAgB56B,KACvB,SAASxS,GAGL,GAAIqtC,IACIngC,MAAO,WACH,OAAO,GAAIxR,IAAG4L,SAAUE,YAGhC8lC,EAAOnY,EAAS,GAAIz5B,IAAG6xC,KAAKhnC,EAAY1E,GAAOwrC,EAC/CG,EAAQ,GAAI9xC,IAAG6uC,aAAahkC,EAAY4mC,EAExCL,GAAkCzvB,EAAW4vB,IAC7CK,EAAKpgC,QAAQsF,KACT,SAAS86B,GACL,GAAItE,GAAcsE,GAAQA,EAAKG,WAE/BD,GAAMvC,OAAO5tB,GACT2V,SAAUpW,EACVmW,UAAWnW,EACXosB,YAAaA,EACbhpC,KAAMA,EACN4oC,OAAQj1B,EAAQmJ,wBAIxB,SAAS4wB,GACL7rC,EAAInG,GAAG8H,OAAO,iEAAkEkqC,IAEhFF,EAAMvC,OAAO5tB,GACT2V,SAAUpW,EACVmW,UAAWnW,EACX5c,KAAMA,EACN4oC,OAAQj1B,EAAQmJ,0BAOpC,WACIjb,EAAI,mBACJorC,EAAYvlC,QAAQ2V,EAAW,qBAIhC4vB,EAGX,QAASU,GAAyBtW,EAAKuW,EAAaZ,EAAMpwB,EAASE,GAC/D,GAAI+wB,GAAU,GAAInD,OACdoD,EAAgB,GAAIpyC,IAAG4L,OAE3BwlC,GAAkCe,EAASC,GAEvC5B,EAAc7U,KACdwW,EAAQhC,YAAc,aAG1BgC,EAAQ/C,IAAMzT,EAEdyW,EAAct7B,KACV,WACIs6B,EAAkCc,EAAaZ,GAEnC,GAAItxC,IAAG6uC,aAAasD,GAC1B5C,OAAO2C,GACT5a,SAAUpW,EACVmW,UAAWnW,EACX5c,KAAM+rC,EAAwB1U,GAC9BuR,OAAQ9rB,KAIhBkwB,EAAKtlC,SAIb,QAASqmC,GAA+B1W,EAAK4P,EAAK+F,EAAMpwB,GACpDkwB,EAAkC7F,EAAK+F,GAKvCtxC,GAAGurC,GAAKjqC,KACJg2B,SAAUpW,EAAU,KACpBmW,UAAWnW,EAAU,OAGzBqqB,EAAI6D,IAAMzT,EAWd,QAAS2W,GAAY3W,EAAKha,EAAW1J,GACjC,GAAIq5B,GAAO,GAAItxC,IAAG4L,QACd6V,EAAQxJ,EAAQwJ,MAChBP,EAAUO,EAAQxJ,EAAQiJ,QAAU,IA8BxC,OA3BIO,IAASsuB,EAAMpuB,GAGXyuB,IAIII,EAAc7U,KAASuU,IACvBmC,EAA+B1W,EAAKha,EAAW2vB,EAAMpwB,GAGrD+wB,EAAyBtW,EAAKha,EAAW2vB,EAAMpwB,GAInDmxB,EAA+B1W,EAAKha,EAAW2vB,EAAMpwB,GAIpD+uB,EAAStuB,GACdswB,EAAyBtW,EAAKha,EAAW2vB,EAAMpwB,GAG1CkwB,EAAkCzvB,EAAW2vB,KAClD3vB,EAAUytB,IAAMzT,GAGb2V,EAGXtxC,GAAG6B,OAAOxB,MAWNuhB,SAAU,SAAS2wB,EAAe5wB,EAAW1J,GACzC,MAAIjY,IAAGwH,SAAS+qC,IACZpsC,EAAI,4DACGmsC,EAAYC,EAAe5wB,EAAW1J,SAG7C9R,EAAI,iDACGmrC,EAAKiB,EAAe5wB,EAAW1J,WAMlD5X,KAAKmyC,YACLnyC,KAAKmyC,SAASzC,MAAQA,EACtB1vC,KAAKmyC,SAASvC,SAAWA,EACzB5vC,KAAKmyC,SAAShC,cAAgBA,EAC9BnwC,KAAKmyC,SAASnC,wBAA0BA,GChT5CrwC,GAAG6xC,KAAO,SAAShnC,EAAY1E,GAC3B,YAYA,SAASssC,GAAkBC,GAIvB,IAHA,GAAI/vC,GAAS,EACTgwC,EAAM,EAEHD,EAAI3sC,OAAS,GAChBpD,GAAU2gC,SAASoP,EAAIpqC,UAAU,EAAG,GAAI,IAAM3G,KAAKgxC,IAAI,EAAGA,GAC1DD,EAAMA,EAAIpqC,UAAU,EAAGoqC,EAAI3sC,QAC3B4sC,GAAO,CAGX,OAAOhwC,GAKX,QAASiwC,GAAWC,EAAQlnC,GACxB,GAAImnC,GAAYD,EACZE,EAAapnC,CAwBjB,OAvBkBxH,UAAd2uC,IACAA,EAAY,EACZC,EAAa,GAAI/yC,IAAG4L,SAGxB5L,GAAGqL,cAAcR,EAAYioC,EAAW,GAAGh8B,KAAK,SAAS47B,GACrD,GACIM,GADA3/B,EAAQ,cAAcpP,KAAKyuC,EAG3Br/B,GACiB,MAAbA,EAAM,IACN2/B,EAAgB1P,SAASoP,EAAIxqC,MAAM,EAAG,GAAI,IAC1C0qC,EAAWE,EAAYE,EAAgB,EAAGD,IAG1CA,EAAWjnC,QAAQgnC,GAIvBC,EAAW/mC,QAAQ,iCAIpB+mC,EAIX,QAASE,KACL,GAAItnC,GAAU,GAAI3L,IAAG4L,OAgBrB,OAdA5L,IAAGqL,cAAcR,EAAY,EAAG,GAAGiM,KAAK,SAAS47B,GACjB,IAAxBA,EAAI/sC,QAAQ,QACZgG,EAAQK,QAAQ,qBAGhB4mC,IAAa97B,KAAK,SAAS+7B,GACvBlnC,EAAQG,QAAQ+mC,IAEpB,SAAS1oC,GACLwB,EAAQK,QAAQ7B,OAKrBwB,EAIX,QAASunC,GAAeC,GACpB,GAAIxnC,GAAU,GAAI3L,IAAG4L,OAMrB,OAJA5L,IAAGqL,cAAcR,EAAYsoC,EAAY,GAAI,GAAGr8B,KAAK,SAAS47B,GAC1D/mC,EAAQG,QAAgB,SAAR4mC,KAGb/mC,EAIX,QAASynC,GAAiBD,EAAWE,GACjC,GAAI1nC,GAAU,GAAI3L,IAAG4L,OAWrB,OATA5L,IAAGqL,cAAcR,EAAYsoC,EAAY,GAAI,GAAGr8B,KAAK,SAAS47B,GAC1D,GAAIW,EACA,MAAO1nC,GAAQG,QAAQ2mC,EAAkBC,GAGzC/mC,GAAQG,QAAQw3B,SAASoP,EAAK,OAI/B/mC,EAIX,QAAS2nC,GAAOH,EAAWI,GACvB,GAAIV,GAASM,EAAY,GACrBjoC,EAAqB,GAAbqoC,CAEZ,OAAOvzC,IAAGqL,cAAcR,EAAYgoC,EAAQ3nC,GAIhD,QAASsoC,GAAcC,GAInB,IAHA,GAAIv5B,MACA24B,EAAS,EAENA,EAAS,IAAMY,EAAO1tC,QACzBmU,EAAQhX,KAAKuwC,EAAOvrC,MAAM2qC,EAAQA,EAAS,KAC3CA,GAAU,EAGd,OAAO34B,GAIX,QAASw5B,GAAaL,EAAcE,GAChC,GACII,GAAa3zC,GAAG6B,UAAW+xC,GAC3BC,IAsBJ,OApBA7zC,IAAG+C,KAAKwwC,EAAY,SAASvwC,EAAKm3B,GAC9B,GAGI2Z,GAAWxqC,EAASyqC,EAHpBC,EAAQ7Z,EAAMjyB,MAAM,EAAG,GACvBiS,EAAKk5B,EAAeZ,EAAkBuB,GAAS1Q,SAAS0Q,EAAO,IAC/DC,EAAgBN,EAAWhuC,QAAQwU,EAYvC,IATI85B,GAAiB,IACjB3qC,EAAU4qC,EAAS/5B,GAAIpY,KACvBgyC,EAAeG,EAAS/5B,GAAIjP,MAC5B4oC,EAAY3Z,EAAMjyB,MAbL,GAAA,GAa4D,EAAf6rC,GAC1DF,EAAKvqC,GAAW+pC,EAAeZ,EAAkBqB,GAAaxQ,SAASwQ,EAAW,IAElFH,EAAWt3B,OAAO43B,EAAe,IAGX,IAAtBN,EAAW5tC,OACX,OAAO,IAIR8tC,EApJX,GAAID,IAAW,KACXM,GACIC,KACIpyC,KAAM,cACNmJ,MAAO,GAmJnBlL,IAAG6B,OAAOxB,MAONmR,MAAO,WACH,GAAI4iC,GAAS,GAAIp0C,IAAG4L,QAChByoC,EAAiB,SAASjuC,GACtBD,EAAInG,GAAG8H,OAAO,kCAAmC1B,IACjDguC,EAAOpoC,QAAQ5F,GA0BvB,OAvBA6sC,KAAgBn8B,KAAK,SAASw9B,GAC1BnuC,EAAInG,GAAG8H,OAAO,mDAAwE3D,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,OAEtHmxC,EAAeoB,GAAYx9B,KAAK,SAASu8B,GAErCltC,EAAInG,GAAG8H,OAAO,+BAAgCurC,EAAe,SAAW,QAExED,EAAiBkB,EAAYjB,GAAcv8B,KAAK,SAASy9B,GAErDpuC,EAAInG,GAAG8H,OAAO,kCAAmCysC,IAEjDjB,EAAOgB,EAAYC,GAAez9B,KAAK,SAAS28B,GAC5C,GAAIF,GAAaC,EAAcC,GAC3Be,EAAYd,EAAaL,EAAcE,EAE3CptC,GAAI,sCAEJiuC,EAAOtoC,QAAQ0oC,IAChBH,IACJA,IACJA,IACJA,GAEID,KAKf/zC,KAAKmyC,YACLnyC,KAAKmyC,SAASC,kBAAoBA,GC7MtCzyC,GAAGwxC,SAAW,SAAS3mC,EAAY1E,GAC/B,YAEA,SAASsuC,GAAeC,EAAYC,GAChC,GAAIC,IAAe,EACfC,KAAuB7kC,OAAO0kC,EASlC,OAPA10C,IAAG+C,KAAK8xC,EAAmB,SAAS7xC,EAAK8xC,GACrC,GAAwD,IAApDH,EAAkBhvC,QAAQmvC,GAE1B,MADAF,IAAe,GACR,IAIRA,EAGX50C,GAAG6B,OAAOxB,MASNqxC,cAAe,WACX,GAAIv5B,GAAO9X,KACPooB,EAAa,GAAIzoB,IAAG4L,QACpBmpC,GAAc,EACdhzC,EAA2BoC,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,IAsC/D,OApCAoE,GAAInG,GAAG8H,OAAO,gEAAiE/F,IAE/EoE,EAAI,oDAEA9F,KAAK20C,qBACL7uC,EAAI,sDAEJnG,GAAGqL,cAAcR,EAAY,EAAG,GAAGiM,KAAK,SAAS47B,GAC7C1yC,GAAG+C,KAAKoV,EAAK88B,uBAAwB,SAAS3wC,EAAM4G,GAChD,GAAIupC,EAAevpC,EAAOwnC,GAQtB,OALa,eAATpuC,GAAyBtE,GAAG8S,kBAAkBuD,gBAC9C0+B,GAAc,EACdtsB,EAAW3c,QAAQxH,KAGhB,IAIf6B,EAAInG,GAAG8H,OAAO,iDAAkD/F,EAAMgzC,EAAc,GAAK,QAEpFA,GACDtsB,EAAWzc,WAGnB,WACI7F,EAAI,+BAAiCpE,EAAO,gDAC5C0mB,EAAWzc,aAIfyc,EAAWzc,UAGRyc,GAWXusB,kBAAmB,WACf,GAAIE,GAAWrqC,EAAWtK,KAEtB40C,EAAoBn1C,GAAG2F,QAAQc,OAAOu6B,KAAK3gC,KAAK40C,wBAAyBC,IAAa,EACtFH,GAAc,EACdhzC,EAA2BoC,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,IAa/D,OAXIozC,KAEIJ,EADa,eAAbG,GACcl1C,GAAG8S,kBAAkBuD,eAO1C0+B,GAAe5uC,EAAIpE,EAAO,gEAEpBgzC,MAKnB/0C,GAAGwxC,SAAS9qC,UAAUuuC,wBAClBG,aAAc,SACdC,YAAa,SACbC,YAAa,SACbC,YAAa,OACbC,cAAe,WAAY,aCpG/Bx1C,GAAGk2B,gBAAkB,SAAS5qB,EAAMnF,GAChC,YAMA,SAASsvC,GAAiBC,GACtB,GAAIC,IAAa,CASjB,OAPA31C,IAAG+C,KAAK2yC,EAAQ,SAASE,EAAO7uC,GAC5B,GAAIA,EAAQ,EAER,MADA4uC,IAAa,GACN,IAIRA,EAQX,QAASE,KACL,GAAIC,GAAoB,GAAI91C,IAAG4L,OA6B/B,OA3BA,IAAI5L,IAAGwxC,SAASlmC,EAAMnF,GAAKurC,gBAAgB56B,KAAK,WAC5C,GAAIsf,GAAQ,GAAI4Y,OACZrT,EAAMz2B,OAAO+pC,KAAO/pC,OAAO+pC,IAAIC,gBAAkBhqC,OAAO+pC,IAClD/pC,OAAOiqC,WAAajqC,OAAOiqC,UAAUD,gBAAkBhqC,OAAOiqC,UAC9D,IAENxT,IACAvF,EAAMrqB,QAAU,WACZ5F,EAAI,4DAA6D,SACjE2vC,EAAkB9pC,WAGtBoqB,EAAMvqB,OAAS,WACXiqC,EAAkBhqC,SACd+/B,MAAOxrC,KAAKwrC,MACZ9yB,OAAQ1Y,KAAK0Y,UAIrBqd,EAAMgZ,IAAMzT,EAAIuT,gBAAgB5jC,KAGhCnF,EAAI,+DAAgE,SACpE2vC,EAAkB9pC,YAEvB8pC,EAAkB9pC,SAEd8pC,EASX,QAASC,GAAgBL,EAAQM,GAC7B,GAAIC,EA0BJ,OAxBAj2C,IAAG+C,KAAK2yC,EAAQ,SAASQ,EAAWC,GAChC,GAAIA,EAAa,EAAG,CAChB,GAAIC,GAAe,0BAA0BnyC,KAAKiyC,GAC9CG,EAAoBD,EAAa,GAAGzmC,OAAO,GAAGvG,cAAgBgtC,EAAa,GAAGluC,MAAM,GACpFouC,EAAcN,EAAWK,EAG7B,QAAQD,EAAa,IACjB,IAAK,MACD,GAAIE,EAAcH,EAEd,MADAF,GAAeC,GACR,CAEX,MACJ,KAAK,MACD,GAAII,EAAcH,EAEd,MADAF,GAAeC,GACR,MAOpBD,EAWX51C,KAAK81B,SAAW,SAASuf,GACrB,GAAIa,GAAmB,GAAIv2C,IAAG4L,OAoB9B,OAlBAzF,GAAI,iCAEAsvC,EAAiBC,GACjBG,IAAiB/+B,KAAK,SAASk/B,GAC3B,GAAIC,GAAeF,EAAgBL,EAAQM,EAEvCC,GACAM,EAAiBvqC,QAAQiqC,GAGzBM,EAAiBzqC,WAEtByqC,EAAiBzqC,SAGpByqC,EAAiBzqC,UAGdyqC,IC7Hfv2C,GAAGo1B,QAAU,SAASha,GAClB,YAaA,SAASo7B,GAAoBrkB,GACzB,GAAInyB,GAAG8G,QAAQqrB,GACX,OAAO,CAGXla,GAAQ9R,IAAI,oCAAqC,SAGrD,QAASswC,GAAgBC,EAAW5qC,EAASic,EAAUpc,GACnD,GAAIgrC,IAAmB,CAEvB7qC,GAAUA,GAAW0qC,EAAoBE,GAErC5qC,GACA9L,GAAG+C,KAAK2zC,EAAW,SAAS1zC,EAAKg8B,GAE7B,GAAqB,MAAjBA,EAAS1kB,KACTq8B,GAAmB,EACnB1+B,EAAQ9R,IAAInG,GAAG8H,OAAO,oEAAqE9E,GAAM,aAEhG,IAAqB,MAAjBg8B,EAASj9B,KACd40C,GAAmB,EACnB1+B,EAAQ9R,IAAInG,GAAG8H,OAAO,oEAAqE9E,GAAM,aAGjG,KAEI,MADAiV,GAAQqd,cAAc0J,IACf,EAEX,MAAO4X,GACHD,GAAmB,EACnB1+B,EAAQ9R,IAAIywC,EAAIxwC,QAAS,SAIjC,OAAO,IAIfuF,EAAQG,IAAY6qC,EAAmB,UAAY,WAAWD,EAAW3uB,GAlD7E,GAAI9P,IACAkG,SAAU,KACVD,UACAsJ,iBACAG,QACA2N,cAAe,SAASjP,KACxBlgB,IAAK,SAASC,EAASC,KAG3BrG,IAAG6B,OAAOoW,EAASmD,GAAM,GA8CzB/a,KAAKk1B,QAAU,WAEX,GAAIshB,GAAgB,GAAI72C,IAAG4L,QACvBkrC,EAA0B,SAAS3kB,EAAUrmB,EAASic,GAClD0uB,EAAgBtkB,EAAUrmB,EAASic,EAAU8uB,IAEjDE,EAAmB/2C,GAAG6B,UAAWoW,EAOrC,OANgB,IAAIjY,IAAGg3C,qBACfh3C,GAAG6B,OAAOk1C,GAAmBzrB,WAAYwrB,KAGvCG,cAEHJ,ICrEf72C,GAAGg3C,qBAAuB,SAAS57B,GAC/B,YAiBA,SAASkQ,GAAWnR,EAAI4N,EAAUC,GAC9B,GAAImK,GAAW,IAGf,IAA6B,MAAzBpK,EAASmvB,aACT,IACI/kB,EAAWnyB,GAAGqR,UAAU0W,EAASmvB,cAErC,MAAON,GACH3+B,EAAQ9R,IAAI,qCAAuCywC,EAAIxwC,QAAS,SAChE4hB,GAAU,EAIlB/P,EAAQqT,WAAW6G,GAAWnK,EAASD,GA7B3C,GAAIsjB,GACApzB,GACIkG,SAAU,KACVqJ,iBACAtJ,UACAyJ,MACI8I,UAAU,EACV4I,iBAAiB,GAErB/N,WAAY,SAAS6G,EAAUrmB,EAASic,KACxC5hB,IAAK,SAAS4B,EAAK1B,KAG3BrG,IAAG6B,OAAOoW,EAASmD,GAmBnBiwB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdM,cAAe,OACfrW,OAAQ,MACRQ,eACItF,IAAK,WACD,MAAOnK,GAAQkG,WAGvBqJ,cAAevP,EAAQuP,cACvBrhB,IAAK8R,EAAQ9R,IACbmlB,WAAYA,EACZ3D,KAAM1P,EAAQ0P,QAGlB3nB,GAAG6B,OAAOxB,MACN42C,YAAa,WACT,GAAI/4B,GAASle,GAAG6B,UAAWoW,EAAQiG,OAEnCjG,GAAQ9R,IAAI,0BAEZklC,EAAUxN,cAAc,kBACnBK,WAAWhgB,GACXsgB,kBACAjC,WCzDjBv8B,GAAG0kB,OAAS,SAAStJ,EAAMjV,GACvB,YAEA,IACIib,GAAuBhG,EAAKme,cAC5B4d,EAAkB/7B,EAAKoe,aACvBC,EAASre,EAAKqe,OACdC,EAActe,EAAKse,YACnBC,EAAiBve,EAAKue,eAAiB,IACvCyd,EAAoBh8B,EAAKwe,YACzBC,EAAcze,EAAKye,YACnBC,EAAQz5B,KAAKg3C,gBAAgBj8B,EAAK0e,MAGtC95B,IAAG6B,OAAOxB,MAGNmgB,QAASxgB,GAAG8S,kBAAkBsD,SAAW0jB,EAAM/zB,OAAS,EAExDuxC,eAAgB,SAASC,EAAkBC,EAAkBC,GACzD,GAAIt/B,GAAO9X,KACPq3C,KACAC,EAAeF,EAAuBnsC,KAAOmsC,EAAuBnsC,KAAOmsC,CAkD/E,OAjDiB,IAAIz3C,IAAGwxC,SAASmG,EAAcxxC,GAGhC6uC,qBAEXh1C,GAAG+C,KAAK+2B,EAAO,SAAS92B,EAAK40C,GACzB,GAAIC,GAAa1/B,EAAK2/B,sBAClBpe,YAAaA,EACbqe,cAAeH,EAAWr3C,KAC1By3C,QAASL,EAAap3C,MAG1Bm3C,GAAQx0C,MACJoX,KAAMta,GAAGiN,cACTlL,KAAMoW,EAAK8/B,SAAST,GAChBz1C,KAAM61C,EAAW71C,KACjBxB,KAAMs3C,EACNG,QAASL,EAAap3C,OAE1B+K,KAAM,GAAItL,IAAGwX,UAAUmgC,EACvB33C,GAAG4P,KAAKuI,EAAK+/B,qBAAsB//B,GAC/BiJ,qBAAsBA,EACtBF,QAAS02B,EAAW12B,QACpBuY,OAAQA,EACRl5B,KAAMs3C,EACNtzC,QAASo1B,EACTwe,WAAYf,EACZvd,YAAaA,EACb1zB,IAAKA,SAKjBuxC,EAAQx0C,MACJoX,KAAMi9B,EACNx1C,KAAMy1C,EACNj8B,KAAMo8B,EAAap8B,KACnBjQ,KAAM6rC,EAAkBQ,EAAe,QAI3CD,EAAQx0C,MACJoX,KAAMi9B,EACNx1C,KAAMy1C,EACNj8B,KAAMo8B,EAAap8B,KACnBjQ,KAAMqsC,IAIPD,GAGXzd,cAAe,SAASze,EAAMzZ,EAAMuY,EAAMiB,EAAMoU,EAAUlU,EAAS4L,EAAe+wB,GAC9E,GAAIjgC,GAAO9X,KAEPg4C,GADW78B,EAAKmL,YAAenL,EAAKlQ,MAAQkQ,EAAKlQ,KAAKqb,eAEtD2xB,EAAa,KACb7oB,EAAmB2oB,EAAI3oB,iBACvB1P,EAAaq4B,EAAIr4B,WACjB0H,EAAc2wB,EAAI3wB,YAClB/L,EAAe1b,GAAGiN,aAEtBjN,IAAG+C,KAAKoV,EAAKm/B,eAAeh9B,EAAMvY,EAAMyZ,GAAO,SAASxY,EAAKgZ,GACzD,GACI7B,GADAo+B,EAAWv8B,EAAOT,IAGlBS,GAAO1Q,eAAgBtL,IAAGwX,YAC1B+gC,GAAW,GAGfp+B,EAAK4F,EAAW5E,SACZb,KAAM0B,EAAO1B,KACbvY,KAAMia,EAAOja,KACbwZ,KAAMg9B,EACN98B,QAASA,EACTC,aAAcA,IAGdM,EAAO1Q,eAAgBtL,IAAGwX,UAC1B6gC,EAAUn1C,KAAKiX,GAGfm+B,EAAan+B,EAGb6B,EAAO1Q,MACPmkB,EAAiBtV,EAAI6B,EAAO1Q,MAC5BqkB,EAASzsB,MAAMiX,GAAIA,EAAIqB,KAAMQ,EAAO1Q,QAGpCyU,EAAW9D,UAAU9B,EAAIna,GAAGya,OAAO0C,YAOxB,OAAfm7B,IACAt4C,GAAG+C,KAAKs1C,EAAW,SAASr1C,EAAKw1C,GAC7B,GAAIt6B,IACAu6B,aAAc14B,EAAWlE,UAAU1B,GAAIm+B,IAAah+B,KACpDo+B,aAAc34B,EAAWlE,UAAU1B,GAAIm+B,IAAa/8B,KAKxD2C,GAAOmJ,GAAiBtH,EAAWlE,UAAU1B,GAAIq+B,IAAWl+B,KAE5DyF,EAAWlD,YAAY27B,EAAUF,GACjC7wB,EAAY8B,YAAYivB,EAAUt6B,KAKlCm6B,EAAUtyC,QACT,WACG,GAAI4yC,KACJA,GAAMtxB,GAAiBtH,EAAWlE,UAAU1B,GAAIm+B,IAAah+B,KAC7DmN,EAAY8B,YAAY+uB,EAAYK,WAQ5D34C,GAAG6B,OAAO7B,GAAG0kB,OAAOhe,WAChB8d,WAAY,SAASrK,EAAIsK,EAAO2zB,GAC5B,YAEA,KAAKp4C,GAAG8S,kBAAkBsD,QACtB,KAAM,IAAIpW,IAAGwB,MAAM,4CAGvB,IAAIo3C,GAAgB,GAAI54C,IAAG4L,QACvBzF,EAAMiyC,EAAIjyC,IACVqV,EAAO48B,EAAI12B,QAAQvH,GACnB4F,EAAaq4B,EAAIr4B,WAAWlE,UAAU1B,GAAIA,IAC1CpY,EAAOge,GAAcA,EAAWhe,KAChCuY,EAAOyF,GAAcA,EAAWzF,KAChCu+B,GACItf,cAAe9U,EAAM8U,cACrBC,cAAc,EACdC,OAAQhV,EAAMgV,OACdC,YAAajV,EAAMlkB,MAAQ,KAC3Bo5B,eAAgBlV,EAAMlgB,QACtB6yC,kBAAmB,kBACnBtd,QAAS/3B,KAAM,GAAImf,QAASuD,EAAMvD,WAEtC43B,EAAS,GAAI94C,IAAG0kB,OAAOm0B,EAAgB1yC,EAuB3C,OArBKnG,IAAG0kB,QAAW1kB,GAAG8S,kBAAkBgD,eAAkB0F,EAOrDxb,GAAG4P,KAAK,WAEL,GAAIoM,GAAS88B,EAAOxB,eAAeh9B,EAAMvY,EAAMyZ,GAAM,EAEjDQ,IAAUA,EAAO1Q,eAAgBtL,IAAGwX,UACpCwE,EAAO1Q,KAAKqM,SAASb,KAAK8hC,EAAc9sC,QAAS8sC,EAAc5sC,UAG/D7F,EAAIgU,EAAK,4BAA6B,SACtCy+B,EAAc5sC,YAEnB3L,SAjBHu4C,EAAc5sC,UAEd7F,EAAI,iDAAmDgU,EAAK,uFAC6B,UAiBtFy+B,GAKXd,qBAAsB,SAAS18B,GAC3B,YAEA,IAAI28B,GAAgB38B,EAAK28B,cACrBre,EAActe,EAAKse,YACnBqf,EAAgB39B,EAAK48B,OAIzB,OAAKte,IAAgBqe,EAQhBA,GAKD/3C,GAAG2F,QAAQc,OAAOu6B,KAAKhhC,GAAGwxC,SAAS9qC,UAAUuuC,wBAAyB8C,IAAkB,EAClE,eAAlBA,EACO/3C,GAAG8S,kBAAkBuD,aAAe0hC,EAAgBre,EAGxDqe,EATAre,EARe,eAAlBqf,EACO,YAEJA,GAqBfd,SAAU,SAAS38B,EAAc09B,GAC7B,YAEA,IAAIC,GAAa39B,EAAazJ,YAAY,KACtCqnC,EAAcF,EAAwBz4C,MAAQ,YAC9Cw4C,EAAgBC,EAAwBhB,QACxCmB,EAAa,GACbC,EAAYp5C,GAAG0R,aAAa4J,GAC5B+9B,EAAgB,EAmBpB,OAjBIL,GAAwBj3C,MAAQi3C,EAAwBj3C,KAAK8F,OAAO9B,SACpEszC,EAAgB,KAAOL,EAAwBj3C,KAAO,KAGtDk3C,GAAc,GACdE,EAAa79B,EAAaxJ,OAAO,EAAGmnC,GAEhCF,IAAkBG,IAClBE,EAAYF,EAAYxzC,MAAM,KAAK,IAGvCyzC,GAAcE,EAAgB,IAAMD,GAGpCD,EAAa79B,EAAe+9B,EAGzBF,GAIX9B,gBAAiB,SAASvd,GACtB,YAIA,OAFAA,GAAQ95B,GAAG6B,UAAWi4B,GAEfA,EAAMwf,KAAK,SAASC,EAAGC,GAC1B,MAAID,GAAEr4B,QAAUs4B,EAAEt4B,QACP,EAEPq4B,EAAEr4B,QAAUs4B,EAAEt4B,SACP,EAEJ,KAIfg3B,qBAAsB,SAAS98B,EAAMq+B,GACjC,YAEA,IAAIthC,GAAO9X,KACP+gB,EAAuBhG,EAAKgG,qBAC5Bjb,EAAMiV,EAAKjV,IACX+a,EAAU9F,EAAK8F,QACfuY,EAASre,EAAKqe,OACdl5B,EAAO6a,EAAK7a,KACZgE,EAAU6W,EAAK7W,QACf4zC,EAAa/8B,EAAK+8B,WAClBte,EAAcze,EAAKye,aAAmC,eAApB4f,EAAWl5C,MAAkC,eAATA,EACtEq4C,EAAgB,GAAI54C,IAAG4L,QACvB8tC,EAAiB,GAAI15C,IAAG+5B,eAAe5zB,GACvC9B,EAASsF,SAASC,cAAc,SA8BpC,OA5BAzD,GAAI,6CAA+CszC,EAAW13C,MAE9D23C,EAAe93B,SAAS63B,EAAYp1C,GAAS6c,QAASA,EAASuY,OAAQA,EAAQrY,qBAAsBA,IAAuBtK,KAAK,WAC7H,GAAI6iC,GAAqBt1C,EAAOI,UAAUlE,EAAMgE,GAC5Cq1C,EAAgB,WACZzzC,EAAI,yCAA2CszC,EAAW13C,KAC1D,IAAIuJ,GAAOtL,GAAGwE,cAAcm1C,EAC5Bf,GAAc9sC,QAAQR,GAG1BuuB,GACA1hB,EAAK0hC,kBAAkBJ,EAAYE,EAAoBxzC,GAAK2Q,KAAK,SAASgjC,GACtEH,EAAqBG,EACrBF,KAEJ,WACIzzC,EAAI,wFAAyF,SAC7FyzC,MAIJA,KAEL,WACCzzC,EAAI,iDAAmDszC,EAAW13C,KAAM,SACxE62C,EAAc5sC,QAAQmsC,KAGnBS,GAIXiB,kBAAmB,SAASE,EAAeJ,EAAoBxzC,GAC3D,YAEA,IAAI6zC,GAAS,GAAItuC,YACbuuC,EAAkB,GAAIj6C,IAAG4L,QACzBsuC,EAAuB,EAc3B,OAZAF,GAAOnuC,OAAS,WACZquC,EAAuBF,EAAOr3C,OAC9Bs3C,EAAgBnuC,QAAQ9L,GAAGm6C,aAAa/L,QAAQ8L,EAAsBP,KAG1EK,EAAOjuC,QAAU,WACb5F,EAAI,mBAAqB4zC,EAAch4C,KAAO,2DAA4D,SAC1Gk4C,EAAgBjuC,WAGpBguC,EAAOI,cAAcL,GAEdE,GAGXI,eAAgB,SAAS31C,GACrB;YAEA,IAAIE,GAAYE,EAAYH,EAAaE,CAsBzC,OAlBID,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlC7F,KAAKi6C,YAAY31C,EAAaG,IAGzCw1C,YAAa,SAASt1C,EAAMV,GACxB,YAEA,IAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,OChZ3CtE,GAAGm6C,aAAe,WAGjB,GAAIA,KA+KD,OA7KAA,GAAaI,QAAU,oEAMvBJ,EAAaK,SAAW,SAAS9wC,GAE7B,GACI+wC,GAAMC,EACNC,EAAMC,EAAMC,EAFZC,EAAS,GACGC,EAAO,GACDC,EAAO,GACzBtqC,EAAI,CAER,GACI+pC,GAAO/wC,EAAMgH,KACbgqC,EAAOhxC,EAAMgH,KACbqqC,EAAOrxC,EAAMgH,KAEbiqC,EAAOF,GAAQ,EACfG,GAAgB,EAAPH,IAAa,EAAMC,GAAQ,EACpCG,GAAgB,GAAPH,IAAc,EAAMK,GAAQ,EACrCC,EAAc,GAAPD,EAEHE,MAAMP,GACPG,EAAOG,EAAO,GACNC,MAAMF,KACdC,EAAO,IAGVF,EAASA,EACNz6C,KAAKk6C,QAAQ5qC,OAAOgrC,GACpBt6C,KAAKk6C,QAAQ5qC,OAAOirC,GACpBv6C,KAAKk6C,QAAQ5qC,OAAOkrC,GACpBx6C,KAAKk6C,QAAQ5qC,OAAOqrC,GACvBP,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SACvBtqC,EAAIhH,EAAM3D,OAEnB,OAAO+0C,IAGXX,EAAa/L,QAAU,SAAS8M,EAAgBC,GAI5C,IAAKD,EAAe7nC,MAFO,2BAI1B,MAAO8nC,EAGR,IAAIC,GAAW/6C,KAAKg7C,SAASH,EAAe34C,QAPjB,0BAO+C,KACtE+4C,EAAWj7C,KAAKk7C,eAAeH,GAE/BhlB,EAAQ/1B,KAAKm7C,iBAAiBL,EAAmBG,EAErD,OAZ2B,0BAYGj7C,KAAKm6C,SAASpkB,IAKhD+jB,EAAaqB,iBAAmB,SAASL,EAAmBG,GAEpD,GAAIG,GAAYp7C,KAAKq7C,aAAaJ,GAC9BK,EAAgBt7C,KAAKu7C,WAAWT,EAAmBM,EAGvD,OAFc,IAAIz1C,YAAW21C,IAMrCxB,EAAauB,aAAe,SAASJ,GAG7B,IAAK,GADDO,GACKC,EAAI,EAAGA,EAAIR,EAASv1C,OAAQ+1C,IAGjC,GADAD,EAAMP,EAASQ,GACD,KAAVD,EAAI,GAAsB,KAAVA,EAAI,GAEpB,MAAOA,EAGf,WAIR1B,EAAayB,WAAa,SAAST,EAAmBM,GAE9C,GAAIM,GAAYZ,EAAkB54C,QAAQ,0BAA2B,IACjEy5C,EAAM37C,KAAKg7C,SAASU,GACpBE,EAAgBD,EAAIr2C,QAAQ,IAAI,GAChCu2C,EAAMF,EAAI9zC,MAAM,EAAG+zC,GACnBE,EAAMH,EAAI9zC,MAAM+zC,GAChBG,EAAQF,CAIb,OAFCE,GAAQA,EAAMpsC,OAAOyrC,GACrBW,EAAQA,EAAMpsC,OAAOmsC,IAM7BhC,EAAaoB,eAAiB,SAASc,GAKnC,IAHA,GAAIC,GAAO,EACPhB,OAGJ,CACI,GAA2B,KAAvBe,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAAW,KACjE,IAA2B,KAAvBD,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAElDA,GAAQ,MAGZ,CACI,GAAIv2C,GAAmC,IAA1Bs2C,EAAcC,EAAO,GAAWD,EAAcC,EAAO,GAC9DC,EAAWD,EAAOv2C,EAAS,EAC3B81C,EAAMQ,EAAcn0C,MAAMo0C,EAAMC,EACpCjB,GAASp4C,KAAK24C,GACdS,EAAOC,EAEX,GAAID,EAAOD,EAAct2C,OAAQ,MAGrC,MAAOu1C,IAKXnB,EAAakB,SAAW,SAAS3xC,GAE7B,GACI+wC,GAAMC,EACNC,EAAMC,EAAMC,EADAE,EAAO,GACDC,EAAO,GACzBtqC,EAAI,EACJsrC,IAIJ,IADiB,sBACF/3C,KAAKyF,GAChB,KAAM,IAAIlI,OAAM,uHAGpBkI,GAAQA,EAAMnH,QAAQ,sBAAuB,GAE7C,GACIo4C,GAAOt6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCkqC,EAAOv6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCmqC,EAAOx6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCsqC,EAAO36C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MAEzC+pC,EAAQE,GAAQ,EAAMC,GAAQ,EAC9BF,GAAgB,GAAPE,IAAc,EAAMC,GAAQ,EACrCE,GAAgB,EAAPF,IAAa,EAAKG,EAE3BgB,EAAI94C,KAAKu3C,GAEG,IAARI,GACDmB,EAAI94C,KAAKw3C,GAEA,IAARM,GACDgB,EAAI94C,KAAK63C,GAGZN,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SAEvBtqC,EAAIhH,EAAM3D,OAEnB,OAAOi2C,IAIJ7B,KC7KXn6C,GAAGk6B,cAAgB,SAAS7qB,EAAUsT,GAClC,YAEA,IAAI65B,MACAC,EAAc,EACdC,EAAY,EAEZC,GAAiB,EACjBC,GAAgB,EAChBC,EAAgB,SAAS1xB,EAAQC,GACzBD,IAAWwxB,GAAkBvxB,IAAUwxB,GACvCvtC,EAAS8b,EAAQC,GAGrBuxB,EAAiBxxB,EACjByxB,EAAgBxxB,GAQpB0xB,EAAmB,SAAShqB,EAAQiqB,GAChC,GAAIC,IAAO,CASX,OAPAh9C,IAAG+C,KAAK+vB,EAAQ,SAAS9vB,EAAKi6C,GAC1B,GAAIj9C,GAAG2F,QAAQo3C,EAAWE,IAAa,EAEnC,MADAD,IAAO,GACA,IAIRA,GAGXvxB,EAAW,SAAStR,GAChB+iC,EAAoB/iC,GAAI,GAAI,SACrBqiC,GAAgBriC,IAG3B4Y,EAAgB,SAASF,EAAYC,EAAQiqB,IACnB,IAAlBjqB,EAAO/sB,QAAgB+2C,EAAiBhqB,EAAQiqB,MAChDF,EAAcH,EAAWA,GACzBr8C,KAAKwZ,UAIbsjC,EAAQ,SAAShjC,GACb,GAAIoB,GAAOoH,EAAQxI,EAGfoB,GAAO,IACP2hC,EAAoB/iC,EAAI,EAAGoB,GAC3BihC,EAAgBriC,IAAOgR,OAAQ,EAAGC,MAAO7P,KAYjD2hC,EAAsB,SAAS/iC,EAAIijC,EAAWC,GAC1C,GAAIC,GAAYd,EAAgBriC,GAAMqiC,EAAgBriC,GAAIgR,OAAS,EAC/DoyB,EAAWf,EAAgBriC,GAAMqiC,EAAgBriC,GAAIiR,MAAQ,CAE7DgyB,MAAc,GAAMC,KAAa,GACjCZ,GAAea,EACfZ,GAAaa,IAGTH,IACAX,GAAeW,EAAYE,GAE3BD,IACAX,GAAaW,EAAWE,IAIhCV,EAAcJ,EAAaC,GAGnC18C,IAAG6B,OAAOxB,MAEN0yB,cAAeA,EAGfnX,eAAgB,SAASzB,EAAIgC,EAAWD,GAChCA,IAAclc,GAAGya,OAAO4C,UAAYnB,IAAclc,GAAGya,OAAO0C,SAC5DsO,EAAStR,GAEJ+B,IAAclc,GAAGya,OAAOY,YAC7B8hC,EAAMhjC,IAKdsZ,qBAAsB,SAAStZ,EAAIgR,EAAQC,GACvC8xB,EAAoB/iC,EAAIgR,EAAQC,GAChCoxB,EAAgBriC,IAAOgR,OAAQA,EAAQC,MAAOA,IAIlDsK,UAAW,SAASvb,GAChBgjC,EAAMhjC,IAGVN,MAAO,WACH2iC,KACAC,EAAc,EACdC,EAAY,MCzHxB18C,GAAGkoB,aAAe,SAASrQ,GACvB,YAYA,SAAS2lC,GAAQl2C,GACb,MAAOA,GAAK/G,MACwB,IAAhC+G,EAAK/G,KAAKoF,QAAQ,UAG1B,QAAS83C,KACLC,EAAqB19C,GAAGiY,EAAQkQ,eAAe7nB,OAAO,QAAS,SAAS40B,GACpE,GAAIyoB,GAAgBzoB,EAAMyoB,aAEtBA,IACA39C,GAAG+C,KAAK46C,EAAcrzC,MAAO,SAAStH,EAAKsE,GACvC,GAAIk2C,EAAQl2C,GAAO,CACf,GAAIgE,GAAOhE,EAAKs2C,WAChB3lC,GAAQ6O,UAAUuB,cAAc/c,QAOpD,QAASuyC,KACDH,GACAA,IAhCR,GAAIzlC,GAASylC,CAEbzlC,IACIkQ,cAAe,KACfrB,WACI3gB,IAAK,SAASC,EAASC,KACvBgiB,cAAe,SAAS/c,OA8BhCtL,GAAG6B,OAAOoW,EAASJ,GACnB4lC,IAEAz9C,GAAG6B,OAAOxB,MACNwZ,MAAO,WACHgkC,QCpCZ79C,GAAGkwB,YAAc,SAASjY,EAAS6lC,EAAa33C,GAC5C,YAgCA,SAAS43C,GAAqBC,GACtBA,EAAO95C,aAAa,YACpBiU,EAAKoY,YAAcytB,EAAO95C,aAAa,WAM/C,QAAS+5C,GAAaD,EAAQE,GAC1B,IAAIF,EAAOG,eAAkBH,EAAOG,gBAKhC,OAAO,CAJPh4C,GAAI,yDAA0D,SAC9D+3C,IAQR,QAASE,GAAoBJ,GACzB,GAAIE,GAAeF,EAAOK,MAG1Br+C,IAAGg+C,GAAQ19C,OAAO,SAAU,SAAS40B,GACjCA,EAAQA,GAAShwB,OAAOgwB,MAEpBA,EAAMrmB,eACNqmB,EAAMrmB,iBAGNqmB,EAAMnmB,aAAc,EAGxBkvC,EAAaD,EAAQE,IAAiBJ,MAK1CE,EAAOK,OAAS,WACZJ,EAAaD,EAAQE,IAAiBJ,KAM9C,QAASQ,GAAgBN,GAarB,MAZIA,KACIh+C,GAAGwH,SAASw2C,KACZA,EAASr0C,SAASs8B,eAAe+X,IAGjCA,IACA73C,EAAI,8BACJ43C,EAAqBC,GACrB1kB,GAAmB8kB,EAAoBJ,KAIxCA,EAzFX,GAAI7lC,GAAQ9X,KACRi5B,EAAkBrhB,EAAQqhB,gBAC1B0kB,EAAS/lC,EAAQhY,QACjBowB,EAAapY,EAAQoY,UAGzBrwB,IAAG6B,OAAOxB,MAINkwB,YAAa,KAIbD,cAAeD,EAGfF,gBAAgB,EAGhBC,sBAAuB,WAEnB,MAAc,OAAV4tB,EACO,KAGJ7lC,EAAKomC,UAAUP,MAkE9BA,EAASM,EAAgBN,GACzB39C,KAAK8vB,iBAAmB6tB,GAG5Bh+C,GAAG6B,OAAO7B,GAAGkwB,YAAYxpB,WAGrB63C,UAAW,SAASrtC,GAChB,YACA,IAAIf,MACAquC,EAAoB,SAASj+C,GACzB,GAAIk+C,IACA,SACA,QACA,QACA,SAGJ,OAAOz+C,IAAG2F,QAAQ84C,EAAiBl+C,EAAK6I,eAAiB,GAE7Ds1C,EAAkB,SAASn+C,GACvB,MAAOP,IAAG2F,SAAS,WAAY,SAAUpF,EAAK6I,gBAAkB,GAEpEu1C,EAAc,SAAS3O,GACnB,SAAI0O,EAAgB1O,EAAGzvC,OAAUyvC,EAAG4O,UAI7B5O,EAAG98B,UAAsC,WAA1B88B,EAAGzvC,KAAK6I,eAElCy1C,EAAc,SAASC,GACnB,GAAI/3C,GAAQ,IASZ,OAPA/G,IAAG+C,KAAK/C,GAAG8+C,GAAQ17C,WAAY,SAASJ,EAAKK,GACzC,GAAoC,WAAhCA,EAAMiG,QAAQF,eAA8B/F,EAAM07C,SAElD,MADAh4C,GAAQ1D,EAAM0D,OACP,IAIRA,EAmBf,OAhBA/G,IAAG+C,KAAKmO,EAAK8tC,SAAU,SAASh8C,EAAKgtC,GACjC,IAAKhwC,GAAG+I,QAAQinC,GAAI,IAAsC,aAA7BA,EAAG1mC,QAAQF,gBACpCo1C,EAAkBxO,EAAGzvC,OACpBo+C,EAAY3O,IAIZ,GAAiC,WAA7BA,EAAG1mC,QAAQF,gBAA+Bu1C,EAAY3O,GAAK,CAChE,GAAIjpC,GAAQ83C,EAAY7O,EAEV,QAAVjpC,IACAoJ,EAAI6/B,EAAGjuC,MAAQgF,QANnBoJ,GAAI6/B,EAAGjuC,MAAQiuC,EAAGjpC,QAWnBoJ,KCzJfnQ,GAAGgkC,YAAchkC,GAAGgkC,gBACpBhkC,GAAGgkC,YAAY0B,kBAAoB,SAASztB,EAAS6mB,GACjD,YAUA,SAASmgB,GAAqB9kC,EAAI6rB,GAG9B,GAAI7T,GAAU+sB,EAAKC,CAGnB,KAEID,EAAMlZ,EAAOe,iBAAmBf,EAAOoZ,cAAcz1C,SACrDw1C,EAAYD,EAAI5Y,KAAKn3B,UAErBhJ,EAAI,yCACJA,EAAI,eAAiBg5C,GAEjBA,GAAaA,EAAU9rC,MAAM,YAC7B8rC,EAAYD,EAAI5Y,KAAKhjC,WAAWA,WAAW+7C,WAG/CltB,EAAW7C,EAAQoX,mBAAmByY,GAE1C,MAAOh1C,GACHhE,EAAI,wDAA0DgE,EAAM/D,QAAU,IAAK,SACnF+rB,GAAYrmB,SAAS,GAGzB,MAAOqmB,GAMX,QAASmtB,GAAWnlC,EAAI6rB,GACpB,GAAI9nB,GAASjG,EAAQwP,YAAYrF,IAAIjI,GACjC+M,EAA0C,QAAjCjP,EAAQiP,OAAO9d,cAA0B,MAAQ,OAC1D+U,EAAWlG,EAAQyP,cAActF,IAAIjI,GACrCpY,EAAOke,EAAQ9F,EAKnB,OAHA+D,GAAOjG,EAAQsP,UAAYrE,EAAQ/I,GACnC+D,EAAOjG,EAAQ8e,eAAiBh1B,EAEzButB,EAAQ2X,oBACX/f,OAAQA,EACR/I,SAAUA,EACVD,OAAQA,EACRgZ,aAAcjf,EAAQif,aACtBgQ,WAAYlB,EAAOjkC,OArD3B,GAAIutB,GAAUjvB,KACV4f,EAAU6e,EAAM7e,QAChBiD,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,GAsDhB9F,MAAKsjC,WAAa,SAASxpB,GACvB,GAGIjJ,GAHAxH,EAAQ4lB,EAAQ/V,SAASY,GACzB6rB,EAAS1W,EAAQ0X,cAAc7sB,GAC/BxO,EAAU,GAAI3L,IAAG4L,OA8BrB,OA3BAsF,GAAOouC,EAAWnlC,EAAI6rB,GACtB90B,EAAKE,YAAY1H,GAEjB4lB,EAAQuX,iBAAiBb,EAAQ,SAASuZ,GACtCp5C,EAAI,gBAEJ,IAAIgsB,GAAWotB,EAAsBA,EAAsBN,EAAqB9kC,EAAI6rB,EAEpF1W,GAAQqX,iBAAiBxsB,GAGpBlC,EAAQ0P,KAAK8I,UACdzwB,GAAGgmC,GAAQ5kC,SAGX+wB,EAASrmB,QACTH,EAAQG,QAAQqmB,GAGhBxmB,EAAQK,QAAQmmB,KAIxBhsB,EAAI,8BAAgCgU,GACpCjJ,EAAKmtC,SACLr+C,GAAGkR,GAAM9P,SAEFuK,GAGX3L,GAAG6B,OAAOxB,KAAM,GAAIL,IAAG0lC,mBACnBztB,SACI4tB,OAAQ5tB,EAAQ0P,KAAK8I,SACrBjG,UAAWvS,EAAQuS,WAGvBsU,OACIrT,SAAUxT,EAAQwT,SAClBxL,QAASA,EACTiD,QAASA,EACT/c,IAAKA,OC5GjBnG,GAAGgkC,YAAchkC,GAAGgkC,gBACpBhkC,GAAGgkC,YAAYoD,iBAAmB,SAAShsB,EAAM0jB,GAC7C,YAEA,IAAIxP,GAAUjvB,KACV4f,EAAU6e,EAAM7e,QAChB0C,EAAUmc,EAAMnc,QAChBO,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,IACZq5C,EAAYpkC,EAAK4b,gBAAkB5b,EAAK8b,aAExCuoB,EAA4B,SAAStlC,EAAI+D,EAAQgO,GAC7C,GAAI3Q,GAAOoH,EAAQxI,GACfpY,EAAOke,EAAQ9F,EAEdiB,GAAK6b,oBACN/Y,EAAO9C,EAAK/F,SAASojB,WAAWpM,WAAaH,EAAUsd,KACvDtrB,EAAO9C,EAAK/F,SAASojB,WAAWC,gBAAkBxM,EAAUphB,MAC5DoT,EAAO9C,EAAK/F,SAASojB,WAAWE,WAAazM,EAAU3Q,KACvD2C,EAAO9C,EAAK/F,SAASojB,WAAWI,YAAc3M,EAAUud,MACxDvrB,EAAO9C,EAAKgc,mBAAqB7b,GAOjCikC,IAAcpkC,EAAK6b,oBACnB/Y,EAAO9C,EAAK2b,eAAiBh1B,IAIrC29C,EAAyB,GAAI1/C,IAAGgkC,YAAY2b,4BACxCh4B,KAAMvM,EAAKuM,KACXxJ,SAAU/C,EAAK/F,SAASvJ,QAAQqS,SAChCyG,QAASxJ,EAAK/F,SAASvJ,QAAQ8Y,QAC/BmU,YAAa3d,EAAK/F,SAASvJ,QAAQitB,YACnC5yB,IAAKA,EACL+gB,OAAQ9L,EAAK/F,SAASvJ,QAAQob,OAC9BhJ,OAAQ9C,EAAK/F,SAASvJ,QAAQoS,SAGlC0hC,EAAiC,SAASzlC,EAAIoR,GAC1C,GAAI5f,GAAU,GAAI3L,IAAG4L,OAerB,OAbA2f,GAAI2Q,mBAAqB,WACrB,GAAuB,IAAnB3Q,EAAIqR,WAAkB,CACtB,GAAIj6B,GAASk9C,EAAwB1lC,EAAIoR,EAErC5oB,GAAOmJ,QACPH,EAAQG,QAAQnJ,EAAOwvB,SAAU5G,GAGjC5f,EAAQK,QAAQrJ,EAAOwvB,SAAU5G,KAKtC5f,GAGXm0C,EAA0B,SAAS3lC,GAC/B,GAAI+D,GAAS9C,EAAKqM,YAAYrF,IAAIjI,GAC9BpY,EAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,EAOnB,OALA+D,GAAO9C,EAAKmM,UAAYrE,EAAQ/I,GAChC+D,EAAO9C,EAAK2b,eAAiBh1B,EAC7Bmc,EAAO9C,EAAKgc,mBAAqB7b,EACjC2C,EAAO9C,EAAK/F,SAASojB,WAAWI,YAAcvJ,EAAQsS,gBAAgBznB,GAE/D+D,GAGX6hC,EAAwB,SAASx0B,EAAK4G,GAClC,MAAOnyB,IAAG2F,SAAS,IAAK,IAAK,IAAK,IAAK,KAAM4lB,EAAI9Q,QAAU,GACtDW,EAAK+b,qBAAuBhF,EAASrmB,SACtCqmB,EAAStY,OAGjBgmC,EAA0B,SAAS1lC,EAAIoR,GACnC,GAAI4G,EAOJ,OALAhsB,GAAI,sCAAwCgU,GAC5ChU,EAAI,kBAAoBolB,EAAI2rB,cAE5B/kB,EAAW6tB,GAAc,EAAMz0B,IAG3Bzf,SAAUi0C,EAAsBx0B,EAAK4G,GACrCA,SAAUA,IAKlB6tB,EAAgB,SAASh2C,EAAQuhB,GAC7B,GAAI4G,KAEJ,KACIhsB,EAAInG,GAAG8H,OAAO,4CAA6CyjB,EAAI9Q,OAAQ8Q,EAAI2rB,eAC3E/kB,EAAWnyB,GAAGqR,UAAUka,EAAI2rB,cAEhC,MAAO/sC,GACHH,GAAUoR,EAAK+b,oBAAsBhxB,EAAI,qDAAuDgE,EAAM/D,QAAU,IAAK,SAGzH,MAAO+rB,IAGX8tB,EAA4B,SAAS9lC,GACjC,GAAIxO,GAAU,GAAI3L,IAAG4L,OAcrB,OAZA8zC,GAAuBQ,SACf/lC,EACAmV,EAAQ2Z,WAAW9uB,GACnB2lC,EAAwB3lC,GACxBiB,EAAKoM,cAAcpF,IAAIjI,IAE1BrD,KAAK,SAASyU,GACX5f,EAAQG,QAAQk0C,GAAc,EAAOz0B,GAAMA,IAC5C,SAASA,GACR5f,EAAQK,QAAQg0C,GAAc,EAAOz0B,GAAMA,KAG5C5f,GAGXw0C,EAA8B,SAASC,GACnC,GAOIliC,GAPArT,EAAau1C,EAAmBv1C,WAChCsP,EAAKimC,EAAmBjmC,GACxBoR,EAAM60B,EAAmB70B,IACzB80B,EAAeD,EAAmBC,iBAClCC,EAAeF,EAAmBE,iBAClCC,EAAgBH,EAAmBliC,WACnCsiC,EAAoBH,EAAaniC,WAGjCnN,EAAWyuC,EAAY,GAAI11C,UAAa,KACxCod,EAASm5B,EAAan5B,QAAU9L,EAAK8L,OACrC/I,EAAWkiC,EAAaliC,UAAY/C,EAAKsM,cAActF,IAAIjI,GAC3DpY,EAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,EAiCnB,OA/BIiB,GAAK6b,mBACL/Y,EAASle,GAAG6B,UAAWy+C,GACvBtgD,GAAG6B,OAAOqc,EAAQsiC,KAGlBtiC,EAASle,GAAG6B,UAAWy+C,GACvBtgD,GAAG6B,OAAOqc,EAAQsiC,GAClBxgD,GAAG6B,OAAOqc,EAAQqiC,GAElBriC,EAAO9C,EAAKmM,UAAYrE,EAAQ/I,GAChC+D,EAAO9C,EAAK2b,eAAiBh1B,EAEzBy9C,EACAthC,EAAO9C,EAAKgc,mBAAqB7b,EAE3BH,EAAK8b,eACXhZ,EAAO9C,EAAKoP,WAAazoB,IAK5BqZ,EAAK8b,eACN/Y,EAAWne,GAAGkQ,QAAQgO,EAAQC,IAGlCoN,EAAI8Q,KAAKnV,EAAQ/I,GAAU,GAEvB/C,EAAKuM,KAAK8I,UAAYrV,EAAKuM,KAAK0R,kBAChC9N,EAAIhY,iBAAkB,GAGtBisC,GACIpkC,EAAK8b,cACLl3B,GAAG8Q,aAAaoN,EAAQnN,GAG5BA,EAASxL,OAAO6V,EAAKoP,UAAW3f,GACzBkG,GAGJlG,GAGX41C,EAAmB,SAASC,GACxB,GAAIC,GAAkBD,EAAeC,gBACjCxmC,EAAKumC,EAAevmC,GACpBoR,EAAMm1B,EAAen1B,GAEzB,IAAIo1B,EACA3gD,GAAG+C,KAAK49C,EAAiB,SAASC,EAAYC,GAC1Ct1B,EAAI2R,iBAAiB0jB,EAAYC,SAGpC,CACD,GAAIC,GAAe1lC,EAAKoM,cAAcpF,IAAIjI,GACtCtP,EAAaykB,EAAQ5N,QAAQvH,EAEjCoR,GAAI2R,iBAAiB,SAAU,oBAC/B3R,EAAI2R,iBAAiB,mBAAoB,kBACzC3R,EAAI2R,iBAAiB,gBAAiB,YAEjCsiB,IACDj0B,EAAI2R,iBAAiB,eAAgB,4BAErC3R,EAAI2R,iBAAiB,cAAeryB,EAAWtK,OAGnDP,GAAG+C,KAAK+9C,EAAc,SAAS/+C,EAAMkB,GACjCsoB,EAAI2R,iBAAiBn7B,EAAMkB,MAK3CjD,IAAG6B,OAAOxB,MACN+hC,YAAa,SAAS2e,GAClB,GAOIp1C,GAASq1C,EAAQV,EAPjBnmC,EAAK4mC,EAAkB5mC,GACvBwlB,EAAWohB,EAAkBphB,SAC7BwC,EAAY4e,EAAkB5e,cAC9BjJ,EAAW6nB,EAAkB7nB,SAE7BhN,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCpU,EAAM+D,EAAQ2Z,WAAW9uB,EAAIwlB,GACEzhB,IA4BnC,OA1BAvS,GAAUi0C,EAA+BzlC,EAAIoR,GAC7C+D,EAAQ+a,yBAAyBlwB,EAAIwlB,EAAUzT,EAAU3Q,MACzD+kC,EAAellC,EAAKqM,YAAYrF,IAAIjI,GACpCslC,EAA0BtlC,EAAI+D,EAAQgO,GAElCgN,IACAhb,EAAO9C,EAAKjF,OAAOsiB,WAAWS,WAAY,GAG9C8nB,EAASb,GACLt1C,WAAYqhB,EAAU5gB,KACtB6O,GAAIA,EACJmmC,aAAcA,EACdpiC,OAAQA,EACRqN,IAAKA,EACL80B,aAAcle,IAGlBse,GACIE,gBAAiBxe,EAAUvd,QAC3BzK,GAAIA,EACJoR,IAAKA,IAGTA,EAAIgR,KAAKykB,GAEFr1C,GAGXg4B,WAAY,SAASxpB,GACjB,GACIxO,GAAS4f,EAAK+0B,EAAcU,EAD5Bn2C,EAAaykB,EAAQ5N,QAAQvH,EAsBjC,OAnBAoR,GAAM+D,EAAQ2Z,WAAW9uB,GACzBmV,EAAQ+a,yBAAyBlwB,GACjCxO,EAAUi0C,EAA+BzlC,EAAIoR,GAC7C+0B,EAAellC,EAAKqM,YAAYrF,IAAIjI,GAEpC6mC,EAASb,GACLt1C,WAAYA,EACZsP,GAAIA,EACJmmC,aAAcA,EACd/0B,IAAKA,IAGTk1B,GACItmC,GAAIA,EACJoR,IAAKA,IAGTA,EAAIgR,KAAKykB,GAEFr1C,KAIf3L,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGonC,kBACnBnvB,QAASjY,GAAG6B,QAAQipB,UAAW,eAAgB1P,GAC/C0jB,MAAO9+B,GAAG6B,QAAQqgB,YAAa9G,EAAKsM,cAActF,KAAM0c,MAG5D9+B,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OACIyzB,eAAgB,SAAS9lB,GAGrB,MAFA2kB,GAAMmF,aAAa9pB,GAEfiB,EAAK/F,SAASvJ,QAAQqS,SACf8hC,EAA0B9lC,GAG1B3N,EAAOyzB,eAAe9lB,EAAIna,GAAG4P,KAAKowC,EAAe3/C,MAAM,SCzSlFL,GAAGgkC,YAAY2b,2BAA6B,SAAS9nC,GACjD,YAEA,IAAIwzB,GACApzB,GACI0P,MACI+I,UAAU,EACVD,UAAU,EACV4I,iBAAiB,GAErBlb,SAAU,KACVhY,IAAK,SAAS4B,EAAK1B,KACnB6gB,OAAQ,QAEZ+5B,KACAC,GACI9+B,IAAK,SAASjI,GACV,MAAIna,IAAG6G,WAAWoR,EAAQkG,UACflG,EAAQkG,SAAShE,GAGrBlC,EAAQkG,UAI3Bne,IAAG6B,OAAOoW,EAASJ,GAEnBwzB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdR,YAAaxkB,EAAQ8gB,YAAc,mBAAqB,oCACxDwE,cAAetlB,EAAQiP,QACvBA,OAAQjP,EAAQiP,OAChBQ,cAAew5B,EACf/jB,oCAAoC,EACpCxV,KAAM1P,EAAQ0P,KACdxhB,IAAK8R,EAAQ9R,IACbmlB,WAAY,SAASnR,EAAIoR,EAAKvD,GAC1B,GAAIrc,GAAUs1C,EAAS9mC,SAEhB8mC,GAAS9mC,GAEZ6N,EACArc,EAAQK,QAAQuf,GAGhB5f,EAAQG,QAAQyf,OAK5BvrB,GAAG6B,OAAOxB,MACN6/C,SAAU,SAAS/lC,EAAIoR,EAAKrN,EAAQ0G,GAChC,GAAIjZ,GAAU,GAAI3L,IAAG4L,OAWrB,OATAqM,GAAQ9R,IAAI,0CAA4CgU,GAExD8mC,EAAS9mC,GAAMxO,EAEf0/B,EAAUxN,cAAc1jB,GACnB+jB,WAAWjmB,EAAQiG,OAAO/D,IAAO+D,GACjCmgB,YAAYpmB,EAAQ2M,QAAQzK,IAAOyK,GACnC2X,KAAKhR,GAEH5f,MCtEnB3L,GAAGmhD,YAAc,SAAStpC,GACtB,YAoBA,SAASupC,GAAmB1hC,EAAO2hC,GAE/B,GAAIC,GAAer5C,MAAMvB,UAAUwB,MAAMtB,KAAK8Y,EAE9CzH,GAAQ6O,UAAUy6B,QAAQ,WAAa7hC,EAAM3Z,OAAS,mBACtDs7C,EAAeG,cAAa,GAC5BvpC,EAAQ6O,UAAU26B,+BAA+BH,EAAcD,EAAeK,cAGlF,QAASC,GAAiBxnB,GACtB,GAAIynB,GAAoB,GAAI5hD,IAAG4L,OAwC/B,OAtCIuuB,GAAM5xB,OACN4xB,EAAM3e,KAAK,SAASA,GAChBA,EAAKqmC,OAASC,EAAqB3nB,GACnC4nB,EAAa7+C,KAAKsY,GAClBomC,EAAkB91C,WAEtB,SAASk2C,GACL/pC,EAAQ6O,UAAUy6B,QAAQ,oBAAsBpnB,EAAM8nB,SAAW,sBAAwBD,EAAUjxB,KAAO,IAAK,SAC/G6wB,EAAkB51C,YAGjBmuB,EAAM+nB,aACXC,EAAoBhoB,GAAOrjB,KACvB,SAAwBoD,GACpB,GAAIkoC,GAAcloC,EAAQnU,MAE1B/F,IAAG+C,KAAKmX,EAAS,SAASlX,EAAKm3B,GAC3BwnB,EAAiBxnB,GAAO5iB,KAAK,WACzB6qC,GAAe,EAEK,IAAhBA,GACAR,EAAkB91C,cAKzBoO,EAAQnU,QACT67C,EAAkB91C,WAI1B,SAAqBk2C,GACjB/pC,EAAQ6O,UAAUy6B,QAAQ,oBAAsBpnB,EAAM8nB,SAAW,sBAAwBD,EAAUjxB,KAAO,IAAK,SAC/G6wB,EAAkB51C,YAKvB41C,EAGX,QAASE,GAAqB3nB,GAC1B,GAAIp4B,GAAOo4B,EAAMp4B,KACbkgD,EAAW9nB,EAAM8nB,SACjBI,EAAwBJ,EAASpwC,YAAY9P,EAUjD,OAPAkgD,GAAWA,EAASnwC,OAAO,EAAGuwC,GAGH,MAAvBJ,EAAStyC,OAAO,KAChBsyC,EAAWA,EAASnwC,OAAO,IAGxBmwC,EAIX,QAASE,GAAoBhoB,EAAO6f,EAAQsI,EAAcC,GACtD,GAAI52C,GAAU42C,GAAmB,GAAIviD,IAAG4L,QACpC42C,EAAYxI,GAAU7f,EAAMsoB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqBxoC,GACjB,GAAIyoC,GAAaL,EAAeA,EAAatyC,OAAOkK,GAAWA,CAE3DA,GAAQnU,OACR4jB,WAAW,WACPw4B,EAAoBhoB,EAAOqoB,EAAWG,EAAYh3C,IACnD,GAGHA,EAAQG,QAAQ62C,IAIxBh3C,EAAQK,SAGLL,EAGX,QAASi3C,GAAmBv4C,EAAcg3C,GACtC,GAAIwB,MACAC,EAA4B,GAAI9iD,IAAG4L,OA4CvC,OA1CAqM,GAAQ6O,UAAUi8B,yBAClB1B,EAAeG,cAAa,GAExBn3C,EAAaqV,MAAM3Z,OAAS,IAAMkS,EAAQ+qC,oBAC1C/qC,EAAQ6O,UAAU26B,mCAClBxpC,EAAQ6O,UAAUm8B,UAAU,oBAAqB,IACjD5B,EAAeG,cAAa,GAC5BsB,EAA0B92C,YAG1B+1C,KAEI/hD,GAAGoK,sBAAsBC,GACzBrK,GAAG+C,KAAKsH,EAAaC,MAAO,SAAStH,EAAKsE,GACtC,GAAI6yB,GAAQ7yB,EAAKiD,kBAEb4vB,KAEIA,EAAM5xB,OACNw5C,EAAa7+C,KAAKoE,EAAKs2C,aAIvBiF,EAAsB3/C,KAAKy+C,EAAiBxnB,GAAO5iB,KAAK,WACpDsrC,EAAsBrf,MACe,IAAjCqf,EAAsB98C,QACtB+8C,EAA0Bh3C,gBAQ9Ci2C,EAAe13C,EAAaqV,MAGK,IAAjCmjC,EAAsB98C,QACtB+8C,EAA0Bh3C,WAI3Bg3C,EAGX,QAASI,GAAcC,GACnB,GAAIC,GAAW,GAAIpjD,IAAGqjD,gBAClBC,sBAlKoB,eAmKpBrjD,QAASkjD,EACTI,QAAS,SAASz0C,GACd9O,GAAGmjD,GAAU9gD,SAAS4V,EAAQmS,QAAQo5B,YACtC10C,EAAE20C,mBAENC,sBAAuB,SAAS50C,GAC5B9O,GAAGmjD,GAAU7gD,YAAY2V,EAAQmS,QAAQo5B,aAE7CG,OAAQ,SAAS70C,GACb8zC,EAAmB9zC,EAAEzE,aAAc+4C,GAAUtsC,KACzC,WACIsqC,EAAmBW,EAAcqB,IAErC,WACInrC,EAAQ6O,UAAUy6B,QAAQ,sEAAuE,aAcjH,OARAvoC,GAAezG,YAAY,WACvB6wC,EAAShxC,YAGbpS,GAAGmjD,GAAUr/C,aA1LY,qBA0L4B9D,GAAGmjD,GAAUjjD,OAElE0jD,EAAgB1gD,KAAKkgD,GAEdA,EAGX,QAASS,GAAWC,GAChB,GAAIC,EASJ,OAPA/jD,IAAG+C,KAAK+gD,EAAUz5C,aAAa25C,MAAO,SAASv0C,EAAKxM,GAChD,GAAY,UAARA,EAEA,MADA8gD,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBn1C,GACxB,MAAI9O,IAAG6N,SACIiB,EAAEgtC,EAAI,GAAKhtC,EAAEo1C,EAAI,EAGb,IAARp1C,EAAEgtC,GAAmB,IAARhtC,EAAEo1C,EAG1B,QAASC,KACL,GAAIC,GAAYnsC,EAAQosC,iBAEpBC,EAAqB,WACjB36B,WAAW,WACP3pB,GAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAC7BpjD,GAAGojD,GAAUt/C,aApOJ,qBAoO4C9D,GAAGojD,GAAUljD,OAClEF,GAAGojD,GAAU9gD,YAAY2V,EAAQmS,QAAQo5B,eAE9C,IAGXxjD,IAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAC7B,GAAI/B,GAAiB6B,EAAcE,EAG/BgB,GAAUr+C,QAAU/F,GAAG8S,kBAAkB6C,UACzCqD,EAAe1Y,OAAOqJ,SAAU,YAAa,SAASmF,IAC7CuyC,EAAeG,gBAAkBqC,EAAW/0C,IAC7C9O,GAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAGzBA,YAAoBmB,cACpBvkD,GAAGojD,GAAUt/C,aArPZ,qBAuPD9D,GAAGojD,GAAU9hD,KAAKlB,QAAS,gBAQnD4Y,EAAe1Y,OAAOqJ,SAAU,YAAa,SAASmF,GAC9Cm1C,EAAmBn1C,IACnBw1C,MAORtrC,EAAe1Y,OAAON,GAAG2J,UAAUvG,WAAW,GAAI,aAAc,SAAS0L,GACrEw1C,MAGJtrC,EAAe1Y,OAAOqJ,SAAU,OAAQ,SAASmF,GACzC+0C,EAAW/0C,KACXA,EAAED,iBACFy1C,OAIRtrC,EAAe1Y,OAAOqJ,SApRE,eAoR+B26C,GArR3D,GAAIrsC,GAGA2rC,KACA7B,KACA/oC,EAAiB,GAAIhZ,IAAGkS,cAE5B+F,IACIosC,oBACArB,oBAAoB,EACpB54B,SACIo5B,WAAY,MAEhB18B,UAAW,GAAI9mB,IAAGmhD,YAAYr6B,WAGlC9mB,GAAG6B,OAAOoW,EAASJ,GAAG,GAwQtBssC,IAEAnkD,GAAG6B,OAAOxB,MACNmkD,mBAAoB,SAASvkD,GACzBgY,EAAQosC,iBAAiBnhD,KAAKjD,GAC9BijD,EAAcjjD,IAGlBwkD,eAAgB,SAASxkD,GACrB,GAAIyQ,GACAg0C,EAAMzsC,EAAQosC,gBAElB,KAAK3zC,IAAKg0C,GACN,GAAIA,EAAIh0C,KAAOzQ,EACX,MAAOykD,GAAIroC,OAAO3L,EAAG,IAKjC0B,QAAS,WACL4G,EAAe5G,UACfpS,GAAG+C,KAAK6gD,EAAiB,SAAS5gD,EAAKogD,GACnCA,EAAShxC,eAKrB/R,KAAKmyC,YACLnyC,KAAKmyC,SAASsP,qBAAuBA,GAGzC9hD,GAAGmhD,YAAYr6B,UAAY,WACvB,YAEA,QACIi8B,uBAAwB,aACxBtB,+BAAgC,SAAS/hC,EAAOilC,KAChD1B,UAAW,SAASlyB,EAAM6zB,GACtB5kD,GAAGmG,IAAI,2BAA6B4qB,EAAO,2BAA6B6zB,EAAiB,IAAK,UAElGrD,QAAS,SAASn7C,EAASC,GACvBrG,GAAGmG,IAAIC,EAASC,MAK5BrG,GAAGqjD,eAAiB,SAASxrC,GACzB,YAiBA,SAASgtC,KACL,MAAO7kD,IAAG6N,UAAa7N,GAAGiO,WAAajO,GAAGkO,UAG9C,QAAS42C,GAAmBh2C,GAEnBi2C,IAGGF,EACA7rC,EAAe1Y,OAAOqJ,SAAU,WAAY,SAASmF,GACjDA,EAAED,mBAGNmK,EAAe1Y,OAAOqJ,SAAU,WAAY,SAASmF,GAC7CA,EAAEzE,eACFyE,EAAEzE,aAAa26C,WAAa,OAC5Bl2C,EAAED,oBAKdk2C,GAAsB,GAI9B,QAASE,GAAgBn2C,GAGrB,IAAK9O,GAAG8S,kBAAkB6C,SACtB,OAAO,CAGX,IAAIuvC,GAAYC,EAAKr2C,EAAEzE,aAEvB+6C,EAAWplD,GAAG6N,QAOd,OADAq3C,MAAallD,GAAGqN,OAAQrN,GAAG8S,kBAAkB6C,WAAuC,SAArBwvC,EAAGE,cAC3DF,GAAMD,IAEAC,EAAGzlC,OAASylC,EAAGzlC,MAAM3Z,SACpBq/C,GAAYD,EAAGnB,MAAMljD,UAAYqkD,EAAGnB,MAAMljD,SAAS,UACpDqkD,EAAGnB,MAAMsB,UAAYH,EAAGnB,MAAMsB,SAAS,UAIxD,QAASC,GAAoBC,GAIzB,MAHmBrhD,UAAfqhD,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiBj8C,SAASk8C,YAAY,SACtCD,EAAeE,UAAU7tC,EAAQqrC,uBAAuB,GAAM,GAJlE,GAAIsC,EAOJ,IAAI1gD,OAAO6gD,YACP,IACIH,EAAiB,GAAIG,aAAY9tC,EAAQqrC,uBAE7C,MAAO1M,GACH+O,QAIJA,IAGJh8C,UAASq8C,cAAcJ,GAG3B,QAASK,KACLjtC,EAAe1Y,OAAOL,EAAS,WAAY,SAAS6O,GAChD,GAAKm2C,EAAgBn2C,GAArB,CAMA,GAAIo3C,GAASlmD,GAAGqN,MAAQrN,GAAG8S,kBAAkB6C,SAAW,KAAO7G,EAAEzE,aAAag7C,aAE1Ev2C,GAAEzE,aAAa26C,WADJ,SAAXkB,GAAgC,aAAXA,EACO,OAEA,OAGhCp3C,EAAE20C,kBACF30C,EAAED,oBAGNmK,EAAe1Y,OAAOL,EAAS,YAAa,SAAS6O,GACjD,IAAKy2C,IAAuB,CACxB,IAAKN,EAAgBn2C,GACjB,MAEJmJ,GAAQsrC,QAAQz0C,MAIxBkK,EAAe1Y,OAAOL,EAAS,YAAa,SAAS6O,GACjD,GAAKm2C,EAAgBn2C,GAArB,CAIAmJ,EAAQkd,QAAQrmB,EAEhB,IAAIq3C,GAAgBx8C,SAASy8C,iBAAiBt3C,EAAEu3C,QAASv3C,EAAEw3C,QAEvDtmD,IAAGK,MAAMS,SAASqlD,IAItBluC,EAAQyrC,sBAAsB50C,MAGlCkK,EAAe1Y,OAAOL,EAAS,OAAQ,SAAS6O,GAC5C,IAAKy2C,IAAuB,CACxB,IAAKN,EAAgBn2C,GACjB,MAGJA,GAAED,iBACFC,EAAE20C,kBACFxrC,EAAQ0rC,OAAO70C,GAEf42C,OArJZ,GACIztC,GAAShY,EAASwlD,EAAaV,EAD/B/rC,EAAiB,GAAIhZ,IAAGkS,cAG5B+F,IACIhY,QAAS,KACTsjD,QAAS,SAASz0C,KAClBqmB,QAAS,SAASrmB,KAElB40C,sBAAuB,SAAS50C,KAChC60C,OAAQ,SAAS70C,MAGrB9O,GAAG6B,OAAOoW,EAASJ,GACnB5X,EAAUgY,EAAQhY,QA6IlB6kD,IACAmB,IAEAjmD,GAAG6B,OAAOxB,MACNmhD,aAAc,SAASgE,GACnB,MAAOD,GAAoBC,IAG/BpzC,QAAS,WACL4G,EAAe5G,WAGnBsvC,WAAY,WACR,MAAOzhD,MAIfI,KAAKmyC,YACLnyC,KAAKmyC,SAASyS,gBAAkBA,GCrfnC,WACG,YAEAjlD,IAAGumD,aACCloC,gBAAiB,SAASC,GACtBje,KAAKmmD,QAAQ9/C,UAAU2X,gBAAgBpO,MAAM5P,KAAM8H,WACnD9H,KAAKomD,YAAYC,iBAGrBpmC,iBAAkB,WACdjgB,KAAKmmD,QAAQ9/C,UAAU4Z,iBAAiBrQ,MAAM5P,KAAM8H,WACpD9H,KAAKomD,YAAYE,cAGrBC,iBAAkB,SAAS3mD,GACvBI,KAAKwmD,MAAQxmD,KAAKwmD,KAAKrC,mBAAmBvkD,IAG9C6mD,oBAAqB,SAAS7mD,GAC1B,GAAII,KAAKwmD,KACL,MAAOxmD,MAAKwmD,KAAKpC,eAAexkD,IAIxC8mD,gBAAiB,SAAS5sC,GACtB,IAAK9Z,KAAKomD,YAAYO,gBAAgB7sC,GAClC,MAAO9Z,MAAKomD,YAAYQ,iBAAiB9sC,IAIjDN,MAAO,WACHxZ,KAAKmmD,QAAQ9/C,UAAUmT,MAAM5J,MAAM5P,KAAM8H,WACzC9H,KAAKomD,YAAY5sC,SAEZxZ,KAAKye,SAAS8E,QAAUvjB,KAAKomD,YAAY1kC,cAC1C1hB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKomD,YAAY1kC,YAC1B7J,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGHnZ,KAAKwmD,OACLxmD,KAAKwmD,KAAKz0C,UACV/R,KAAKwmD,KAAOxmD,KAAK6mD,qBAGrB7mD,KAAK8mD,mBAAqB,EAC1B9mD,KAAK+mD,uBAAyB,EAE9B/mD,KAAKgnD,mCAGTzhC,QAAS,SAASzL,EAAIuC,GAClB,GAAI4qC,GAAoBjnD,KAAKye,SAAS0S,eAAe9U,EAErDrc,MAAKmmD,QAAQ9/C,UAAUkf,QAAQ3V,MAAM5P,KAAM8H,WAC3C9H,KAAKomD,YAAYc,eAAeptC,EAAImtC,IAGxChkC,YAAa,SAASnJ,GAClB,GAAIyuB,GAASvoC,KAAKmmD,QAAQ9/C,UAAU4c,YAAYrT,MAAM5P,KAAM8H,UAG5D,OADAygC,IAAUvoC,KAAKomD,YAAYe,aAAartC,GACjCyuB,GAGXroB,eAAgB,SAASpG,GACrB,GAAIstC,GAAYpnD,KAAKmmD,QAAQ9/C,UAAU6Z,eAAetQ,MAAM5P,KAAM8H,UAGlE,OADAs/C,IAAapnD,KAAKomD,YAAYiB,gBAAgBvtC,GACvCstC,GAGXE,MAAO,SAASC,GACZ,MAAOvnD,MAAKomD,YAAYoB,UAAUD,IAGtCE,cAAe,SAAS9mC,GAGpB,MAFW3gB,MAAKqhB,QAAQV,GAEZ+mC,eAOpB/nD,GAAGgoD,cACChmC,WAAY,SAAShK,GACjB,GAAI4L,GAASvjB,KAAKmmD,QAAQ9/C,UAAUsb,WAAW/R,MAAM5P,KAAM8H,UAQ3D,OANKyb,IACG5L,IAAa3X,KAAK6tB,mBAClBtK,EAASvjB,KAAKomD,YAAY1kC,aAI3B6B,GAGXqkC,gBAAiB,SAASjnC,GACtB3gB,KAAKomD,YAAYyB,WAAWlnC,IAGhCqmC,gCAAiC,WAC7BhnD,KAAK8nD,yBAA2BnoD,GAAGooD,yBAA2B/nD,KAAKgoD,6BAInEhoD,KAAKioD,wBAA0BtoD,GAAGiO,UAE9B5N,KAAKkoD,2BAELloD,KAAKmoD,sBAAwBnoD,KAAKooD,0BAClCpoD,KAAKqoD,6BAA+BroD,KAAKsoD,iCACzCtoD,KAAKuoD,2BAA6BvoD,KAAKwoD,iCAI/C3B,kBAAmB,WACf,GAAI/uC,GAAO9X,KACPgkD,EAAmBhkD,KAAKye,SAASgqC,YAAYC,eAC7CC,EAAa3oD,KAAKomD,YAClBwC,EAAkBD,EAAWE,aAIjC,OAFAD,IAAmB5E,EAAiBnhD,KAAK+lD,GAElC,GAAIjpD,IAAGmhD,aACVkD,iBAAkBA,EAClBrB,mBAAoB3iD,KAAKye,SAASjV,SAClCugB,SACIo5B,WAAYnjD,KAAKye,SAASsL,QAAQo5B,YAEtC18B,WACIi8B,uBAAwB,WACpBiG,EAAWG,sBAEf1H,+BAAgC,SAAS/hC,EAAOilC,GAC5CqE,EAAWI,qBAEXppD,GAAG+C,KAAK2c,EAAO,SAAS1c,EAAKwY,GACzBA,EAAKusC,aAAepD,IAGpBjlC,EAAM3Z,QACNoS,EAAKiG,SAASsB,EAAO,KAAM,OAGnCujC,UAAW,SAASlyB,EAAMs4B,GACtBlxC,EAAK+N,WAAW6K,EAAMs4B,IAE1B9H,QAAS,SAASn7C,EAASC,GACvB8R,EAAKhS,IAAIC,EAASC,QAMlCgiD,2BAA4B,WACxB,GAAIlwC,GAAO9X,IAEX,OAAO,IAAIL,IAAGooD,yBACVY,WAAY3oD,KAAKomD,YAEjBtgD,IAAK,SAASC,EAASkjD,GACnBnxC,EAAKhS,IAAIC,EAASkjD,IAGtBC,aAAc,SAASvoC,GACnB7I,EAAKuI,WAAWM,IAGpByK,SAAU,SAASzK,GACf7I,EAAK2H,OAAOkB,IAGhBwoC,QAAS,SAASxoC,GACd7I,EAAKmM,MAAMtD,IAGfyoC,QAAS,SAASzoC,GACd7I,EAAKmL,YAAYtC,IAGrB0oC,WAAY,SAAS1oC,GACjB7I,EAAKoI,eAAeS,IAGxB2oC,UAAW,SAAS3oC,GAChB,MAAO7I,GAAK8H,QAAQe,OAKhCunC,uBAAwB,WAEpB,MAAOloD,MAAKomD,YAAYmD,2BAChBvpD,KAAKye,SAASuR,YACfrwB,GAAG6pD,sBACH7pD,GAAG8pD,2BACH9pD,GAAG8pD,2BAGdC,qBAAsB,WAClB,GAAI5xC,GAAO9X,KACP2oD,EAAa3oD,KAAKomD,WAEtB,QACIuC,WAAYA,EACZ7iD,IAAK,SAASC,EAASkjD,GACnBnxC,EAAKhS,IAAIC,EAASkjD,IAEtBU,kBAAmB,SAAShpC,GACxB,MAAO7I,GAAKsK,YAAYtI,GAAI6G,IAASvG,QAEzCkvC,UAAW,SAAS3oC,GAChB,MAAO7I,GAAK8H,QAAQe,IAExBipC,UAAW,SAAS9vC,EAAIuC,GACpBvE,EAAKyN,QAAQzL,EAAIuC,IAErBwtC,sBAAuB,SAAS/vC,EAAIgwC,GAChC,GAAIC,GAAUpqD,GAAGgpD,EAAWqB,aAAalwC,IACrCmwC,EAAkBtqD,GAAGgpD,EAAW/B,iBAAiB9sC,GAEjDgwC,IACAC,EAAQ/nD,SAAS,cACjB2mD,EAAWuB,aAAapwC,GACxB6uC,EAAWwB,aAAarwC,KAGxBiwC,EAAQ9nD,YAAY,cACpB0mD,EAAWyB,aAAatwC,GACxB6uC,EAAW0B,aAAavwC,IAI5BmwC,EAAgBjoD,SAAS,WAAWC,YAAY,cAK5DmnB,sBAAuB,SAAStP,EAAIgC,EAAWD,GAC3C7b,KAAKmmD,QAAQ9/C,UAAU+iB,sBAAsBxZ,MAAM5P,KAAM8H,WAErD9H,KAAKkoD,0BAEDloD,KAAKomD,YAAYQ,iBAAiB9sC,IAAO+B,IAAclc,GAAGya,OAAOyC,YACjE7c,KAAKomD,YAAYkE,qBAAqBxwC,GACtC9Z,KAAKomD,YAAY+D,aAAarwC,IAIlCgC,IAAcnc,GAAGya,OAAOgD,iBAAmBvB,IAAclc,GAAGya,OAAO8C,WACnEld,KAAKomD,YAAYmE,UAAUzwC,GAC3B9Z,KAAKomD,YAAYoE,cAAc1wC,GAC/Bna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK7X,YAAYjC,KAAKyqD,SAASC,WAE/D7uC,IAAclc,GAAGya,OAAOkD,eAC7Btd,KAAKomD,YAAYuE,UAAU7wC,IAInCwuC,+BAAgC,WAC5B,GAAIvtC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAGirD,4BAA4B7vC,IAG9CytC,6BAA8B,WAC1B,GAAIztC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAG8pD,0BAA0B1uC,IAG5CqtC,wBAAyB,WACrB,GAAIrtC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAG6pD,qBAAqBzuC,IAGvC0Y,eAAgB,SAAS3Z,GACrB9Z,KAAKmmD,QAAQ9/C,UAAUotB,eAAe7jB,MAAM5P,KAAM8H,WAClD9H,KAAKomD,YAAYyE,YAAY/wC,IAGjC2X,eAAgB,SAASe,EAAYC,GACjCzyB,KAAKmmD,QAAQ9/C,UAAUorB,eAAe7hB,MAAM5P,KAAM8H,WAClD9H,KAAKomD,YAAY0E,sBAGrBz3B,UAAW,SAASvZ,EAAIpY,GACpB,GAAIyZ,GAAOnb,KAAKqhB,QAAQvH,EAEpBqB,IAAQA,EAAKqmC,QAAUxhD,KAAKye,SAASgqC,YAAYsC,sBACjD/qD,KAAKwjB,aAAa0F,YAAYpP,GAC1BkxC,OAAQ7vC,EAAKqmC,SAIrBxhD,KAAKmmD,QAAQ9/C,UAAUgtB,UAAUzjB,MAAM5P,KAAM8H,WAC7C9H,KAAKirD,WAAWnxC,EAAIpY,IAIxB6xB,aAAc,SAASzZ,GAEf9Z,KAAKkoD,2BACLloD,KAAKomD,YAAYkE,qBAAqBxwC,GACtC9Z,KAAKomD,YAAYiE,aAAavwC,GAGzB9Z,KAAKioD,wBACNjoD,KAAKuoD,2BAA2B2C,WAAWlrD,KAAKomD,YAAY4D,aAAalwC,MAMrFkR,YAAa,SAASlR,EAAIpY,EAAMopB,EAAQC,GACpC/qB,KAAKmmD,QAAQ9/C,UAAU2kB,YAAYpb,MAAM5P,KAAM8H,WAE/C9H,KAAKomD,YAAY+E,eAAerxC,EAAIgR,EAAQC,GAE9B,IAAVA,GAAoD,MAArCzpB,KAAKC,MAAMupB,EAASC,EAAQ,MAC3C/qB,KAAKomD,YAAYgF,WAAWtxC,GAC5B9Z,KAAKomD,YAAYuE,UAAU7wC,GAC3B9Z,KAAKomD,YAAYiF,aAAavxC,GAC9B9Z,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAASpb,KAAKioD,oBAGtDtrD,KAAKurD,iBAAiBzxC,IAItB9Z,KAAKurD,iBAAiBzxC,EAAIgR,EAAQC,IAI1CiJ,iBAAkB,SAASlJ,EAAQC,GAC/B/qB,KAAKmmD,QAAQ9/C,UAAU2tB,iBAAiBpkB,MAAM5P,KAAM8H,WACpD9H,KAAKomD,YAAYvJ,oBAAoB/xB,EAAQC,IAGjDI,YAAa,SAASrR,EAAIpY,EAAMY,EAAQ4oB,GAMpC,QAASsgC,GAAelpD,GAGfid,IAILopC,EAAW6B,cAAc1wC,GAEzBna,GAAG4f,GAAetd,YAAY6V,EAAK2yC,SAASC,UAC5C/B,EAAW0C,aAAavxC,GAEpBhC,EAAKsK,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAOkD,eAC/CqrC,EAAWyC,WAAWtxC,GAE1B6uC,EAAWkC,YAAY/wC,GAEnBxX,EAAOmJ,QACPqM,EAAK2zC,sBAAsB3xC,IAG3Bna,GAAG4f,GAAevd,SAAS8V,EAAK2yC,SAASiB,MACzC/C,EAAWgD,WAAW7xC,GAElB6uC,EAAWiD,oBAAsB9zC,EAAKuL,gBAAgBvJ,KACtDna,GAAG4f,GAAevd,SAAS8V,EAAK2yC,SAAS/N,WACzCiM,EAAWkD,UAAU/xC,IAEzBhC,EAAKg0C,2BAA2BhyC,EAAIxX,KAjC5C,GAAIypD,GAAe/rD,KAAKmmD,QAAQ9/C,UAAU8kB,YAAYvb,MAAM5P,KAAM8H,WAC9D6gD,EAAa3oD,KAAKomD,YAClB7mC,EAAgBopC,EAAW/B,iBAAiB9sC,GAC5ChC,EAAO9X,IA6CX,OAVI+rD,aAAwBpsD,IAAG4L,QAC3BwgD,EAAa70C,KAAK,SAAS80C,GACvBR,EAAeQ,KAKnBR,EAAelpD,GAGZypD,GAGXN,sBAAuB,SAAS3xC,GAC5B,GAAI6uC,GAAa3oD,KAAKomD,WAElBpmD,MAAKmwB,qBACLw4B,EAAWsD,iBAAiBnyC,GAGhCna,GAAGgpD,EAAW/B,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAASh/C,SAE3DzL,KAAKksD,sBAAsBpyC,IAG/B0R,cAAe,SAAS1R,GACpB9Z,KAAKmmD,QAAQ9/C,UAAUmlB,cAAc5b,MAAM5P,KAAM8H,WACjD9H,KAAKomD,YAAY+F,YAAYryC,IAGjC4R,UAAW,SAAS5R,EAAIpY,GACpB,GAAIqqD,GAAe/rD,KAAKmmD,QAAQ9/C,UAAUqlB,UAAU9b,MAAM5P,KAAM8H,UAIhE,OAFA9H,MAAKomD,YAAY+F,YAAYryC,GAEtBiyC,GAGXjgC,eAAgB,SAAShS,EAAI+R,GACzB7rB,KAAKmmD,QAAQ9/C,UAAUylB,eAAelc,MAAM5P,KAAM8H,WAI9C+jB,EAAUG,UAAY,GAAKhsB,KAAK6f,SAASiD,YAAYhJ,IACrD9Z,KAAKomD,YAAYgG,WAAWtyC,IAIpCwR,UAAW,SAASxR,EAAIpY,GACpB1B,KAAKmmD,QAAQ9/C,UAAUilB,UAAU1b,MAAM5P,KAAM8H,WAC7C9H,KAAK4nD,gBAAgB9tC,GAEU,IAA3B9Z,KAAKkuB,mBACLluB,KAAKomD,YAAY0E,sBAIzBh4B,mBAAoB,SAAShZ,GACzB,GAAIuyC,GAAoBC,EAASC,CAEjCvsD,MAAKmmD,QAAQ9/C,UAAUysB,mBAAmBljB,MAAM5P,KAAM8H,WAEtD9H,KAAKwsD,gBAAgB1yC,GAEjB9Z,KAAKye,SAASwF,MAAMwoC,oBACpBJ,EAAqBrsD,KAAKmjB,aAAarJ,GACvCwyC,EAAUtsD,KAAKye,SAASwF,MAAMqR,gBAE9Bi3B,EAAYvsD,KAAKye,SAASwF,MAAMyoC,cAAcxqD,QAAQ,gBAAiBmqD,GACvEE,EAAYA,EAAUrqD,QAAQ,eAAgBoqD,GAE9CtsD,KAAKomD,YAAYoE,cAAc1wC,EAAIyyC,GACnC5sD,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAASC,YAKzEn5B,qBAAsB,SAASzX,GAC3B,MAAI9Z,MAAKmmD,QAAQ9/C,UAAUkrB,qBAAqB3hB,MAAM5P,KAAM8H,YACxD9H,KAAKomD,YAAYuG,cAAc7yC,GAC/Bna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK7X,YAAYjC,KAAKyqD,SAASiB,MACpE1rD,KAAKomD,YAAYoE,cAAc1wC,GAC/B9Z,KAAKomD,YAAY+F,YAAYryC,GAC7B9Z,KAAKwsD,gBAAgB1yC,IACd,IAGPna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAAS/N,WACjE18C,KAAKomD,YAAYyF,UAAU/xC,IACpB,IAIfwG,gBAAiB,SAASxG,GACtB,GAAI4Z,GAAoB/zB,GAAG4P,KAAKvP,KAAK4sD,uBAAwB5sD,KAE7DA,MAAKmmD,QAAQ9/C,UAAUia,gBAAgB/Z,KAAKvG,KAAM8Z,EAAI4Z,IAG1Dk5B,uBAAwB,SAAS9yC,EAAIG,EAAM0Z,GACnC3zB,KAAKye,SAAS4B,WAAWwsC,aACzB7sD,KAAK8sD,mBAAmBl9C,MAAM5P,KAAM8H,WAGpC9H,KAAK+sD,mBAAmBn9C,MAAM5P,KAAM8H,YAI5C4d,kBAAmB,SAAS5L,EAAIoR,EAAKvD,GACjC3nB,KAAKmmD,QAAQ9/C,UAAUqf,kBAAkB9V,MAAM5P,KAAM8H,WAErD9H,KAAKomD,YAAYyE,YAAY/wC,GAEzB6N,GACA3nB,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAAS4B,WAAW2sC,oBAC5DhtD,KAAKomD,YAAY6F,iBAAiBnyC,IAGlC9Z,KAAK4nD,gBAAgB9tC,IAI7BizC,mBAAoB,SAASjzC,EAAIG,EAAM0Z,GACnC3zB,KAAKomD,YAAY6G,iBAAiBnzC,GAClC9Z,KAAKomD,YAAY+F,YAAYryC,GAC7B9Z,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAAS4B,WAAW6sC,oBAC5DltD,KAAK8zB,eAAeC,WAAWnkB,MAAM5P,KAAM8H,YAG/CglD,mBAAoB,SAAShzC,EAAIG,EAAMmhB,GAEnC,GAKIlsB,GALA0C,EAAW5R,KAAK4f,QAAQ9F,GACxBqzC,EAAiBntD,KAAKye,SAAS4B,WAAW8sC,eAAejrD,QAAQ,gBAAiB0P,GAElFw7C,GADOptD,KAAK6iB,QAAQ/I,GACAhS,WACpBgQ,EAAO9X,IAGXkP,GAASlP,KAAKye,SAAS4uC,YAAYF,GAE/BxtD,GAAG4W,iBAAiBrH,GACpBA,EAAOuH,KAAK,WACRqB,EAAKi1C,mBAAmBn9C,MAAMkI,EAAMs1C,KAGnCl+C,KAAW,GAChB4I,EAAKi1C,mBAAmBn9C,MAAMkI,EAAMs1C,IAI5CnC,WAAY,SAASnxC,EAAIpY,EAAM4rD,GAC3B,GAAIC,GAGA5xC,EAFA6xC,EAAe,EACfC,EAAcztD,KAAK6f,SAAS+kB,UAAU9qB,IAAO9Z,KAAKye,SAAS1I,QAAQ23C,UAGnE1tD,MAAKye,SAAS1e,QAAQ4tD,eAClB3tD,KAAK8mD,mBAAqB,GAAK9mD,KAAK+mD,uBAAyB,IAC7DyG,EAAextD,KAAK+mD,uBAAyB,GAGjDwG,GACIhzC,MAAOizC,IAIVF,IACGttD,KAAKye,SAAS+X,8BAAgC72B,GAAG8S,kBAAkBoC,eACnE7U,KAAKomD,YAAYwH,gBAMhB5tD,KAAKye,SAASjV,WACfmS,EAAS3b,KAAKoiB,YAAYtI,GAAIA,IAE9B9Z,KAAK6tD,mBAAqB7tD,KAAK6tD,oBAAsBlyC,EAAON,aAExDM,EAAON,eAAiBrb,KAAK6tD,oBAAuBlyC,EAAON,eAC3Drb,KAAK6f,SAASC,YACd9f,KAAK8tD,aACL9tD,KAAK6tD,mBAAqB,QAKlCP,GACAttD,KAAKomD,YAAY2H,eAAej0C,EAAI9Z,KAAKye,SAAS0S,eAAezvB,GAAO6rD,EAAaE,GACrFztD,KAAKomD,YAAY4H,gBAAgBl0C,EAAI9Z,KAAKmhB,eAAerH,IAAK,EAAM9Z,KAAKye,SAASwvC,WAAW/0B,iBAG7Fl5B,KAAKomD,YAAYtrC,QAAQhB,EAAI9Z,KAAKye,SAAS0S,eAAezvB,GAAO6rD,EAAaE,GAC9EztD,KAAKomD,YAAY8H,gBAAgBp0C,EAAI9Z,KAAKqhB,QAAQvH,GAAK9Z,KAAKye,SAASwvC,WAAW/0B,gBAGpFl5B,KAAK+mD,wBAA0B,GAE3BuG,GACCttD,KAAKye,SAAS1e,QAAQouD,kBAAoBxuD,GAAG8S,kBAAkBoC,gBAEhE7U,KAAKurD,iBAAiBzxC,IAI9Bg0C,WAAY,WACR9tD,KAAKomD,YAAYE,aACjBtmD,KAAKigB,oBAGTsrC,iBAAkB,SAASzxC,EAAIs0C,EAAY/R,GACvC,GAAInhC,GAAOlb,KAAKsiB,QAAQxI,GACpBu0C,EAAiBruD,KAAKktB,YAAYhS,EAElCA,IAAQ,IACWpX,SAAfsqD,GAA0CtqD,SAAdu4C,IAC5BgS,EAAiBruD,KAAKsuD,gBAAgBF,EAAY/R,IAGtDr8C,KAAKomD,YAAY9pC,WAAWxC,EAAIu0C,KAIxCC,gBAAiB,SAASC,EAAclS,GAEpC,QAASvvC,GAAEpL,EAAMkvB,GAAe7qB,EAAUA,EAAQ7D,QAAQR,EAAMkvB,GADhE,GAAI7qB,GAAU/F,KAAKye,SAASpb,KAAKmrD,cAKjC,OAFA1hD,GAAE,YAAaxL,KAAKC,MAAMgtD,EAAelS,EAAY,MACrDvvC,EAAE,eAAgB9M,KAAKktB,YAAYmvB,IAC5Bt2C,GAGX+lD,2BAA4B,SAAShyC,EAAIgY,GACrC,GAAI28B,GAAMC,EAAkBC,CAE5BF,GAAOzuD,KAAKye,SAASmwC,wBAAwBH,KAC7CC,EAAmB1uD,KAAKye,SAASmwC,wBAAwBF,iBAE5C,WAATD,GACAE,EAAgB78B,EAAS48B,GACpBC,IACDA,EAAgB3uD,KAAKye,SAASpb,KAAKwrD,YAGvC7uD,KAAKomD,YAAYoE,cAAc1wC,EAAI60C,GAE/B3uD,KAAKye,SAASmwC,wBAAwBE,eACtC9uD,KAAK+uD,aAAaj1C,EAAI60C,IAGZ,YAATF,EACLzuD,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAASpb,KAAKwrD,YAExC,SAATJ,GACLzuD,KAAK8F,IAAI,0CAA4C2oD,EAAO,iBAAkB,SAItFM,aAAc,SAASj1C,EAAIzW,GACvBrD,KAAKomD,YAAYQ,iBAAiB9sC,GAAIjC,MAAQxU,GAGlDmpD,gBAAiB,SAAS1yC,GACjB9Z,KAAKye,SAAS+X,8BAA+B72B,GAAG8S,kBAAkBoC,eACnE7U,KAAKomD,YAAYuF,WAAW7xC,IAIpC+L,WAAY,SAAS6K,EAAMhvB,EAAMuF,GAC7B,GAAIlB,GAAU/F,KAAKmmD,QAAQ9/C,UAAUwf,WAAWjW,MAAM5P,KAAM8H,UAC5D9H,MAAKye,SAASuwC,YAAYjpD,IAG9BygB,YAAa,SAASzgB,GAClB/F,KAAKmmD,QAAQ9/C,UAAUmgB,YAAY5W,MAAM5P,KAAM8H,WAC/C9H,KAAKye,SAASuwC,YAAYjpD,IAG9BkpD,kBAAmB,WACf,GAAIn3C,GAAO9X,IAEXA,MAAKye,SAASgI,UAAUyB,gBAAkB,WACtC,GAAIniB,GAAU+R,EAAK2G,SAASsJ,MAAMmnC,kBAC9BC,EAAar3C,EAAK2G,SAASsJ,MAAMpJ,WAErC,OAAO7G,GAAK2G,SAAS2wC,WAAWrpD,EAASopD,KAIjDliC,oBAAqB,SAASnT,EAAIpY,GAC9B1B,KAAK8mD,oBAAsB,EAC3B9mD,KAAKmmD,QAAQ9/C,UAAU4mB,oBAAoBrd,MAAM5P,KAAM8H,YAG3D0X,uBAAwB,SAASvV,EAAO4T,EAAQC,GAC5C9d,KAAK8mD,mBAAqB78C,EAAMvE,OAChC1F,KAAK+mD,uBAAyB,EAC9B/mD,KAAKmmD,QAAQ9/C,UAAUmZ,uBAAuB5P,MAAM5P,KAAM8H,YAG9DokD,sBAAuB,SAASvrC,GAC5B,GAAIwF,GAAenmB,KAAKmhB,eAAeR,EACtB3gB,MAAKoiB,YAAYtI,GAAI6G,IAASvG,SAE5Bza,GAAGya,OAAOqD,UACxB0I,IACDnmB,KAAKye,SAASwvC,WAAWoB,aAAaC,mBACrC3vD,GAAG8S,kBAAkBgD,eAItBzV,KAAKomD,YAAY4H,gBAAgBrtC,EAAQwF,EAAcnmB,KAAKye,SAASwvC,WAAW/0B,gBAIxF/a,eAAgB,SAAS6H,GACrB,GAAIlM,GAAK9Z,KAAKmmD,QAAQ9/C,UAAU8X,eAAevO,MAAM5P,KAAM8H,UAO3D,OALA9H,MAAKirD,WAAWnxC,EAAI9Z,KAAK4f,QAAQ9F,IAAK,GACtC9Z,KAAKomD,YAAYyE,YAAY/wC,GAC7B9Z,KAAKomD,YAAYgF,WAAWtxC,GAC5B9Z,KAAKyrD,sBAAsB3xC,GAEpBA,GAGX4S,SAAU,SAAS5S,EAAIyC,GACnBvc,KAAKmmD,QAAQ9/C,UAAUqmB,SAAS9c,MAAM5P,KAAM8H,WAE5C9H,KAAKomD,YAAY9pC,WAAWxC,EAAI9Z,KAAKktB,YAAY3Q,KAGrD4Y,wBAAyB,WACrBn1B,KAAKomD,YAAYC,gBACjBrmD,KAAKmmD,QAAQ9/C,UAAU8uB,wBAAwBvlB,MAAM5P,KAAM8H,gBC7sBvEnI,GAAG4vD,aAAe,SAAS/3C,EAAGiT,GAC1B,YAEA,IAAI3S,GAAO9X,IAKXA,MAAKmmD,QAAU17B,EAAY9qB,GAAG8qB,GAAW8L,kBAAoB52B,GAAG42B,kBAChEv2B,KAAKmmD,QAAQv2C,MAAM5P,KAAM8H,WAGzBnI,GAAG6B,OAAOxB,KAAKye,UACX7e,QAAS,KAET2jB,OAAQ,KAERisC,YAAa,KAEb/G,aACIC,kBACAqC,sBAAsB,GAG1B1nD,MACImrD,eAAgB,6BAChBK,WAAY,gBACZvD,mBAAoB,gBACpB/iB,OAAQ,UAGZknB,SAAU,cAEV1lC,SACI2gC,SAAU,qBACVhO,UAAW,sBACXjxC,QAAS,oBACTigD,KAAM,iBACNgE,SAAU,cACV7vD,KAAM,UACNsjD,WAAY,8BAGhByL,yBACIH,KAAM,UACNC,iBAAkB,QAClBI,eAAe,GAGnB/9B,UACI4+B,kBAAmB,6BACnBC,mBAAoB,kFAGxB3rC,OACIwoC,mBAAmB,EACnBC,cAAe,oCAGnBrsC,YACIwsC,cAAc,EACdM,eAAgB,8CAChBD,mBAAoB,cACpBF,mBAAoB,iBAIxBjtD,SACIouD,kBAAkB,EAClBR,cAAc,GAGlB5lC,OACI8nC,eAAe,EACfX,kBAAmB,0BAGvBjB,YACI/0B,cAAe,KACf42B,SAAU,EACVT,cACIC,mBAAmB,EACnBS,iBAAkB,KAClBC,YAAa,MAEjBC,kBAAmB,KAGvBl6C,SACI23C,YAAY,GAGhBsB,YAAa,SAASjpD,GAClB,GAAI+R,EAAKsuC,YAAY8J,UAAU,SAC3B,MAAOp4C,GAAKsuC,YAAY+J,WAAW,QAASpqD,EAG5CujB,YAAW,WACPzkB,OAAO8sB,MAAM5rB,IACd,IAIXsnD,YAAa,SAAStnD,GAClB,MAAI+R,GAAKsuC,YAAY8J,UAAU,WACpBp4C,EAAKsuC,YAAY+J,WAAW,UAAWpqD,GAGvClB,OAAOurD,QAAQrqD,IAI9BqpD,WAAY,SAASrpD,EAASsqD,GAC1B,MAAIv4C,GAAKsuC,YAAY8J,UAAU,UACpBp4C,EAAKsuC,YAAY+J,WAAW,SAAUpqD,EAASsqD,GAG/CxrD,OAAOyrD,OAAOvqD,EAASsqD,MAGvC,GAGH1wD,GAAG6B,OAAOxB,KAAKye,SAAUjH,GAAG,GAE5BxX,KAAKomD,YAAc,GAAIzmD,IAAG4wD,YACtBzqD,IAAKnG,GAAG4P,KAAKvP,KAAK8F,IAAK9F,MACvBwwD,eAAgBxwD,KAAKye,SAASgxC,SAC9BgB,YAAazwD,KAAKye,SAAS7e,QAC3B8wD,gBAAiB1wD,KAAKye,SAAS+wC,YAC/BjsC,OAAQvjB,KAAKye,SAAS8E,OACtB81B,eAAgBr5C,KAAKkhB,gBACrB6I,SACIlqB,KAAMG,KAAKye,SAASsL,QAAQlqB,KAC5B6vD,SAAU1vD,KAAKye,SAASsL,QAAQ2lC,UAEpCra,QACIsb,UAAW3wD,KAAKye,SAASwvC,WAAW6B,SACpCG,kBAAmBjwD,KAAKye,SAASwvC,WAAWgC,mBAEhDZ,cACIuB,gBAAiB5wD,KAAKye,SAASwvC,WAAWoB,aAAaC,kBACvDuB,sBAAuB7wD,KAAKye,SAASwvC,WAAWoB,aAAaU;6EAC7De,oBAAqB9wD,KAAKye,SAASwvC,WAAWoB,aAAaW,aAE/D3sD,KAAMrD,KAAKye,SAASpb,OAGpBrD,KAAKye,SAASgL,YAAYiI,mBAAqB/xB,GAAGyO,UAAYzO,GAAG2O,YACjEtO,KAAKomD,YAAY2K,cAAc/wD,KAAKye,SAASsS,SAASa,+BAEhDjyB,GAAG8S,kBAAkByD,WAAclW,KAAKye,SAAS6I,KAAK8I,WAAazwB,GAAG8S,kBAAkB0D,WAC9FnW,KAAKomD,YAAY2K,cAAc/wD,KAAKye,SAASsS,SAAS6+B,qBAGtD5vD,KAAKi2B,iBAELj2B,KAAKomD,YAAYlX,SAEjBlvC,KAAKyqD,SAAWzqD,KAAKye,SAASsL,SAEzB/pB,KAAKye,SAAS8E,QAAUvjB,KAAKomD,YAAY1kC,cAC1C1hB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKomD,YAAY1kC,YAC1B7J,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGPnZ,KAAKgnD,kCAEDrnD,GAAGmhD,aAAenhD,GAAG8S,kBAAkB6C,WACvCtV,KAAKwmD,KAAOxmD,KAAK6mD,qBAGjB7mD,KAAKye,SAASsJ,MAAMD,eAAiB9nB,KAAKye,SAASsJ,MAAM8nC,gBACrDlwD,GAAGkoB,aACH7nB,KAAKivD,oBAGLjvD,KAAK8F,IAAI,kCAAmC,UAIpD9F,KAAK8mD,mBAAqB,EAC1B9mD,KAAK+mD,uBAAyB,IAKtCpnD,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAG+d,eACxC/d,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGomB,gBAGxCpmB,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGumD,aACxCvmD,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGgoD,cC5LxChoD,GAAG4wD,WAAa,SAASx1C,GACrB,YAEA,IA4EIjV,GACAkrD,EACAC,EACAC,EACA5vC,EACAgO,EACA6hC,EACAC,EA1EAC,GACIC,QAAShoD,SAASioD,yBAClBC,QAEJC,GAAmB,EACnBC,EAAsB,EACtBC,GAA+B,EAC/BC,KACAC,GAAmB,EACnBj6C,GACI9R,IAAK,KACLuvC,QACIsb,UAAW,EACXV,kBAAmB,KAEvBO,eAAgB,cAChBC,YAAa,KACbC,gBAAiB,KACjBntC,OAAQ,KACR81B,eAAgB,KAChBtvB,SACIlqB,KAAM,UACN6vD,SAAU,eAEdL,cACIuB,iBAAiB,EACjBC,sBAAuB,KACvBC,oBAAqB,MAEzBztD,MACIklC,OAAQ,WAGhBupB,GACIvuC,OAAQ,4BACRwuC,YAAa,2BACbC,mBAAoB,4BACpBC,cAAe,6BACfC,cAAe,6BACfC,eAAgB,wBAChBC,aAAc,4BACdC,SAAU,uBACVC,KAAM,+BACNC,KAAM,0BACNC,qBAAsB,qCACtB38C,YAAa,2BACb48C,0BAA2B,2CAC3BC,iBAAkB,iCAClBv3C,KAAM,0BACNw3C,QAAS,6BACTz3C,KAAM,0BACNuE,OAAQ,4BACR7J,MAAO,2BACPg9C,eAAgB,8BAChBC,aAAc,4BACd5uC,MAAO,2BACP6uC,WAAY,iCACZC,kBAAmB,4BACnBC,aAAc,iCACdC,SAAU,oCACVC,eAAgB,8BAChBC,sBAAuB,sCACvBC,UAAW,yBAEfC,KACAC,EAAiC,GAAI3zD,IAAG4L,QACxCgoD,EAA+B,GAAI5zD,IAAG4L,QAatCioD,EAA6B,WACzB,GAAIC,GAAmB77C,EAAQy3C,aAAawB,sBACxC6C,EAAa97C,EAAQy3C,aAAayB,oBAClC/1C,GACI8F,QAASgxC,EACTzwC,MAAOgwC,EAGXD,KACIsC,EACA77C,EAAQyhC,eAAe93B,SAASkyC,EAAiB,GAAI9kB,OAAS5zB,GAAMtE,KAChE,SAASk9C,GACLL,EAA+B7nD,QAAQkoD,IAE3C,WACIL,EAA+B3nD,UAC/B7F,EAAI,wDAA0D2tD,EAAiB,WAKvFH,EAA+B3nD,UAG/B+nD,EACA97C,EAAQyhC,eAAe93B,SAASmyC,EAAY,GAAI/kB,OAAS5zB,GAAMtE,KAC3D,SAASk9C,GACLJ,EAA6B9nD,QAAQkoD,IAEzC,WACIJ,EAA6B5nD,UAC7B7F,EAAI,gEAAkE4tD,EAAY,WAK1FH,EAA6B5nD,YAOzCioD,EAAoB,SAASR,GACzB,GAAIS,GAAsB,GAAIl0D,IAAG4L,OAwBjC,OAtBAgoD,GAA6B98C,KAAK,SAASy0B,GACvC4oB,EAA4B5oB,EAAKkoB,GAE5BA,EAAUrkB,IASX8kB,EAAoBpoD,WARpB2nD,EAAUrkB,IAAM7D,EAAI6D,IACpBqkB,EAAU5nD,OAAS,WACf4nD,EAAU5nD,OAAS,KACnBuoD,EAAKX,GACLS,EAAoBpoD,aAM7B,WAIC5L,EAAKuzD,GACLS,EAAoBpoD,YAGjBooD,GAGXG,EAAqB,SAASl6C,EAAI7O,EAAM8P,GACpC,GAAIq4C,GAAYa,EAAan6C,EAK7B,OAHAhU,GAAI,gCAAkCgU,GACtC7O,EAAKipD,cAAgBp6C,EAEdlC,EAAQyhC,eAAe93B,SAAStW,EAAMmoD,EAAWr4C,GAAMtE,KAC1D,WACIi7C,IACAqC,EAAKX,GACLC,EAAkBv5C,GAAIrO,WAE1B,WACI4nD,EAAkBv5C,GAAInO,UAIjBiM,EAAQy3C,aAAauB,iBACtBuD,EAA+Br6C,EAAIs5C,MAKnDgB,EAA4B,WACxB,GAAIxC,EAAqBlsD,OAAQ,CAC7BisD,GAA+B,CAE/B,IAAI0C,GAAqBzC,EAAqB3/C,OAE1CoiD,GAAmBC,OACnBC,EAAkCF,GAGlCG,EAA+BH,OAInC1C,IAA+B,GAIvC8C,EAAY,SAAS36C,GACjB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBryC,SAGtDk1C,EAAc,SAAS76C,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBc,iBAGtDgC,EAAY,SAAS10D,GACjB,MAAOw0D,GAAcpzC,EAAWwwC,EAAgB5xD,EAAO,YAG3D20D,EAAY,SAAS/6C,GACjB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBe,eAGtDiC,EAAoB,WAChB,MAAOJ,GAAcpzC,EAAWwwC,EAAgBoB,iBAGpD6B,EAAc,SAASj7C,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBkB,eAGtD3xC,EAAU,SAASvH,GACf,MAAOu3C,GAAUG,IAAI13C,IAAOna,GAAG2vB,GAAUxsB,gBAhOzB,cAgO6DgX,IAGjFpI,EAAc,SAASoI,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB32C,OAGtD65C,EAAW,SAASl7C,GAChB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBl8C,QAGtDq/C,EAAc,SAASn7C,GAGnB,MAAU,OAANA,EACO46C,EAAcpzC,EAAWwwC,EAAgBW,4BAC5CiC,EAAcpzC,EAAWwwC,EAAgBY,kBAI1CgC,EAAcrzC,EAAQvH,GAAKg4C,EAAgBU,uBAC9CkC,EAAcrzC,EAAQvH,GAAKg4C,EAAgBj8C,cAGnDq/C,EAAW,SAASp7C,GAChB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB7tC,QAGtD3B,EAAU,SAASxI,GACf,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB52C,OAGtDi6C,EAAa,SAASr7C,GAClB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBa,UAGtD+B,EAAgB,SAASjlD,EAAS2lD,GAC9B,MAAO3lD,IAAW9P,GAAG8P,GAAS3M,gBAAgBsyD,IAGlDnB,EAAe,SAASn6C,GACpB,MAAOq3C,IAAkBuD,EAAcrzC,EAAQvH,GAAKg4C,EAAgBsB,YAGxEvzD,EAAO,SAAS8vC,GACZA,GAAMhwC,GAAGgwC,GAAI3tC,SAAS4V,EAAQmS,QAAQlqB,OAM1Ci0D,EAA8B,SAASxiC,EAAa8hC,GAChD,GAAIn8B,GAAW3F,EAAYxxB,MAAMm3B,SAC7BD,EAAY1F,EAAYxxB,MAAMk3B,SAE9BA,IAAaC,IAAam8B,EAAUtzD,MAAMm3B,WAAam8B,EAAUtzD,MAAMk3B,WACvEr3B,GAAGyzD,GAAWnyD,KACVg2B,SAAUA,EACVD,UAAWA,KAQvBm9B,EAAiC,SAASr6C,EAAIs5C,GAC1C,GAAIiC,GAAahC,EAAkBv5C,KAAO,GAAIna,IAAG4L,SAAUI,UACvD2pD,EAA2B,GAAI31D,IAAG4L,OAqBtC,OAnBA+nD,GAA+B78C,KAAK,SAASy0B,GACzCmqB,EAAW5+C,KACP,WACI6+C,EAAyB7pD,WAE7B,WACIqoD,EAA4B5oB,EAAKkoB,GAEjCA,EAAU5nD,OAAS,WACf4nD,EAAU5nD,OAAS,KACnB8pD,EAAyB7pD,WAG7B2nD,EAAUrkB,IAAM7D,EAAI6D,IACpBglB,EAAKX,OAKVkC,GAWXC,EAAsB,WAClB,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACA/S,EACAsQ,EACAF,EACA4C,EACAC,CAKJ,IAHAjwD,EAAI,oBAG0B,MAA1B8R,EAAQ44C,eACR,KAAM,IAAIrvD,OAAM,oDAIpB,IAAIxB,GAAGwH,SAASyQ,EAAQ44C,gBAAiB,CAGrC,GAFAgF,EAAWlsD,SAASs8B,eAAehuB,EAAQ44C,gBAE1B,OAAbgF,EACA,KAAM,IAAIr0D,OAAMxB,GAAG8H,OAAO,0CAA2CmQ,EAAQ44C,gBAGjFiF,GAAaD,EAAS1mD,cAErB,CACD,GAAyChL,SAArC8T,EAAQ44C,eAAe1hD,UACvB,KAAM,IAAI3N,OAAM,gGAIpBs0D,GAAa79C,EAAQ44C,eAAe1hD,UA4ExC,GAzEA2mD,EAAa91D,GAAG0H,QAAQouD,GACxBE,EAAiBrsD,SAASC,cAAc,OACxCosD,EAAe5kD,YAAYpR,GAAGgP,UAAU8mD,IACxCM,EAAap2D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBO,UAI5Dz6C,EAAQ2L,SACRsyC,EAAgBl2D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBvuC,QAC/DsyC,GACAl2D,GAAGk2D,GAAe90D,UASrBpB,GAAGmhD,aAAgBnhD,GAAG8S,kBAAkB6C,WACzC49C,EAAiBvzD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBoB,gBAChEA,GACAvzD,GAAGuzD,GAAgBnyD,UAI3B+hD,EAAWnjD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBQ,MAI1DxP,IAAanjD,GAAGmhD,cAChBh7C,EAAI,0BAA2B,QAC/BnG,GAAGmjD,GAAU/hD,UAGZpB,GAAG8S,kBAAkB6C,SAajB3V,GAAGo2D,GAAYtyD,aAtZN,sBAsZ2Cq/C,IACzDgT,EAAan2D,GAAGmjD,GAAUhgD,gBAAgBgvD,EAAgBmB,UAC1D6C,GAAcn2D,GAAGm2D,GAAY/0D,WAb7Bg1D,EAAWz8C,gBA3YG,qBA6YVwpC,GAAYnjD,GAAGmjD,GAAUr/C,aA9YhB,qBAkZT9D,GAAGmjD,GAAU7hD,KACTlB,QAAS,UAWrBqzD,EAAYzzD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBsB,WAC1DjC,EAGIiC,IACLvB,EAAmB5uB,SAASmwB,EAAUvvD,aAtapB,gBAwalBguD,EAAmBA,EAAmB,EAAIA,EAAmB,KAE7DT,EAAczxD,GAAGyzD,GAAW3vD,aAzaN,oBAkatB2vD,GAAazzD,GAAGyzD,GAAWryD,SAS/BowD,EAAiBA,GAAkBiC,EAEnCpC,EAAsBrxD,GAAGg2D,GAAgBxzD,WAAW2vD,EAAgBiB,mBAAmBrtD,OAAS,EAChGurD,EAAsBtxD,GAAGg2D,GAAgBxzD,WAAW2vD,EAAgB7tC,OAAOve,OAAS,EAEpFgwD,EAAe/1D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBS,MAE9C,MAAhBmD,EACA,KAAM,IAAIv0D,OAAM,0DAapB,OAVAy0D,GAAaF,EAAa3yD,SAAS,GAAGizD,WAAU,GAChDN,EAAa5mD,UAAY,GAGrB6mD,EAAelzD,qBAAqB,UAAUiD,QAC9C4D,SAASC,cAAc,UAG3BzD,EAAI,8BAGA2pD,SAAUkG,EACVM,aAAcL,IAItBM,EAAc,SAASvmB,EAAIp1B,EAAO+U,GAC9B,GAAI6mC,GAAW7mC,EACX8mC,EAAWD,EAASlzD,UAEpBsX,GAAQ,IACR67C,EAAWz2D,GAAGw2D,GAAUpzD,WAAWwX,GAAOpX,aAI9CgzD,EAASv1D,aAAa+uC,EAAIymB,IAG9B5B,EAAiC,SAASH,GACtC,GAAIv6C,GAAKu6C,EAAmBv6C,GACxBu8C,EAAgBhC,EAAmBgC,cACnCC,EAAqBD,GAAiBA,EAAcnC,cACpDd,EAAYa,EAAan6C,GACzBiB,GACIgG,qBAAsBszC,EAAmBtzC,qBACzCF,QAASgxC,EACTz4B,QAAQ,EACRhY,OAAO,EAGXzhB,IAAG8S,kBAAkBgD,cACjB29C,EACIx7C,EAAQy9B,OAAOsb,WAAa/4C,EAAQy9B,OAAOsb,WAAae,GACxDyC,EAA+Br6C,EAAIs5C,GACnCgB,KAGAR,EAAkBR,GAAWl8C,KAAK,WAC9Bm8C,EAAkBv5C,GAAM,GAAIna,IAAG4L,QAE/B8nD,EAAkBv5C,GAAI5C,KAAK,WACvBoS,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,qBAM/B,MAAtBqG,EACAC,EAAiBz8C,EAAIw8C,GAGrBtC,EAAmBl6C,EAAIu8C,EAAet7C,KAOlDq5C,IAGChB,IACLQ,EAAkBR,GAClBgB,MAIRG,EAAoC,SAASF,GACzC,GAAIv6C,GAAKu6C,EAAmBv6C,GACxBqM,EAAekuC,EAAmBluC,aAClCqwC,EAAiBnC,EAAmBmC,eACpCpD,EAAYa,EAAan6C,GACzBiB,GACIgG,qBAAsBszC,EAAmBtzC,qBACzCK,MAAOgwC,EACPvwC,QAASgxC,EAGjB,IAAIuB,EACA,GAAIjtC,EAAc,CACd,KAAIvO,EAAQy9B,OAAOsb,WAAa/4C,EAAQy9B,OAAOsb,WAAae,GASxD,MAJI8E,IACA5C,EAAkBR,GAGfx7C,EAAQyhC,eAAe93B,SAAS4E,EAAcitC,EAAWr4C,GAAMtE,KAClE,WACIs9C,EAAKX,GACL1B,IACApoC,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,oBAGzD,WACIkE,EAA+Br6C,EAAIs5C,GACnC9pC,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,oBAjB7DkE,GAA+Br6C,EAAIs5C,GACnCgB,QAsBJD,GAA+Br6C,EAAIs5C,GACnCgB,KAKZqC,EAAsB,SAAS38C,EAAI48C,GAC/B,GAAIC,GAAM1B,EAAYn7C,GAElB88C,EAA4B,MAAN98C,EAAag4C,EAAgBY,iBAAmBZ,EAAgBj8C,WAEtF8gD,KAAQh3D,GAAGg3D,GAAKl1D,SAASm1D,KACzBD,EAAMh3D,GAAGg3D,GAAK7zD,gBAAgB8zD,IAG9BD,IACAh3D,GAAGg3D,GAAK11D,KAAKuqC,MAAOkrB,EAAU,MAC9BC,EAAI7lD,aAAa,gBAAiB4lD,KAI1C3C,EAAO,SAASpkB,GACZA,GAAMhwC,GAAGgwC,GAAI1tC,YAAY2V,EAAQmS,QAAQlqB,OAG7C02D,EAAmB,SAASM,EAAmBC,GAC3C,GAAIC,GAAkB9C,EAAa4C,GAC/BG,EAAkB/C,EAAa6C,EAEnChxD,GAAInG,GAAG8H,OAAO,qFAAsFovD,EAAmBC,EAAmBA,IAG1IzD,EAAkByD,GAAmBrgD,KAAK,WACtCi7C,IACA2B,EAAkBwD,GAAmBprD,UACrC3F,EAAInG,GAAG8H,OAAO,uEAAwEqvD,EAAmBD,IACzGE,EAAgBhoB,IAAMioB,EAAgBjoB,IACtCglB,EAAKgD,IAET,WACI1D,EAAkBwD,GAAmBlrD,UAChCiM,EAAQy3C,aAAauB,iBACtBuD,EAA+B0C,EAAmBE,KAKlEp3D,IAAG6B,OAAOoW,EAASmD,GACnBjV,EAAM8R,EAAQ9R,IAITnG,GAAG8S,kBAAkBgD,gBACtBmC,EAAQy9B,OAAO4a,kBAAoB,EACnCr4C,EAAQy9B,OAAOsb,UAAY,GAG/BrvC,EAAY1J,EAAQ64C,YACpBU,EAA4CrtD,SAA3B8T,EAAQyhC,eACzB6X,EAAcqE,IAEd/B,IAEA7zD,GAAG6B,OAAOxB,MACNkvC,OAAQ,WACJppC,EAAI,8BAEJ4rD,EAAsB,EAEtBpwC,EAAUvQ,YAAYmgD,EAAYzB,SAASuG,WAAU,IACrDn2D,EAAKi1D,KACL90D,KAAKi3D,oBACL3nC,EAAW1X,EAAQ84C,iBAAmBgE,EAAcpzC,EAAWwwC,EAAgBS,MAE/EzsD,EAAI,gCAGRirD,cAAe,SAAShrD,GACpB,GAAImxD,GAAev3D,GAAGgP,UAAU5I,EAChCub,GAAUxS,UAAY,GACtBwS,EAAUvQ,YAAYmmD,IAG1B19C,MAAO,WACH8H,EAAUxS,UAAY,GACtB9O,KAAKkvC,UAGToX,WAAY,WACRh3B,EAASxgB,UAAY,IAGzB8+C,cAAe,WACX6D,GAAmB,GAGvB32C,QAAS,SAAShB,EAAIpY,EAAMy1D,EAAaC,EAAaC,GAClD,GAIIC,GAJAC,EAASrG,EAAY+E,aAAaD,WAAU,GAC5CwB,EAAa9C,EAAc6C,EAAQzF,EAAgB32C,MACnD46C,EAAarB,EAAcpzC,EAAWwwC,EAAgBO,UACtD9yC,EAAgB83C,EAAQhG,EAAUC,QAAUhiC,CAG5C+nC,KACAhG,EAAUG,IAAI13C,GAAMy9C,GAGxB53D,GAAG43D,GAAQv1D,SArpBK,cAqpBwB8X,GACxCi8C,EAAWz8C,gBAjpBO,qBAmpBdk+C,IACA73D,GAAG63D,GAAYp0D,QAAQ1B,GACvB81D,EAAW1mD,aAAa,QAASpP,IAGrC61D,EAAOzmD,aA9pBI,aA8pBuBgJ,GAE9Bq9C,EACAjB,EAAYqB,EAAQJ,EAAY58C,MAAOgF,GAGvCA,EAAcxO,YAAYwmD,GAG1BH,GACAG,EAAOz3D,MAAMC,QAAU,OACvBJ,GAAG43D,GAAQv1D,SAjqBI,uBAoqBfnC,EAAKo1D,EAAYn7C,IACjBja,EAAKyiB,EAAQxI,IACbja,EAAKg1D,EAAU/6C,IACfja,EAAKq1D,EAASp7C,IACdja,EAAKm1D,EAASl7C,IACdja,EAAK80D,EAAY76C,IAEb23C,GACAzxD,KAAKorD,WAAWtxC,GAGpBw9C,EAAQrD,EAAan6C,GACjBw9C,IAAUA,EAAMvoB,KAChBwkB,EAA6B98C,KAAK,SAASghD,GACvCH,EAAMvoB,IAAM0oB,EAAW1oB,IACnB0oB,EAAW33D,MAAMk3B,WAAaygC,EAAW33D,MAAMm3B,UAC/Ct3B,GAAG23D,GAAOr2D,KACN+1B,UAAWygC,EAAW33D,MAAMk3B,UAC5BC,SAAUwgC,EAAW33D,MAAMm3B,WAInC88B,EAAKuD,OAMrBvJ,eAAgB,SAASj0C,EAAIpY,EAAMy1D,EAAaC,GAC5Cp3D,KAAK8a,QAAQhB,EAAIpY,EAAMy1D,EAAaC,GAAa,IAGrD/Q,cAAe,WACX/2B,EAASve,YAAYsgD,EAAUC,SAC/BD,EAAUC,QAAUhoD,SAASioD,yBAC7BF,EAAUG,QAGd3J,WAAY,SAAS/tC,GACjBna,GAAG0hB,EAAQvH,IAAK/Y,UAGpBymD,UAAW,SAAS7X,GAChB,GAAI+nB,GAAc/nB,CAElB,IAAI+nB,EAAa,CAEb,KAAiD,MAA1CA,EAAY7zD,aA3tBZ,eA4tBH6zD,EAAcA,EAAY52D,UAG9B,OAAOmiC,UAASy0B,EAAY7zD,aA/tBrB,iBAmuBf8zD,YAAa,WACT,MAAOroC,IAGXg7B,qBAAsB,SAASxwC,GAC3B,GAAIxI,GAAWI,EAAYoI,EAE3BxI,IAAY3R,GAAG2R,GAAUtP,SAAS4V,EAAQmS,QAAQ2lC,WAGtDxI,eAAgB,SAASptC,EAAIpY,GACzB,GAAIk2D,GAAalmD,EAAYoI,EAEzB89C,KACAj4D,GAAGi4D,GAAYx0D,QAAQ1B,GACvBk2D,EAAW9mD,aAAa,QAASpP,KAIzCwoD,aAAc,SAASpwC,GACnBja,EAAK6R,EAAYoI,KAGrBswC,aAAc,SAAStwC,GACnBi6C,EAAKriD,EAAYoI,KAGrB+9C,WAAY,SAASloB,GACjB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgB32C,OAG3CuG,UAAW,WACP,MAAO9J,GAAQ2L,QAAUmxC,EAAcpzC,EAAWwwC,EAAgBvuC,SAGtEwlC,mBAAoB,WAChBlpD,EAAKi1D,MAGThM,mBAAoB,WAChBiL,EAAKe,MAGTjM,YAAa,WACT,MAAO6L,GAAcpzC,EAAWwwC,EAAgBQ,OAGpD/I,uBAAwB,WACpB,MAAOyH,IAGXzG,UAAW,SAASzwC,GAChBja,EAAKq1D,EAASp7C,KAGlB8xC,gBAAiB,WACb,MAAOqF,IAGXpF,UAAW,SAAS/xC,GAChBi6C,EAAKmB,EAASp7C,KAGlB8sC,iBAAkB,SAAS9sC,GACvB,MAAOuH,GAAQvH,IAGnBuwC,aAAc,SAASvwC,GACnB,GAAIg+C,GAAO/C,EAAYj7C,EAEvBg+C,IAAQn4D,GAAGm4D,GAAM91D,SAAS4V,EAAQmS,QAAQ2lC,WAG9C/I,gBAAiB,SAAS7sC,GACtB,MAAOna,IAAG0hB,EAAQvH,IAAKrY,SAryBJ,sBAwyBvB0oD,aAAc,SAASrwC,GACnB,GAAIg+C,GAAO/C,EAAYj7C,EAEvBg+C,IAAQn4D,GAAGm4D,GAAM71D,YAAY2V,EAAQmS,QAAQ2lC,WAGjDqI,WAAY,SAASpoB,GACjB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBkB,cAAc,IAGzDhJ,aAAc,SAASlwC,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBiB,oBAGtDiF,YAAa,SAASroB,GAClB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBiB,mBAAmB,IAG9D5H,eAAgB,SAASrxC,EAAIgR,EAAQC,GACjC,GACI2rC,GADAC,EAAM1B,EAAYn7C,EAGlB68C,IAAO5rC,EAAQ,IACf2rC,EAAUp1D,KAAKC,MAAMupB,EAASC,EAAQ,KAEtB,MAAZ2rC,EACA72D,EAAK82D,GAGL5C,EAAK4C,GAGTF,EAAoB38C,EAAI48C,KAIhC7Z,oBAAqB,SAAS/xB,EAAQC,GAClC/qB,KAAKmrD,eAAe,KAAMrgC,EAAQC,IAGtCsgC,aAAc,SAASvxC,GACnB,GAAI68C,GAAM1B,EAAYn7C,EAEtB68C,IAAO92D,EAAK82D,IAGhBM,kBAAmB,WACfj3D,KAAKqrD,gBAGTsB,cAAe,SAAS7yC,GACpB28C,EAAoB38C,EAAI,GACxB9Z,KAAKi3D,kBAAkBn9C,IAG3BgxC,mBAAoB,WAChB9qD,KAAK2sD,iBAGThB,WAAY,SAAS7xC,GACjB,IAAK23C,EAAkB,CACnB,GAAIhyC,GAASg1C,EAAU36C,EAEvB2F,IAAU9f,GAAG8f,GAAQxd,YAAY2V,EAAQmS,QAAQlqB,QAIzDurD,WAAY,SAAStxC,GACjBja,EAAK40D,EAAU36C,KAGnBm+C,SAAU,SAAStoB,GACf,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBryC,QAAQ,IAGnD2sC,WAAY,SAAStyC,GACjBi6C,EAAKiB,EAASl7C,IACdja,EAAK80D,EAAY76C,KAGrBqtC,aAAc,SAASrtC,GACnB9Z,KAAKwqD,cAAc1wC,EAAIlC,EAAQvU,KAAKklC,QACpCvoC,KAAKk4D,oBAAoBp+C,GACzBja,EAAKs1D,EAAWr7C,KAGpB6wC,UAAW,SAAS7wC,GAChBja,EAAKm1D,EAASl7C,KAGlBq+C,QAAS,SAASxoB,GACd,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBl8C,OAAO,IAGlDwiD,iBAAkB,SAASzoB,GACvB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBc,gBAAgB,IAG3DsF,oBAAqB,SAASp+C,GAC1Bi6C,EAAKY,EAAY76C,IACjBja,EAAKm1D,EAASl7C,KAGlButC,gBAAiB,SAASvtC,GACtB9Z,KAAKwqD,cAAc1wC,EAAI,IACvB9Z,KAAKosD,WAAWtyC,GAChBi6C,EAAKoB,EAAWr7C,KAGpBmyC,iBAAkB,SAASnyC,GACvBi6C,EAAKc,EAAU/6C,KAGnBmzC,iBAAkB,SAASnzC,GACvBja,EAAKg1D,EAAU/6C,KAGnBu+C,eAAgB,SAAS1oB,GACrB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBe,cAAc,IAGzDyF,QAAS,SAAS3oB,GACd,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgB7tC,OAAO,IAGlD3H,WAAY,SAASxC,EAAIzW,GACrB,GAAI6X,GAAOoH,EAAQxI,EAEfoB,KACA64C,EAAK74C,GACLvb,GAAGub,GAAM9X,QAAQC,KAIzBmnD,cAAe,SAAS1wC,EAAIzW,GACxB,GAAIk1D,GAAS7D,EAAcrzC,EAAQvH,GAAKg4C,EAAgBgB,WAEpDyF,KAEY,MAARl1D,EACA1D,GAAG44D,GAAQ/0D,YAGX7D,GAAG44D,GAAQn1D,QAAQC,KAK/BwnD,YAAa,SAAS/wC,GAClBna,GAAG0hB,EAAQvH,IAAK7X,YA97BA,kBA+7BhBpC,EAAKs1D,EAAWr7C,KAGpBqyC,YAAa,SAASryC,GAClBna,GAAG0hB,EAAQvH,IAAK9X,SAn8BA,kBAo8BhB+xD,EAAKoB,EAAWr7C,KAGpBo0C,gBAAiB,SAASp0C,EAAIu8C,EAAet1C,GACpC/gB,KAAK2mD,gBAAgB7sC,KACtB83C,EAAqB/uD,MAAMiX,GAAIA,EAAIiH,qBAAsBA,EAAsBs1C,cAAeA,KAC7F1E,GAAgCyC,MAIzCpG,gBAAiB,SAASl0C,EAAIqM,EAAcqwC,EAAgBz1C,GACnD/gB,KAAK2mD,gBAAgB7sC,KACtB83C,EAAqB/uD,MAAMke,qBAAsBA,EAAsBuzC,QAAQ,EAAMx6C,GAAIA,EAAIqM,aAAcA,EAAcqwC,eAAgBA,KACxI7E,GAAgCyC,MAIzClE,UAAW,SAAShwD,GAChB,MAAOP,IAAG8S,kBAAkB2C,iBAAmBw/C,EAAU10D,IAG7DiwD,WAAY,SAASjwD,EAAM6F,EAASsqD,GAChC,GAAImI,GAAS5D,EAAU10D,GACnBu4D,EAAY/D,EAAc8D,EAAQ1G,EAAgBI,eAClDwG,EAAUF,EAAO/1D,qBAAqB,SAAS,GAC/Ck2D,EAAYjE,EAAc8D,EAAQ1G,EAAgBE,oBAClD4G,EAAQlE,EAAc8D,EAAQ1G,EAAgBK,gBAC9C7mD,EAAU,GAAI3L,IAAG4L,QAEjBstD,EAAe,WACXF,EAAUp4D,oBAAoB,QAASu4D,GACvCF,GAASA,EAAMr4D,oBAAoB,QAASw4D,GAC5CztD,EAAQK,WAGZmtD,EAAqB,WACjBH,EAAUp4D,oBAAoB,QAASu4D,GACvCN,EAAOQ,SAGXD,EAAiB,WACbP,EAAOj4D,oBAAoB,QAASs4D,GACpCD,EAAMr4D,oBAAoB,QAASw4D,GACnCP,EAAOQ,QAEP1tD,EAAQG,QAAQitD,GAAWA,EAAQhyD,OAc3C,OAXA8xD,GAAOp4D,iBAAiB,QAASy4D,GACjCF,EAAUv4D,iBAAiB,QAAS04D,GACpCF,GAASA,EAAMx4D,iBAAiB,QAAS24D,GAErCL,IACAA,EAAQhyD,MAAQ2pD,GAEpBoI,EAAUl1D,YAAcwC,EAExByyD,EAAOS,YAEA3tD,MChhCnB3L,GAAGu5D,eAAiB,SAASC,EAAGC,GAC5B,YAqBA,SAASlO,GAAWtrD,GAChBoS,EAAS/R,OAAOL,EAASmb,EAAKs+C,UAAW,SAASxkC,GAE9CA,EAAQA,GAAShwB,OAAOgwB,KAGxB,IAAI5oB,GAAS4oB,EAAM5oB,QAAU4oB,EAAMykC,UAEnCv+C,GAAKw+C,UAAUttD,EAAQ4oB,KA3B/B,GAAI7iB,GAAW,GAAIrS,IAAGkS,eAClBkJ,GACIs+C,UAAW,QACXG,SAAU,KACVD,UAAW,SAASttD,EAAQ4oB,KAKpCl1B,IAAG6B,OAAOxB,MACNkrD,WAAY,SAAStrD,GACjBsrD,EAAWtrD,IAGfmS,QAAS,WACLC,EAASD,aAiBjBpS,GAAG6B,OAAO43D,GACNK,kBAAmB,SAASxyD,GACxB,MAAOA,GAAKyyD,UAGhBC,kBAAmB,WACf,MAAO3nD,MAIfrS,GAAG6B,OAAOuZ,EAAMo+C,GAEZp+C,EAAKy+C,UACLtO,EAAWnwC,EAAKy+C,WClDxB75D,GAAGooD,wBAA0B,SAASoR,GAClC,YAqBA,SAASS,GAAa3tD,EAAQ4oB,GAC1Bl1B,GAAG+C,KAAKm3D,EAAgB,SAASC,EAAY7qC,GACzC,GACItO,GADAo5C,EAA2BD,EAAWxqD,OAAO,GAAGwX,cAAgBgzC,EAAWjyD,MAAM,EAGrF,IAAIkT,EAAK4tC,WAAW,KAAOoR,GAA0B9tD,GAKjD,MAJA0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,GACnCtM,GAAG6O,eAAeqmB,GAClB9Z,EAAKjV,IAAInG,GAAG8H,OAAO,+DAAgEsT,EAAKuuC,UAAU3oC,GAASA,IAC3GsO,EAAQtO,IACD,IA7BnB,GAAIq5C,MACAj/C,GACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBC,aAAc,SAASvoC,KACvByK,SAAU,SAASzK,KACnBwoC,QAAS,SAASxoC,KAClByoC,QAAS,SAASzoC,KAClB0oC,WAAY,SAAS1oC,KACrB2oC,UAAW,SAAS3oC,MAExBk5C,GACIp6C,OAAQ,SAAS3F,GAAMiB,EAAKqQ,SAAStR,IACrCmK,MAAQ,SAASnK,GAAMiB,EAAKouC,QAAQrvC,IACpC+4C,aAAc,SAAS/4C,GAAMiB,EAAKmuC,aAAapvC,IAC/ClE,MAAO,SAASkE,GAAMiB,EAAKquC,QAAQtvC,IACnC84C,eAAgB,SAAS94C,GAAMiB,EAAKsuC,WAAWvvC,IAkBvDna,IAAG6B,OAAOuZ,EAAMo+C,GAEhBp+C,EAAKs+C,UAAY,QACjBt+C,EAAKw+C,UAAYK,EACjB7+C,EAAKy+C,SAAWz+C,EAAK4tC,WAAWgP,cAEhCh4D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu5D,eAAen+C,EAAMi/C,KC1ChDr6D,GAAG6pD,qBAAuB,SAAS2P,GAC/B,YAiBA,SAASS,GAAa3tD,EAAQ4oB,GAC1B,GAAI9Z,EAAK4tC,WAAWkP,WAAW5rD,IAAW8O,EAAK4tC,WAAWoP,WAAW9rD,GAAS,CAC1E,GAAI0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,EAC1B8O,GAAK4uC,kBAAkBhpC,KAGrBhhB,GAAGya,OAAOyC,YACrB9B,EAAKjV,IAAInG,GAAG8H,OAAO,4DAA6DsT,EAAKuuC,UAAU3oC,GAASA,IACxGhhB,GAAG6O,eAAeqmB,GAElBmlC,EAAqBC,mBAAmBt5C,EAAQ1U,GAAQ,KAzBpE,GAAI+tD,MACAj/C,GACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBl/B,SACI5O,KAAM,iBACN63C,aAAc,yBAElBrJ,kBAAmB,SAAShpC,KAC5B2oC,UAAW,SAAS3oC,KAG5BhhB,IAAG6B,OAAOuZ,EAAMo+C,GAkBhBp+C,EAAKs+C,UAAY,QACjBt+C,EAAKw+C,UAAYK,EAEjBj6D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu6D,oBAAoBn/C,EAAMi/C,KCpCrDr6D,GAAGirD,4BAA8B,SAASuO,EAAGa,GACzC,YAaA,SAASG,GAAiBluD,EAAQ4oB,GAC9B,GAAI9Z,EAAK4tC,WAAWqP,YAAY/rD,GAAS,CACrC,GAAI0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,EAC1B8O,GAAK4uC,kBAAkBhpC,KAErBhhB,GAAGya,OAAOyC,YACrB9B,EAAKjV,IAAInG,GAAG8H,OAAO,kEAAmEsT,EAAKuuC,UAAU3oC,GAASA,IAC9Gq5C,EAAqBC,mBAAmBt5C,EAAQ1U,KAlB5D,GAAI8O,IACI4tC,WAAY,KACZgB,kBAAmB,SAAShpC,KAC5B7a,IAAK,SAASC,EAASkjD,KAG1B+Q,KACDA,MAgBJj/C,EAAKs+C,UAAY,UACjBt+C,EAAKw+C,UAAYY,EAEjBx6D,GAAG6B,OAAOuZ,EAAMo+C,GAChBx5D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu6D,oBAAoBn/C,EAAMi/C,KCzBrDr6D,GAAG8pD,0BAA4B,SAAS1uC,GACpC,YAEAA,GAAKs+C,UAAY,QACjBt+C,EAAKy+C,SAAW,KAEhB75D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGirD,4BAA4B7vC,QCVvDpb,GAAGu6D,oBAAsB,SAASf,EAAGa,GACjC,YAWA,SAASI,GAAyBz5C,GAC9B,GAAI05C,GAAkBt/C,EAAKuuC,UAAU3oC,GACjCpP,EAAS8oD,EAAgB7oD,YAAY,IAMzC,OAJID,GAAS,IACT8oD,EAAkBA,EAAgB5oD,OAAO,EAAGF,IAGzC8oD,EAGX,QAASC,GAAqB35C,GAC1B,GAAI45C,GAAWx/C,EAAKuuC,UAAU3oC,EAC9B,OAAOhhB,IAAG0R,aAAakpD,GAI3B,QAASC,GAAiBC,EAAoB95C,GAC1C,GACI+5C,GADAr+C,EAAUo+C,EAAmB/zD,KAGjB5C,UAAZuY,GAAyB1c,GAAG0H,QAAQgV,GAAS3W,OAAS,IACtDg1D,EAAgBJ,EAAqB35C,GAEf7c,SAAlB42D,IACAr+C,EAAUA,EAAU,IAAMq+C,GAG9B3/C,EAAK6uC,UAAUjpC,EAAQtE,IAG3BtB,EAAK8uC,sBAAsBlpC,GAAQ,GAIvC,QAASg6C,GAAyBjC,EAAS/3C,GACvCq5C,EAAqBL,oBAAoB15D,OAAOy4D,EAAS,OAAQ,WAC7D8B,EAAiB9B,EAAS/3C,KAKlC,QAASi6C,GAA6BlC,EAAS/3C,GAC3Cq5C,EAAqBL,oBAAoB15D,OAAOy4D,EAAS,QAAS,SAAS7jC,GAI1D,MAFFA,EAAMgmC,SAAWhmC,EAAMimC,QAG9BN,EAAiB9B,EAAS/3C,KAzDtC,GAAI5F,IACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBU,kBAAmB,SAAShpC,KAC5B2oC,UAAW,SAAS3oC,KACpBipC,UAAW,SAASjpC,EAAQtE,KAC5BwtC,sBAAuB,SAASlpC,EAAQmpC,KAwDhDnqD,IAAG6B,OAAOuZ,EAAMo+C,GAEhBp+C,EAAKy+C,SAAWz+C,EAAK4tC,WAAWgP,cAEhCh4D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu5D,eAAen+C,EAAMi/C,IAE5Cr6D,GAAG6B,OAAOw4D,GACNC,mBAAoB,SAASngD,EAAI7N,EAAQ8uD,GACrC,GAAIN,GAAqB1/C,EAAK4tC,WAAWqB,aAAalwC,EAEtDiB,GAAK8uC,sBAAsB/vC,GAAI,GAE/B2gD,EAAmB/zD,MAAQ0zD,EAAyBtgD,GAEhDihD,GACAN,EAAmBO,QAGvBL,EAAyBF,EAAoB3gD,GAC7C8gD,EAA6BH,EAAoB3gD,Q3CvF9BjV","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse, +thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],q=-1,f={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=f.placeholders.thumbnailNotAvailable,n=f.placeholders.waitingForThumbnail,i={maxSize:q,scale:u};s&&(e?f.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?f.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,f.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(f.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},M=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==f.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(f.templateIdOrEl)){if(e=document.getElementById(f.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",f.templateIdOrEl));o=e.innerHTML}else{if(void 0===f.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=f.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),f.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(q=parseInt(p.getAttribute("qq-max-size")),q=q>0?q:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},j=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:q,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?f.limits.maxThumbs&&f.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,f.limits.timeBetweenThumbs)}),null!=i?J(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:q};if(o)if(n){if(!(f.limits.maxThumbs&&f.limits.maxThumbs<=d))return i&&y(o),f.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,f.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,f.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(f.classes.hide)},J=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),f.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(f,e),t=f.log,qq.supportedFeatures.imagePreviews||(f.limits.timeBetweenThumbs=0,f.limits.maxThumbs=0),r=f.containerEl,s=void 0!==f.imageGenerator,o=M(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=f.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),q=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?j(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(f.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return f.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(f.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(f.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(f.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,f.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map index 1f6fedda2..872c1e3cc 100644 --- a/styles/bootstrap/fine-uploader/fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"
tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA,QCEV,GAAIC,IAAK,SAASC,GACd,YAEA,QACIC,KAAM,WAEF,MADAD,GAAQE,MAAMC,QAAU,OACjBC,MAIXC,OAAQ,SAASC,EAAMC,GAMnB,MALIP,GAAQQ,iBACRR,EAAQQ,iBAAiBF,EAAMC,GAAI,GAC5BP,EAAQS,aACfT,EAAQS,YAAY,KAAOH,EAAMC,GAE9B,WACHR,GAAGC,GAASU,OAAOJ,EAAMC,KAIjCG,OAAQ,SAASJ,EAAMC,GAMnB,MALIP,GAAQW,oBACRX,EAAQW,oBAAoBL,EAAMC,GAAI,GAC/BP,EAAQS,aACfT,EAAQY,YAAY,KAAON,EAAMC,GAE9BH,MAGXS,SAAU,SAASC,GAKf,QAAKA,IAKDd,IAAYc,IAIZd,EAAQa,SACDb,EAAQa,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwBf,OAOrDgB,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAahB,EAASiB,GACnCb,MAGXe,OAAQ,WAEJ,MADAnB,GAAQkB,WAAWE,YAAYpB,GACxBI,MAOXiB,IAAK,SAASC,GAEV,GAAqB,MAAjBtB,EAAQE,MACR,KAAM,IAAIH,IAAGwB,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1BxB,GAAQE,MAAMsB,SAAqD,SAArBxB,EAAe,UACpEsB,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9EzB,GAAG6B,OAAO5B,EAAQE,MAAOoB,GAElBlB,MAGXyB,SAAU,SAASC,EAAMC,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAUH,EAAO,QACrC,OAAOE,GAAGE,KAAKlC,EAAQmC,eAAiBJ,IAAkBC,EAAGE,KAAKlC,EAAQkB,WAAWiB,aAGzFC,SAAU,SAASN,GAIf,MAHK/B,IAAGC,GAAS6B,SAASC,KACtB9B,EAAQmC,WAAa,IAAML,GAExB1B,MAGXiC,YAAa,SAASP,GAClB,GAAIE,GAAK,GAAIC,QAAO,QAAUH,EAAO,QAErC,OADA9B,GAAQmC,UAAYnC,EAAQmC,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtElC,MAGXmC,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASxC,EAAQ2C,cACV3C,EAAQ2C,cAAc,IAAMR,GAE9BnC,EAAQ4C,iBACN5C,EAAQ4C,iBAAiB,IAAMT,IAG1CM,EAAazC,EAAQ6C,qBAAqB,KAE1C9C,GAAG+C,KAAKL,EAAY,SAASM,EAAKC,GAC1BjD,GAAGiD,GAAKnB,SAASM,IACjBO,EAAOO,KAAKD,KAGbR,EAAQE,EAAO,GAAKA,IAG/BQ,gBAAiB,SAASf,GACtB,MAAOpC,IAAGC,GAASuC,WAAWJ,GAAW,IAG7CgB,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQpD,EAAQqD,WAEbD,GACoB,IAAnBA,EAAME,UACNH,EAASF,KAAKG,GAElBA,EAAQA,EAAMG,WAGlB,OAAOJ,IAGXK,QAAS,SAASC,GAGd,MAFAzD,GAAQ0D,UAAYD,EACpBzD,EAAQ2D,YAAcF,EACfrD,MAGXwD,UAAW,WACP,MAAO7D,IAAGC,GAASwD,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAI/D,GAAQ6D,eAEH7D,EAAQ6D,aAAaC,IAKkC,MAArD,WAAaE,KAAKhE,EAAQiE,aAAaH,KAG9CC,EAAU/D,EAAQ8D,GAEFI,SAAZH,GAKiC,MAA9B,WAAaC,KAAKD,QAMxC,WACG,YAEAhE,IAAGoE,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAOvE,IAAGwE,cAAcH,EAAOI,UAAUH,EAAMC,KAGnDvE,GAAGwE,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAASC,EAAMV,GACxB,GAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,IAyB3C,OAlBIM,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlCnB,EAAWJ,EAAaG,IAGnC9E,GAAGmG,IAAM,SAASC,EAASC,GACnBnB,OAAOoB,UACFD,GAAmB,SAAVA,EAKNnB,OAAOoB,QAAQD,GACfnB,OAAOoB,QAAQD,GAAOD,GAGtBlB,OAAOoB,QAAQH,IAAI,IAAME,EAAQ,KAAOD,GAR5ClB,OAAOoB,QAAQH,IAAIC,KAc/BpG,GAAGuG,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAASjD,UAAyD,oBAA7CkD,OAAOC,UAAUC,SAASC,KAAKJ,IAG5ExG,GAAG6G,WAAa,SAASL,GACrB,MAA6B,kBAAf,IASlBxG,GAAG8G,QAAU,SAASC,GAClB,MAAiD,mBAA1CN,OAAOC,UAAUC,SAASC,KAAKG,IACjCA,GAAS7B,OAAOY,aAAeiB,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBnB,aAIrF9F,GAAGkH,WAAa,SAASC,GACrB,MAAyD,kCAAlDV,OAAOC,UAAUC,SAASC,KAAKO,IAK1CnH,GAAGoH,WAAa,SAASC,GACrB,MAAyD,sBAAlDZ,OAAOC,UAAUC,SAASC,KAAKS,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CvH,GAAGwH,SAAW,SAASC,GACnB,MAAuD,oBAAhDhB,OAAOC,UAAUC,SAASC,KAAKa,IAG1CzH,GAAG0H,QAAU,SAASC,GAClB,MAAIC,QAAOlB,UAAUmB,KACVF,EAAOE,OAGXF,EAAOpF,QAAQ,aAAc,KAOxCvC,GAAG8H,OAAS,SAASC,GAEjB,GAAIC,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,GAC9CC,EAASL,EACTM,EAAmBD,EAAOzC,QAAQ,KAetC,OAbA3F,IAAG+C,KAAKiF,EAAM,SAAShF,EAAKC,GAQxB,GAJAmF,EAHgBA,EAAOE,UAAU,EAAGD,GAGfpF,EAFNmF,EAAOE,UAAUD,EAAmB,GAGnDA,EAAmBD,EAAOzC,QAAQ,KAAM0C,EAAmBpF,EAAI8C,QAG3DsC,EAAmB,EACnB,OAAO,IAIRD,GAGXpI,GAAGuI,OAAS,SAASC,GACjB,MAAOtD,QAAOuD,MAAsD,kBAA9ChC,OAAOC,UAAUC,SAASC,KAAK4B,IAGzDxI,GAAG0I,WAAa,SAASC,GACrB,MAAOzD,QAAO0D,UAA8D,sBAAlDnC,OAAOC,UAAUC,SAASC,KAAK+B,IAG7D3I,GAAG6I,cAAgB,SAASC,GACxB,MAAO9I,IAAGuI,OAAOO,IAAqB9I,GAAG+I,QAAQD,IAGrD9I,GAAG+I,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAAS3I,GACxB,GAAI4I,GAAiB5I,EAAK6I,aAE1B,OAAIH,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAIjE,OAAOmE,kBAC4C,8BAA/C5C,OAAOC,UAAUC,SAASC,KAAKoC,IAC3BA,EAAWzI,MAAQ2I,EAAaF,EAAWzI,WAKnDyI,EAAWM,SAC8B,UAArCN,EAAWM,QAAQF,eACfJ,EAAWzI,MAAQ2I,EAAaF,EAAWzI,QAS3DP,GAAGuJ,OAAS,SAASC,GACjB,GAAItE,OAAOO,MAAsD,kBAA9CgB,OAAOC,UAAUC,SAASC,KAAK4C,GAC9C,OAAO,GAIfxJ,GAAGyJ,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAMnJ,KAAO,OAGU4D,SAAnBuF,EAAMG,UACc,mBAATpB,OACa,mBAAbqB,WACoC,SAAnC9J,GAAG+J,oBAAqBC,QAI5ChK,GAAG+J,kBAAoB,WACnB,GAAI7E,OAAO+E,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOC,GAEH,MADAnK,IAAGmG,IAAI,wCAAyC,SACzC,OAIfnG,GAAGoK,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMvE,OAAS,GAC5BsE,EAAaC,MAAM,GAAGC,kBAG9BvK,GAAGwK,wBAA0B,WACzB,OAAQxK,GAAGyK,gBACPzK,GAAGyJ,yBACuBtF,SAAzBsE,KAAK/B,UAAUwB,OAAsD/D,SAA/BsE,KAAK/B,UAAUgE,aAAyDvG,SAA5BsE,KAAK/B,UAAUiE,WAG1G3K,GAAG4K,UAAY,SAASC,EAAYC,EAAOC,GAGvC,OAFaF,EAAW3C,OAAS2C,EAAWF,UAAYE,EAAWH,aAErD9D,KAAKiE,EAAYC,EAAOC,IAG1C/K,GAAGgL,iBAAmB,SAAShE,GAC3B,GAAIiE,GAAa,GACbC,EAAQ,GAAIlF,YAAWgB,EAY3B,OAVAhH,IAAG+C,KAAKmI,EAAO,SAASlI,EAAKmI,GACzB,GAAIC,GAAeD,EAAIxE,SAAS,GAE5ByE,GAAarF,OAAS,IACtBqF,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXjL,GAAGqL,cAAgB,SAASC,EAAMC,EAAaxF,GAC3C,GAAIyF,GAAcxL,GAAG4K,UAAUU,EAAMC,EAAaA,EAAcxF,GAC5D0F,EAAa,GAAIC,YACjBC,EAAU,GAAI3L,IAAG4L,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQ9L,GAAGgL,iBAAiBS,EAAW9I,UAGnD8I,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGX3L,GAAG6B,OAAS,SAASY,EAAOyJ,EAAQC,GAahC,MAZAnM,IAAG+C,KAAKmJ,EAAQ,SAASE,EAAMnJ,GACvBkJ,GAAgBnM,GAAGuG,SAAStD,IACRkB,SAAhB1B,EAAM2J,KACN3J,EAAM2J,OAEVpM,GAAG6B,OAAOY,EAAM2J,GAAOnJ,GAAK,IAG5BR,EAAM2J,GAAQnJ,IAIfR,GAaXzC,GAAGqM,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACAC,EAASF,EAASC,EAUtB,OARAxM,IAAG+C,KAAK0J,EAAQ,SAASC,EAAaC,GACNxI,SAAxBmI,EAAOI,KACPF,EAAOE,GAAeJ,EAAOI,IAGjCJ,EAAOI,GAAeC,IAGnBL,GAMXtM,GAAG2F,QAAU,SAASiH,EAAKC,EAAKC,GAC5B,GAAIF,EAAIjH,QACJ,MAAOiH,GAAIjH,QAAQkH,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAI7G,MAMd,KAJI+G,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIX9M,GAAGiN,YAAc,WACb,MAAO,uCAAuC1K,QAAQ,QAAS,SAAS2K,GAEpE,GAAIC,GAAoB,GAAhBxL,KAAKyL,SAAgB,CAC7B,QADyC,KAALF,EAAWC,EAAS,EAAJA,EAAU,GACrDxG,SAAS,OAM1B3G,GAAGqN,GAAK,WACJ,MAAOC,WAAUC,UAAU5H,QAAQ,WAAY,GAC3C2H,UAAUC,UAAU5H,QAAQ,cAAe,GAGnD3F,GAAGwN,IAAM,WACL,MAAOF,WAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAGyN,IAAM,WACL,MAAOH,WAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAG0N,KAAO,WACN,MAAOJ,WAAUC,UAAU5H,QAAQ,cAAe,GAGtD3F,GAAG2N,KAAO,WACN,MAAO3N,IAAGqN,MAAQC,UAAUC,UAAU5H,QAAQ,YAAa,GAG/D3F,GAAG4N,KAAO,WACN,MAAON,WAAUC,UAAU5H,QAAQ,SAAW,GAGlD3F,GAAG6N,OAAS,WACR,MAA4B1J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,YAAa,GAGnF3F,GAAG+N,OAAS,WACR,MAA4B5J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,aAAc,GAGpF3F,GAAGgO,MAAQ,WACP,MAA4B7J,UAArBmJ,UAAUQ,QAAwBR,UAAUQ,OAAOnI,QAAQ,YAAa,GAGnF3F,GAAGiO,QAAU,WACT,OAASjO,GAAG4N,SAAW5N,GAAG2N,QAAUL,UAAUC,UAAU5H,QAAQ,cAAe,GAA2BxB,SAArBmJ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrI9N,GAAGkO,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrBnO,GAAGoO,QAAU,WACT,MAAOd,WAAUC,UAAUnE,cAAczD,QAAQ,cAAe,GAKpE3F,GAAGyK,aAAe,WACd,MAAOzK,IAAGoO,WAAad,UAAUC,UAAUnE,cAAczD,QAAQ,UAAY,GAGjF3F,GAAGqO,KAAO,WACN,MAAOrO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAGjE3F,GAAGuO,KAAO,WACN,MAAOvO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAGjE3F,GAAGwO,KAAO,WACN,MAAOxO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,aAAc,GAIjE3F,GAAGyO,OAAS,WACR,MAAOzO,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,eAAgB,GAGnE3F,GAAGsO,IAAM,WAEL,MAAOhB,WAAUC,UAAU5H,QAAQ,WAAY,GACxC2H,UAAUC,UAAU5H,QAAQ,WAAY,GACxC2H,UAAUC,UAAU5H,QAAQ,aAAc,GAGrD3F,GAAG0O,UAAY,WACX,MAAO1O,IAAGsO,OAAShB,UAAUC,UAAU5H,QAAQ,YAAa,GAGhE3F,GAAG2O,UAAY,WACX,MAAO3O,IAAGsO,QAAUtO,GAAG0O,aAAepB,UAAUC,UAAU5H,QAAQ,aAAc,GAGpF3F,GAAG4O,iBAAmB,WAClB,MAAO5O,IAAGsO,QAAUtO,GAAG0O,cAAgB1O,GAAG2O,aAM9C3O,GAAG6O,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxB/O,GAAGgP,UAAa,WACZ,GAAIC,GAAMtF,SAASC,cAAc,MACjC,OAAO,UAASsF,GACZD,EAAIE,UAAYD,CAChB,IAAIjP,GAAUgP,EAAI3L,UAElB,OADA2L,GAAI5N,YAAYpB,GACTA,MAKfD,GAAG+C,KAAO,SAASqM,EAAcC,GAC7B,GAAIC,GAAYC,CAEhB,IAAIH,EAEA,GAAIlK,OAAOsK,SAAWJ,EAAanI,cAAgB/B,OAAOsK,QACtD,IAAKF,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASD,EAAaK,IAAIH,GAAaF,EAAaM,QAAQN,EAAaK,IAAIH,KAClFC,KAAW,GAFoCD,SAStD,IAAItP,GAAG8G,QAAQsI,IAAiBpP,GAAGkH,WAAWkI,IAAiBpP,GAAGoH,WAAWgI,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GAFoCD,SAOtD,IAAItP,GAAGwH,SAAS4H,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAarJ,SAC3CwJ,EAASF,EAASC,EAAYF,EAAaO,OAAOL,IAC9CC,KAAW,GAFoCD,SAQvD,KAAKA,IAAcF,GACf,GAAI3I,OAAOC,UAAUsG,eAAepG,KAAKwI,EAAcE,KACnDC,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GACX,OASxBvP,GAAG4P,KAAO,SAASC,EAASC,GACxB,GAAI9P,GAAG6G,WAAWgJ,GAAU,CACxB,GAAI7H,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,EAElD,OAAO,YACH,GAAI4H,GAAU/P,GAAG6B,UAAWmG,EAI5B,OAHIG,WAAUpC,SACVgK,EAAUA,EAAQC,OAAO/H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,aAEjD0H,EAAQI,MAAMH,EAASC,IAItC,KAAM,IAAIvO,OAAM,wCAmBpBxB,GAAGkQ,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQjO,KAAKiO,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAWpN,KACa,gBAAZuN,GACFzQ,GAAGkQ,QAAQO,EAASE,GAAU,GACe,sBAA5ClK,OAAOC,UAAUC,SAASC,KAAK6J,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAKpO,KAAKiO,GAAU,MAAMjO,KAAKiO,GAAS,GAAK,IAAM,IAC7DE,EAAWpN,KAAKkN,GAChBE,EAAWpN,KAAKlD,GAAGkQ,QAAQC,KACqB,mBAAxC1J,OAAOC,UAAUC,SAASC,KAAKuJ,IAA8C,SAARA,EAC7EnQ,GAAG+C,KAAKoN,EAAK,SAASnN,EAAKC,GACvBuN,EAAIvN,EAAKD,KAEU,SAARmN,GAAiC,OAARA,GAAiC,gBAARA,GACjEnQ,GAAG+C,KAAKoN,EAAK,SAAS/D,EAAMnJ,GACxBuN,EAAIvN,EAAKmJ,KAGbkE,EAAWpN,KAAK0N,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBhO,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7BvC,GAAG8Q,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAIjH,WAGnB9J,GAAG+C,KAAKoN,EAAK,SAASV,EAAKxM,GACvBwM,EAAMuB,EAAeA,EAAe,IAAMvB,EAAM,IAAMA,EAElDzP,GAAGuG,SAAStD,GACZjD,GAAG8Q,aAAa7N,EAAK8N,EAAUtB,GAE1BzP,GAAG6G,WAAW5D,GACnB8N,EAASxL,OAAOkK,EAAKxM,KAGrB8N,EAASxL,OAAOkK,EAAKxM,KAItB8N,GAGX/Q,GAAGiR,WAAa,SAASd,EAAKe,GAC1B,GAAIxH,EAeJ,OAbKwH,KACDA,EAAOvH,SAASC,cAAc,SAGlC5J,GAAG8Q,aAAaX,GACZ5K,OAAQ,SAASkK,EAAKxM,GAClByG,EAAQC,SAASC,cAAc,SAC/BF,EAAMyH,aAAa,OAAQ1B,GAC3B/F,EAAMyH,aAAa,QAASlO,GAC5BiO,EAAKE,YAAY1H,MAIlBwH,GAOXlR,GAAGqR,UAAY,SAASC,MAEpB,MAAIpM,QAAOqM,MAAQvR,GAAG6G,WAAW0K,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjCtR,GAAG0R,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAAS5L,OAAS6L,IAIzD5R,GAAG+R,YAAc,SAASC,GAGtB,MAAIhS,IAAG+I,QAAQiJ,GAEJA,EAAgBjL,MAAMxE,QAAQ,YAAa,IAE7CvC,GAAGuI,OAAOyJ,IACkB,OAA7BA,EAAgBC,UAAkD9N,SAA7B6N,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgBjQ,MAM3B/B,GAAGkS,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIX/R,OAAQ,WACJ,GAAI0H,GAAOG,SAEX9H,MAAKkS,YAAYvS,GAAGgI,EAAK,IAAI1H,OAAO2P,MAAM5P,KAAM4H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,MAI1FoK,YAAa,SAASC,GAClBL,EAAUjP,KAAKsP,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAOzS,MAGY,mBAAX2S,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAU5S,GAGjBD,OAAOC,GAAKA,MCRnB,WACG,YAEAA,IAAGwB,MAAQ,SAAS4E,GAChB/F,KAAK+F,QAAU,kBAAoBpG,GAAG6S,QAAU,KAAOzM,GAG3DpG,GAAGwB,MAAMkF,UAAY,GAAIlF,UCV7BxB,GAAG6S,QAAU,SCAb7S,GAAG8S,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAYrJ,SAASC,cAAc,SACnCoJ,EAAUzS,KAAO,OACjBP,GAAGgT,GAAW9S,OAEV8S,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQpT,GAAG+N,UAAY/N,GAAGgO,UAC+C7J,SAArEmJ,UAAUC,UAAU8F,MAAM,uCAIlC,QAASC,KACL,GAAIpO,OAAO+E,eAAgB,CAIvB,MAA+B9F,UAHrBnE,GAAG+J,oBAGFwJ,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiCrP,UAA1Be,OAAOuO,eAKlB,QAASC,KACL,QAAIJ,KAIGE,IAGX,QAASG,KAEL,MAA2DxP,UAApDwF,SAASC,cAAc,SAASgK,gBAG3C,QAASC,KACL,IACI,QAAS3O,OAAO4O,cAEZ9T,GAAG6G,WAAW3B,OAAO4O,aAAaC,SAE1C,MAAO5J,GAEH,OAAO,GAIf,QAAS6J,KACL,GAAIC,GAAOtK,SAASC,cAAc,OAElC,QAAQ,aAAeqK,IAAS,eAAiBA,IAAQ,UAAYA,MAChEjU,GAAGoO,YAAcpO,GAAGsO,MA1F7B,GAAI4F,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAzCAd,GAAoBnB,IAEpBsB,EAA4BH,GAAqBlU,GAAGyJ,uBAEpD0K,EAAyBE,IAA8BrU,GAAGyK,eAE1D2J,EAAmBC,GAA6BL,IAGhDM,EAAqBF,GAAqB,WACtC,GAAI1K,GAAQC,SAASC,cAAc,QAGnC,OADAF,GAAMnJ,KAAO,UACH,oBAAsBmJ,GAASC,SAAS9G,iBAAiB,oBAAoB,QAG3F0R,EAAmBF,GAA6BrU,GAAGwK,0BAEnDgK,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BjB,IAEtDsB,EAAqBR,IAA6C/P,SAAvBe,OAAO+P,aAA6BZ,GAE/EO,EAA4BtB,IAE5BqB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmDlQ,SAAtBe,OAAOwG,WAE5DsJ,EAA0B,WACtB,QAAIX,KACQrU,GAAGyK,iBAAmBzK,GAAG0O,iBAMrCwG,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiBvQ,OAAOwQ,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAcrW,GAAG6N,SACjByI,0BAA2BtW,GAAGsO,MAC9BiI,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxBzU,GAAG4W,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQ9W,GAAG6G,WAAWgQ,EAAaC,QAG9E9W,GAAG4L,QAAU,WACT,YAEA,IAAImL,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZpX,IAAG6B,OAAOxB,MACNyW,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiB/T,KAAKmU,GAEtBC,GACAJ,EAAiBhU,KAAKoU,IAGrBF,KAAU,EACfE,GAAaA,EAAUrH,MAAM,KAAM+G,GAE9BK,GACLA,EAAUpH,MAAM,KAAM8G,GAGnB1W,MAGXkX,KAAM,SAASlI,GAQX,MAPc,KAAV+H,EACAD,EAAcjU,KAAKmM,GAGnBA,EAASY,MAAM,KAAsB9L,SAAhB6S,EAA4BD,EAAcC,GAG5D3W,MAGXyL,QAAS,WAgBL,MAfAsL,GAAQ,EACRL,EAAc5O,UAEV8O,EAAiBlR,QACjB/F,GAAG+C,KAAKkU,EAAkB,SAASjU,EAAKqM,GACpCA,EAASY,MAAM,KAAM8G,KAIzBI,EAAcpR,QACd/F,GAAG+C,KAAKoU,EAAe,SAASnU,EAAKqM,GACjCA,EAASY,MAAM,KAAM8G,KAItB1W,MAGX2L,QAAS,WAgBL,MAfAoL,IAAQ,EACRJ,EAAc7O,UAEV+O,EAAiBnR,QACjB/F,GAAG+C,KAAKmU,EAAkB,SAASlU,EAAKqM,GACpCA,EAASY,MAAM,KAAM+G,KAIzBG,EAAcpR,QACd/F,GAAG+C,KAAKoU,EAAe,SAASnU,EAAKqM,GACjCA,EAASY,MAAM,KAAM+G,KAItB3W,SC3EnBL,GAAGwX,UAAY,SAASC,EAAeC,GACnC,YAEA1X,IAAG6B,OAAOxB,MACNoX,cAAeA,EAEfE,OAAQ,WACJ,MAAOD,GAASD,OCF5BzX,GAAG4X,aAAe,SAASC,GACvB,YA0CA,SAASC,KACL,GAAIpO,GAAQC,SAASC,cAAc,QAmEnC,OAjEAF,GAAMyH,aAAanR,GAAG4X,aAAaG,oBAAqBC,GACxDtO,EAAMyH,aAAa,QAAS8G,EAAQC,OAEpCC,EAAKC,YAAYH,EAAQpO,SAAUH,GAE/BuO,EAAQI,SAAWrY,GAAG8S,kBAAkB+C,iBAExCnM,EAAMyH,aAAa,kBAAmB,IAGtC8G,EAAQK,aACR5O,EAAMyH,aAAa,SAAU8G,EAAQK,aAGzC5O,EAAMyH,aAAa,OAAQ,QAC3BzH,EAAMyH,aAAa,OAAQ8G,EAAQlW,MAEnC/B,GAAG0J,GAAOpI,KACNiX,SAAU,WAIVC,MAAO,EACPC,IAAK,EACLC,WAAY,QASZC,SAAU3Y,GAAGqN,OAASrN,GAAGyN,MAAQ,SAAW,QAC5CmL,OAAQ,EACRC,QAAS,EACTC,OAAQ,UACRrX,QAAS,KAKZzB,GAAGwN,OAASxN,GAAG0J,GAAOpI,KAAKyX,OAAQ,SAEpCd,EAAQhY,QAAQmR,YAAY1H,GAE5BsP,EAAe1Y,OAAOoJ,EAAO,SAAU,WACnCuO,EAAQgB,SAASvP,KAIrBsP,EAAe1Y,OAAOoJ,EAAO,YAAa,WACtC1J,GAAGiY,EAAQhY,SAASoC,SAAS4V,EAAQiB,cAEzCF,EAAe1Y,OAAOoJ,EAAO,WAAY,WACrC1J,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQiB,cAG5CF,EAAe1Y,OAAOoJ,EAAO,QAAS,WAClC1J,GAAGiY,EAAQhY,SAASoC,SAAS4V,EAAQkB,cAEzCH,EAAe1Y,OAAOoJ,EAAO,OAAQ,WACjC1J,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQkB,cAGrCzP,EA5GX,GAgCIA,GAAOsO,EAhCPG,EAAO9X,KAEP2Y,EAAiB,GAAIhZ,IAAGkS,eAExB+F,GAEIK,YAAa,KAGbrY,QAAS,KAETkZ,WAAY,yBAGZd,SAAS,EAGTa,WAAY,yBAEZE,4BAA4B,EAG5BvP,UAAU,EAGV9H,KAAM,SAGNkX,SAAU,SAASvP,KAEnBwO,MAAO,KAKflY,IAAG6B,OAAOoW,EAASJ,GAEnBG,EAAWhY,GAAGiN,cA2EdjN,GAAGiY,EAAQhY,SAASqB,KAChBiX,SAAU,WACVc,SAAU,SAEVC,UAAW,QAIftZ,GAAG6B,OAAOxB,MACNkZ,SAAU,WACN,MAAO7P,IAGX8P,YAAa,WACT,MAAOxB,IAGXI,YAAa,SAASqB,EAAYC,GAC9B,GAAIhQ,GAAQgQ,GAAYrZ,KAAKkZ,UAKzBtB,GAAQmB,4BAA8BpZ,GAAGwO,SAAWxO,GAAG0O,aAAe1O,GAAG4O,oBACzElF,EAAMyH,aAAa,WAAY,IAI3BsI,EACA/P,EAAMyH,aAAa,WAAY,IAG/BzH,EAAMiQ,gBAAgB,aAKlCC,eAAgB,SAAStB,GACjBA,IAAgBL,EAAQK,aACxB5O,EAAMyH,aAAa,SAAUmH,IAIrCuB,MAAO,WACCnQ,EAAMvI,YACNnB,GAAG0J,GAAOtI,SAGdpB,GAAGiY,EAAQhY,SAASqC,YAAY2V,EAAQkB,YACxCzP,EAAQ,KACRA,EAAQoO,OAIhBpO,EAAQoO,KAGZ9X,GAAG4X,aAAaG,oBAAsB,eCxLtC/X,GAAG8Z,WAAa,SAASC,GACrB,YAQA,SAASC,GAAaC,GAClB,GAAIja,GAAG8G,QAAQmT,GAAU,CACrB,GAAIC,KAMJ,OAJAla,IAAG+C,KAAKkX,EAAS,SAASjX,EAAKmX,GAC3BD,EAAQhX,KAAK8B,EAAKmV,MAGfD,EAGX,MAAOlV,GAAKiV,GAGhB,QAASG,GAAeC,GACpB,GAAIra,GAAG8G,QAAQuT,GAAQ,CACnB,GAAIH,KAMJ,OAJAla,IAAG+C,KAAKsX,EAAO,SAASrX,EAAKsX,GACzBJ,EAAQhX,KAAK8B,EAAKuV,EAAOD,OAGtBJ,EAGX,MAAOlV,GAAKuV,EAAOF,IAGvB,QAASG,GAAgBC,GACrB,GAAIC,MACAC,KAAc3K,OAAOyK,EAYzB,OAVAza,IAAG+C,KAAK4X,EAAU,SAASC,EAAOC,GAC9B,GAAIC,GAAsBC,EAASF,EAEP1W,UAAxB2W,GACA9a,GAAG+C,KAAK+X,EAAqB,SAASpK,EAAGsK,GACrCN,EAAcxX,KAAK8B,EAAKgW,QAK7BN,EAhDX,GAAI1V,MACAuV,KACAQ,KACAE,KACAC,IA+CJlb,IAAG6B,OAAOxB,MAgBN8a,QAAS,SAASC,GACd,GAAIX,GAASW,EAAKX,QAAUza,GAAGya,OAAOY,WAClClB,EAAKnV,EAAK9B,MACNnB,KAAMqZ,EAAKrZ,KACXuZ,aAAcF,EAAKrZ,KACnBuY,KAAMc,EAAKd,KACXiB,KAAmB,MAAbH,EAAKG,MAAe,EAAKH,EAAKG,KACpCd,OAAQA,EACRe,KAAMJ,EAAKI,OACV,CA+BT,OA7BIJ,GAAKK,UACLzW,EAAKmV,GAAIsB,QAAUL,EAAKK,QAEQtX,SAA5B+W,EAAUE,EAAKK,WACfP,EAAUE,EAAKK,aAEnBP,EAAUE,EAAKK,SAASvY,KAAKiX,IAG7BiB,EAAKM,eACL1W,EAAKmV,GAAIuB,aAAeN,EAAKM,aAEavX,SAAtC8W,EAAeG,EAAKM,gBACpBT,EAAeG,EAAKM,kBAExBT,EAAeG,EAAKM,cAAcxY,KAAKiX,IAG3CnV,EAAKmV,GAAIA,GAAKA,EACdI,EAAOa,EAAKd,MAAQH,EAEKhW,SAArB4W,EAASN,KACTM,EAASN,OAEbM,EAASN,GAAQvX,KAAKiX,GAEtBiB,EAAKO,sBAAwBP,EAAKO,qBAAqBxB,GACvDJ,EAAc6B,eAAezB,EAAI,KAAMM,GAEhCN,GAGX0B,SAAU,SAASC,GACf,MAAI9b,IAAGuG,SAASuV,IAAmB9W,EAAKe,OACV5B,SAAtB2X,EAAe3B,GACRH,EAAa8B,EAAe3B,IAGNhW,SAAxB2X,EAAexB,KACbF,EAAe0B,EAAexB,MAGhCwB,EAAerB,OACbD,EAAgBsB,EAAerB,QADrC,OAKEza,GAAG6B,UAAWmD,GAAM,IAInC+W,cAAe,SAAS5B,GACpB,GAAI6B,GAAShC,EAAaG,EAEtB6B,UACOA,GAAOR,MAItB3B,MAAO,WACH7U,KACAuV,KACAQ,KACAG,MAGJe,UAAW,SAAS9B,EAAI+B,GACpB,GAAIC,GAAYnX,EAAKmV,GAAIM,OACrB2B,EAAyBpc,GAAG2F,QAAQoV,EAASoB,GAAYhC,EAE7DY,GAASoB,GAAWE,OAAOD,EAAwB,GAEnDpX,EAAKmV,GAAIM,OAASyB,EAEU/X,SAAxB4W,EAASmB,KACTnB,EAASmB,OAEbnB,EAASmB,GAAWhZ,KAAKiX,GAEzBJ,EAAc6B,eAAezB,EAAIgC,EAAWD,IAGhDI,YAAa,SAASnC,EAAIoC,GACtB,GAAIC,GAAUxX,EAAKmV,GAAIG,IAEvBtV,GAAKmV,GAAIG,KAAOiC,EAChBhC,EAAOgC,GAAWpC,QACXI,GAAOiC,IAGlBC,WAAY,SAAStC,EAAIuC,GACrB1X,EAAKmV,GAAIpY,KAAO2a,GAGpBC,WAAY,SAASxC,EAAIyC,GACrB5X,EAAKmV,GAAIoB,KAAOqB,GAIpBC,YAAa,SAASC,EAAUC,GAC5B/X,EAAK8X,GAAUC,SAAWA,GAG9BC,mBAAoB,SAAS7C,GACzB,GAAIuB,GAAe1W,EAAKmV,GAAIuB,YAE5B,OAAIA,GACOT,EAAeS,OAK9BuB,cAAe,SAAS9C,GAGpB,MAAOe,GAFOlW,EAAKmV,GAAIsB,aAOnCzb,GAAGya,QACCY,WAAY,aACZ6B,UAAW,YACXC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,UAAW,YACXC,kBAAmB,oBACnBC,gBAAiB,kBACjBC,kBAAmB,oBACnBC,cAAe,gBACfC,cAAe,gBACfC,SAAU,WACVC,QAAS,WCpNZ,WACG,YAEA9d,IAAG+d,eAECC,SAAU,SAASC,EAAiBC,EAAQC,GACxC9d,KAAK+d,SAASH,EAAiBC,EAAQC,IAG3CE,gBAAiB,SAASC,GACtB,GAAInG,GAAO9X,IAEXL,IAAG+C,KAAKub,EAAgB,SAAS1D,EAAO2D,GACpCpG,EAAKqG,eAAeD,MAI5BH,SAAU,SAASpZ,EAAMkZ,EAAQC,GAC7B9d,KAAKoe,kCAEL,IAAIhD,GAAqC,IAA3Bpb,KAAKqe,WAAW3Y,OAAe/F,GAAGiN,cAAgB5M,KAAKse,gBAEjEC,EAAc5e,GAAG4P,KAAK,SAAStE,GAC3BjL,KAAKwe,gBACDvT,KAAMA,EACNvJ,KAAM1B,KAAKye,SAASC,MAAMC,aAC3BvD,EAASwD,IACb5e,MAEH6e,EAAkBlf,GAAG4P,KAAK,SAASuP,GAC/B9e,KAAKwe,eAAeM,EAAU1D,EAASwD,IACxC5e,MAEH+e,EAAgBpf,GAAG4P,KAAK,SAASvL,GAC7B,GAAIiH,GAAOtL,GAAGoE,aAAaC,EAE3BhE,MAAKwe,gBACDvT,KAAMA,EACNvJ,KAAM1B,KAAKye,SAASC,MAAMC,YAAc,QACzCvD,EAASwD,IACb5e,MAEHgf,EAAoBrf,GAAG4P,KAAK,SAAS0P,GACjC,GAAIC,GAAoBD,EAAW/a,SAAW+a,EAAW/a,QAAU,IAC/D+G,EAAOtL,GAAGoE,aAAakb,EAAWjb,OAAQib,EAAW/e,KAAMgf,EAE/Dlf,MAAKwe,gBACDvT,KAAMA,EACNvJ,KAAMud,EAAWvd,MAClB0Z,EAASwD,IACb5e,MAEHmf,EAAqBxf,GAAG4P,KAAK,SAAS6P,GAClC,GAAIzf,GAAG+I,QAAQ0W,IAAgBzf,GAAG8S,kBAAkBoC,cAAe,CAC/D,GAAIwK,GAAQzX,MAAMvB,UAAUwB,MAAMtB,KAAK6Y,EAAYC,OAC/CvH,EAAO9X,IAEXL,IAAG+C,KAAK2c,EAAO,SAAS1c,EAAKwY,GACzBrD,EAAK0G,eAAerD,EAAMC,EAASwD,SAIvC5e,MAAKwe,eAAeY,EAAahE,EAASwD,IAE/C5e,MAEHsf,EAAgB,WACR3f,GAAG0I,WAAW1D,KACdA,EAAOiD,MAAMvB,UAAUwB,MAAMtB,KAAK5B,IAEtCA,KAAUgL,OAAOhL,IAGrBmT,EAAO9X,KACP4e,IAEJ5e,MAAKse,gBAAkBlD,EAEnBzW,IACA2a,IAEA3f,GAAG+C,KAAKiC,EAAM,SAAShC,EAAK4c,GACpB5f,GAAG6I,cAAc+W,GACjBJ,EAAmBI,GAEd5f,GAAGuJ,OAAOqW,GACfhB,EAAYgB,GAEP5f,GAAGuG,SAASqZ,GACbA,EAActU,MAAQsU,EAAc7d,KACpCmd,EAAgBU,GAEXA,EAAcvb,QAAUub,EAAc7d,MAC3Csd,EAAkBO,GAGjBA,EAActW,SAAmD,WAAxCsW,EAActW,QAAQF,cACpDgW,EAAcQ,GAGdzH,EAAKhS,IAAIyZ,EAAgB,6CAA8C,UAI/Evf,KAAK8F,IAAI,YAAc8Y,EAAclZ,OAAS,WAC9C1F,KAAKwf,uBAAuBZ,EAAef,EAAQC,KAI3D2B,OAAQ,SAAS3F,GACb,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAE5C4F,IAAcA,EAAWtF,SAAWza,GAAGya,OAAO+C,kBAC9Cnd,KAAK8F,IAAInG,GAAG8H,OAAO,2DAA4DqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,SAGtG9Z,KAAK6f,SAASJ,OAAO3F,IAI7BgG,UAAW,WACP,GAAIC,MACAjI,EAAO9X,IAEXL,IAAG6B,OAAOue,EAAe/f,KAAKqe,YAC9B1e,GAAG+C,KAAKqd,EAAe,SAASpd,EAAKqd,GACjClI,EAAK2H,OAAOO,KAGhBhgB,KAAK6f,SAASC,aAGlBG,iBAAkB,WACdjgB,KAAKqe,eAGT6B,eAAgB,SAASpG,GACrB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAEhD,UAAKna,GAAG8S,kBAAkBmD,QAAU5V,KAAKye,SAASzJ,SAASmL,WAIvDT,EAAWtF,SAAWza,GAAGya,OAAO6C,QAChCjd,KAAK8F,IAAInG,GAAG8H,OAAO,yDAA0DqS,EAAI9Z,KAAK4f,QAAQ9F,KAC9F9Z,KAAKogB,YAAYtG,IACV,IAGP9Z,KAAK8F,IAAInG,GAAG8H,OAAO,sDAAuDqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,UAG9F,KAGXuG,WAAY,SAASvG,GACjB,MAAO9Z,MAAKsgB,gBAAgBxG,IAIhCyG,UAAW,SAASC,GAChB,MAAOxgB,MAAK6f,SAASY,QAAQD,IAOjCE,cAAe,SAASC,EAAQC,EAAaC,EAASC,EAAYC,GAC9D,GACIC,GAAWpJ,EADXqJ,EAAkB,GAAIthB,IAAG4L,OAqC7B,OAlCIvL,MAAKkhB,iBACLF,EAAYhhB,KAAKmhB,eAAeR,GAChC/I,GACImJ,qBAAsBA,EACtBF,QAASA,EAAU,EAAIA,EAAU,KACjCO,MAAOP,EAAU,IAKhBC,GAAcnhB,GAAG8S,kBAAkBgD,gBACpCuL,EAAYhhB,KAAKqhB,QAAQV,IAIZ,MAAbK,EACAC,EAAgBtV,SAAS2V,UAAWV,EAAa9W,MAAO,2BAGxD9J,KAAKkhB,gBAAgBK,SAASP,EAAWJ,EAAahJ,GAASnB,KAC3D,SAAiB+K,GACbP,EAAgBxV,QAAQ+V,IAG5B,SAAiBF,EAAWG,GACxBR,EAAgBtV,SAAS2V,UAAWA,EAAWxX,MAAO2X,GAAU,oCAM5ER,EAAgBtV,SAAS2V,UAAWV,EAAa9W,MAAO,mCAGrDmX,GAGXS,UAAW,SAASf,GAChB,MAAO3gB,MAAK2hB,WAAW3hB,KAAK4hB,qBAAqBjB,KAGrDkB,YAAa,SAASlB,GAClB,MAAO3gB,MAAK8hB,eAAeC,IAAIpB,IAGnCU,QAAS,SAASb,GACd,GACIwB,GADA7G,EAAOnb,KAAK6f,SAASwB,QAAQb,EAWjC,OARKrF,KACD6G,EAAmBhiB,KAAK2f,YAAYnE,UAAU1B,GAAI0G,IAE9CwB,IACA7G,EAAO6G,EAAiB7G,OAIzBA,GAAQ,MAGnB8G,cAAe,WACX,MAAOjiB,MAAK2f,YAAYnE,UACpBpB,QACIza,GAAGya,OAAO8C,UACVvd,GAAGya,OAAOgD,gBACVzd,GAAGya,OAAO2C,UAEfrX,QAGPka,QAAS,SAAS9F,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKpY,MAI/CwgB,YAAa,SAASpI,GAClB,GAAIqI,GAAkBniB,KAAKoiB,YAAYtI,GAAIA,IACvC4C,EAAW,IAQf,OANIyF,IACiCre,SAA7Bqe,EAAgBzF,WAChBA,EAAWyF,EAAgBzF,UAI5BA,GAGX2F,sBAAuB,WACnB,MAAOriB,MAAK6f,SAASwC,yBAGzBC,QAAS,SAASxI,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKoB,MAG/CqH,cAAe,WACX,MAAOviB,MAAKwiB,cAGhBC,yBAA0B,WACtB,GAAIC,GAAe1iB,KAAK2iB,iBAExB,OAAID,GAAe,EACRA,EAAe1iB,KAAK4iB,qBAGxB,MAGXR,WAAY,SAAS3G,GACjB,MAAOzb,MAAK2f,YAAYnE,SAASC,IAGrCoH,QAAS,SAAS/I,GACd,MAAO9Z,MAAK2f,YAAYnE,UAAU1B,GAAIA,IAAKG,MAG/C6I,YAAa,SAAShJ,GAClB,MAAO9Z,MAAK6f,SAASkD,gBAAgBjJ,IAGzChU,IAAK,SAAS4B,EAAK1B,IACXhG,KAAKye,SAASuE,OAAWhd,GAAmB,SAAVA,EAG7BA,GAAmB,SAAVA,GACdrG,GAAGmG,IAAI,kBAAoBnG,GAAG6S,QAAU,KAAO9K,EAAK1B,GAHpDrG,GAAGmG,IAAI,kBAAoBnG,GAAG6S,QAAU,KAAO9K,IAQvDub,YAAa,SAASnJ,GAClB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAEhD,KAAKna,GAAG8S,kBAAkBmD,QAAU5V,KAAKye,SAASzJ,SAASmL,QACvD,OAAO,CAIX,IAAIxgB,GAAG2F,SAAS3F,GAAGya,OAAO8C,UAAWvd,GAAGya,OAAOgD,iBAAkBsC,EAAWtF,SAAW,EAAG,CACtF,GAAIpa,KAAK6f,SAASjK,MAAMkE,GAEpB,MADA9Z,MAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO6C,SAClC,CAGPjd,MAAK8F,IAAInG,GAAG8H,OAAO,mCAAoCqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,aAIlF9Z,MAAK8F,IAAInG,GAAG8H,OAAO,wDAAyDqS,EAAI9Z,KAAK4f,QAAQ9F,IAAM,QAGvG,QAAO,GAGX4B,cAAe,SAAS5B,GACpB9Z,KAAK6f,SAASqD,QAAQpJ,GACtB9Z,KAAK2f,YAAYjE,cAAc5B,IAGnCN,MAAO,WACHxZ,KAAK8F,IAAI,yBAET9F,KAAK6f,SAASrG,QACdxZ,KAAKqe,cACLre,KAAKmjB,gBACLnjB,KAAKojB,kBACLpjB,KAAKqjB,mBACLrjB,KAAKmhB,kBAELxhB,GAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjCA,EAAO/J,UAGXxZ,KAAKwjB,aAAahK,QAClBxZ,KAAK8hB,eAAetI,QACpBxZ,KAAK4iB,qBAAuB,EAC5B5iB,KAAKwiB,aAAe,EACpBxiB,KAAK2f,YAAYnG,QACjBxZ,KAAK4hB,wBAEL5hB,KAAKyjB,eAAiBzjB,KAAKyjB,cAAcjK,QACzCxZ,KAAKye,SAASiF,QAAQC,gBAAkB3jB,KAAK4jB,sBAE7C5jB,KAAK6jB,kCACL7jB,KAAK8jB,+BAEL9jB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAevK,QAE3CxZ,KAAKgkB,uBAAuBxK,SAGhCyK,MAAO,SAASnK,GACZ,MAAO9Z,MAAKkkB,aAAapK,IAG7BqK,WAAY,SAASrK,EAAIsK,GACrB,GAAItM,GAAO9X,IAEX,OAAOL,IAAG0kB,OAAOhe,UAAU8d,WAAWrK,EAAIsK,GACtCte,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvBuJ,QAAS1hB,GAAG4P,KAAKuI,EAAKuJ,QAASvJ,GAC/B4H,WAAY5H,EAAK6H,eAIzB2E,iBAAkB,SAASC,EAASzK,GAChC9Z,KAAKwkB,oBAAoBC,IAAIF,EAASzK,IAG1C4K,oBAAqB,SAAS5K,EAAInV,GAC9B3E,KAAKgkB,uBAAuBS,IAAI9f,EAAMmV,IAG1C6K,2BAA4B,SAASJ,EAASzK,GAC1C9Z,KAAK4kB,8BAA8BH,IAAIF,EAASzK,IAGpD+K,sBAAuB,SAAS/G,EAAUhE,GACtC9Z,KAAK8kB,yBAAyBL,IAAI3G,EAAUhE,IAGhDiL,oBAAqB,SAASlH,EAAQ/D,GAClC9Z,KAAKglB,uBAAuBP,IAAI5G,EAAQ/D,IAI5CmL,YAAa,SAASnH,EAAUhE,GAC5B9Z,KAAK8hB,eAAe2C,IAAI3G,EAAUhE,IAGtCoL,QAAS,SAASC,GACdnlB,KAAKolB,4BAA4BD,IAGrCE,aAAc,SAASC,GACnBtlB,KAAK2iB,kBAAoB2C,GAG7BC,QAAS,SAASzL,EAAIuC,GAClBrc,KAAK2f,YAAYvD,WAAWtC,EAAIuC,IAGpCmJ,UAAW,SAAS3H,EAAQ/D,GACxB9Z,KAAKwjB,aAAaiB,IAAI5G,EAAQ/D,IAGlC2L,QAAS,SAAS3L,EAAIoC,GAClB,MAAOlc,MAAK2f,YAAY1D,YAAYnC,EAAIoC,IAY5CN,UAAW,SAAS9B,EAAI+B,GAEpB,IADiB7b,KAAKoiB,YAAYtI,GAAIA,IAElC,KAAM,IAAIna,IAAGwB,MAAM2Y,EAAK,2BAG5B,QAAQ+B,GACJ,IAAKlc,IAAGya,OAAOqD,QACXzd,KAAK0lB,kBAAkB5L,EAAI,MAAM,EACjC,MACJ,KAAKna,IAAGya,OAAOmD,cACXvd,KAAK0lB,kBAAkB5L,EAAI,MAAM,EACjC,MACJ,SACI,GAAI6L,GAAe,+BAAiCjkB,KAAO,6BAA+Bma,CAE1F,MADA7b,MAAK8F,IAAI6f,GACH,GAAIhmB,IAAGwB,MAAMwkB,KAI/BC,kBAAmB,WACgB,IAA3B5lB,KAAKqe,WAAW3Y,OAChB1F,KAAK6lB,WAAW,gBAGhB7lB,KAAK8lB,uBAQjBnmB,GAAGomB,gBAEC5H,eAAgB,SAAS6H,GACrB,GAAIlO,GAAO9X,IAEX,OAAOA,MAAK2f,YAAY7E,SACpBb,KAAM+L,EAAY/L,KAClBvY,KAAMskB,EAAYtkB,KAClBwZ,KAAM8K,EAAY9K,KAClBd,OAAQza,GAAGya,OAAOiD,kBAClB/B,qBAAsB,SAASxB,GAC3BkM,EAAYC,oBAAsBnO,EAAK+M,sBAAsBmB,EAAYC,mBAAoBnM,GAC7FkM,EAAYE,kBAAoBpO,EAAKiN,oBAAoBiB,EAAYE,iBAAkBpM,GAEnFkM,EAAYG,eACZrO,EAAKqJ,eAAerH,GAAMkM,EAAYG,cAG1CrO,EAAK0K,eACL1K,EAAK8K,2BAKjBwD,sBAAuB,SAASjL,EAAMkL,GAC9B1mB,GAAGuI,OAAOiT,KACVA,EAAKmL,WAAatmB,KAAKumB,aAAaF,KAI5CG,YAAa,SAASzgB,GAClB/F,KAAKye,SAASgI,UAAUC,QAAQ,KAAM,KAAM3gB,EAASjC,SAGzD6iB,qBAAsB,WAClB,GAAI7O,GAAO9X,IAEX,OAAO,IAAIL,IAAGinB,yBACVC,OAAQ7mB,KAAKye,SAAS4B,WAAWwG,OAAOC,cACxCC,eAAgB/mB,KAAKye,SAASsI,eAC9BC,cAAehnB,KAAKye,SAASwI,QAAQC,SACrCC,cAAennB,KAAK4kB,8BACpBwC,YAAapnB,KAAKglB,uBAClBqC,cAAernB,KAAK8kB,yBACpBwC,KAAMtnB,KAAKye,SAAS6I,KACpBxhB,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvByP,SAAU,SAASzN,GACfhC,EAAK0P,UAAU1N,GACfhC,EAAK2G,SAASgI,UAAUc,SAASzN,IAErC2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,GACrC7P,EAAK4N,kBAAkB5L,EAAI4N,EAAUC,GACrC7P,EAAK2G,SAASgI,UAAUgB,iBAAiB3N,EAAI4N,EAAUC,OAMnEC,oBAAqB,WACjB,GAAI9P,GAAO9X,IAEX,OAAO,IAAIL,IAAGkoB,cACVC,cAAe9nB,KAAKye,SAASsJ,MAAMD,cACnCrB,WACI3gB,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvBkQ,cAAe,SAAS/c,GACpB6M,EAAKmQ,wBACDvmB,KAAM,kBACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAUyB,gBAAiBpQ,EAAM7M,GACjE+L,UAAWrX,GAAG4P,KAAKuI,EAAKqQ,oBAAqBrQ,EAAM7M,GACnDmd,WAAY,sBAOhCC,aAAc,SAASC,EAAcC,GACjC,GAAIC,MACAC,EAAWH,EACXI,KACAC,EAAiBJ,EACjBK,EAAO,SAASC,GACZ,MAAIlpB,IAAGuG,SAAS2iB,GACLlpB,GAAG6B,UAAWqnB,GAElBA,GAEXC,EAAoB,WAChB,MAAInpB,IAAG6G,WAAWmiB,GACPA,IAEJA,GAEXI,EAAwB,SAASjP,EAAIkP,GAC7BL,GAAkBhpB,GAAGuG,SAAS8iB,IAC9BrpB,GAAG6B,OAAOwnB,EAAUF,KAGpBJ,EAAoB5O,IACpBna,GAAG6B,OAAOwnB,EAAUN,EAAoB5O,IAIpD,QACI2K,IAAK,SAAS7hB,EAAKkX,GAEL,MAANA,GACA0O,KACAC,EAAWG,EAAKhmB,IAGhB4lB,EAAM1O,GAAM8O,EAAKhmB,IAIzBmf,IAAK,SAASjI,GACV,GAAImP,EAYJ,OARIA,GADM,MAANnP,GAAc0O,EAAM1O,GACX0O,EAAM1O,GAGN8O,EAAKH,GAGlBM,EAAsBjP,EAAImP,GAEnBL,EAAKK,IAGhBC,YAAa,SAASpP,EAAImP,GAElBtpB,GAAGuG,SAASsiB,KAED,OAAP1O,EACIna,GAAG6G,WAAWyiB,GACdN,EAAiBM,GAGjBN,EAAiBA,MACjBhpB,GAAG6B,OAAOmnB,EAAgBM,KAI9BP,EAAoB5O,GAAM4O,EAAoB5O,OAC9Cna,GAAG6B,OAAOknB,EAAoB5O,GAAKmP,MAK/CloB,OAAQ,SAAS4f,GACb,aAAc6H,GAAM7H,IAGxBnH,MAAO,WACHgP,KACAE,KACAD,EAAWH,KAKvBa,yBAA0B,WACtB,GAAIrR,GAAO9X,IAEX,OAAO,IAAIL,IAAG8Z,YACVmG,QAAS,SAAS9F,GACd,MAAOhC,GAAK8H,QAAQ9F,IAExB+I,QAAS,SAAS/I,GACd,MAAOhC,GAAK+K,QAAQ/I,IAExBwI,QAAS,SAASxI,GACd,MAAOhC,GAAKwK,QAAQxI,IAExByB,eAAgB,SAASzB,EAAIgC,EAAWD,GACpC/D,EAAKsR,sBAAsBtP,EAAIgC,EAAWD,GAC1C/D,EAAK2G,SAASgI,UAAUlL,eAAezB,EAAIgC,EAAWD,GACtD/D,EAAKuR,kBAAkBvP,EAAI+B,GAEvB/D,EAAKiM,gBACLuF,WAAW,WACPxR,EAAKiM,eAAexI,eAAezB,EAAIgC,EAAWD,IACnD,OAcnB0N,oBAAqB,SAASxO,GAM1B,QAASyO,KACL,QAAI7pB,GAAG8S,kBAAkBoC,kBAEjBiD,EAAK2G,SAASgL,YAAYC,gBAC1B/pB,GAAGsO,QACFtO,GAAGqO,QACJ8J,EAAK6R,oBAAoBC,EAAmB,WAK1B9lB,SAAlBiX,EAAKvR,SACEsO,EAAK2G,SAASjV,SAGlBuR,EAAKvR,WApBpB,GAGI+Z,GAHAzL,EAAO9X,KACPiY,EAAc8C,EAAK8O,QAAU7pB,KAAKye,SAASqL,WAAW7R,YACtD2R,EAAoB7O,EAAK6O,mBAAqB5pB,KAAKye,SAASqL,WAAWF,iBA6C3E,OArBArG,GAAS,GAAI5jB,IAAG4X,cACZU,YAAaA,EACbrY,QAASmb,EAAKnb,QACdkZ,WAAY9Y,KAAKye,SAASsL,QAAQC,YAClChS,QAAS+C,EAAK/C,QACda,WAAY7Y,KAAKye,SAASsL,QAAQE,YAClClR,2BAA4B/Y,KAAKye,SAASgL,YAAYS,iBACtD1gB,SAAUggB,IACV9nB,KAAM1B,KAAKye,SAASwI,QAAQkD,UAC5BvR,SAAU,SAASvP,GACfyO,EAAKsS,eAAe/gB,IAExBwO,MAAqB,MAAdkD,EAAKlD,MAAgB7X,KAAKye,SAASpb,KAAKgnB,eAAiBtP,EAAKlD,QAGzE7X,KAAKsqB,gBAAgBpY,YAAY,WAC7BqR,EAAOxR,YAGX+F,EAAKwL,SAASzgB,KAAK0gB,GAEZA,GAGXgH,qBAAsB,SAASC,EAAmBC,GAC9C,GAAI3S,GAAO9X,KACP0qB,KACA9S,GACIoL,MAAOhjB,KAAKye,SAASuE,MACrB+D,eAAgB/mB,KAAKye,SAASsI,eAC9BO,KAAMtnB,KAAKye,SAAS6I,KACpBF,YAAapnB,KAAKwjB,aAClB6D,cAAernB,KAAK8hB,eACpB9M,SAAUhV,KAAKye,SAASzJ,SACxBc,OAAQ9V,KAAKye,SAAS3I,OACtB4I,MAAO1e,KAAKye,SAASC,MACrB5Y,IAAKnG,GAAG4P,KAAKuI,EAAKhS,IAAKgS,GACvB6S,kBAAmB3qB,KAAKye,SAASwF,MAAM2G,6BACvCC,WAAY,SAAS/Q,EAAIpY,EAAMopB,EAAQC,GAC/BD,EAAS,GAAKC,EAAQ,IAItBL,EAAe5Q,GACX4Q,EAAe5Q,GAAIgR,SAAWA,GAAUJ,EAAe5Q,GAAIiR,QAAUA,IACrEjT,EAAKkT,YAAYlR,EAAIpY,EAAMopB,EAAQC,GACnCjT,EAAK2G,SAASgI,UAAUoE,WAAW/Q,EAAIpY,EAAMopB,EAAQC,KAIzDjT,EAAKkT,YAAYlR,EAAIpY,EAAMopB,EAAQC,GACnCjT,EAAK2G,SAASgI,UAAUoE,WAAW/Q,EAAIpY,EAAMopB,EAAQC,IAGzDL,EAAe5Q,IAAOgR,OAAQA,EAAQC,MAAOA,KAGjDE,WAAY,SAASnR,EAAIpY,EAAMY,EAAQ4oB,SAC5BR,GAAe5Q,EAEtB,IACI5K,GADAkL,EAAStC,EAAKsK,YAAYtI,GAAIA,IAAKM,MAOnCA,KAAWza,GAAGya,OAAOiD,mBAAqBjD,IAAWza,GAAGya,OAAOkD,gBAInEpO,EAAS4I,EAAKqT,YAAYrR,EAAIpY,EAAMY,EAAQ4oB,GAIxChc,YAAmBvP,IAAG4L,QACtB2D,EAAOgI,KAAK,WACRY,EAAK2G,SAASgI,UAAUwE,WAAWnR,EAAIpY,EAAMY,EAAQ4oB,KAIzDpT,EAAK2G,SAASgI,UAAUwE,WAAWnR,EAAIpY,EAAMY,EAAQ4oB,KAG7DE,SAAU,SAAStR,EAAIpY,EAAM2pB,GACzB,GAAI/f,GAAU,GAAI3L,IAAG4L,OAgBrB,OAdAuM,GAAKmQ,wBACDvmB,KAAM,WACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAU2E,SAAUtT,EAAMgC,EAAIpY,GAC9DuV,UAAW3L,EAAQK,QACnBqL,UAAW,WACPqU,EAAyB5U,KAAK,WAC1BqB,EAAKwT,UAAUxR,EAAIpY,KAGvB4J,EAAQG,WAEZ2c,WAAYtO,IAGTxO,GAEXigB,aAAc5rB,GAAG4P,KAAKvP,KAAKwrB,cAAexrB,MAC1CyrB,SAAU,SAAS3R,EAAIpY,GACnBoW,EAAK4T,UAAU5R,EAAIpY,EACnB,IAAIiqB,GAAiB7T,EAAK2G,SAASgI,UAAUgF,SAAS3R,EAAIpY,EAE1D,OAAI/B,IAAG4W,iBAAiBoV,IACpB7T,EAAKhS,IAAInG,GAAG8H,OAAO,+DAAgEqS,IAC5E6R,IAGJ,GAAIhsB,IAAG4L,SAAUE,WAE5BmgB,cAAe,SAAS9R,EAAIpY,EAAMmqB,GAC9B/T,EAAKgU,eAAehS,EAAI+R,EACxB,IAAIE,GAAsBjU,EAAK2G,SAASgI,UAAUmF,cAAc9R,EAAIpY,EAAMmqB,EAE1E,OAAIlsB,IAAG4W,iBAAiBwV,IACpBjU,EAAKhS,IAAInG,GAAG8H,OAAO,uEAAwEqS,EAAI+R,EAAUG,YAClGD,IAGJ,GAAIpsB,IAAG4L,SAAUE,WAE5BwgB,qBAAsB,SAASnS,EAAI+R,EAAWvpB,EAAQ4oB,GAClDpT,EAAKoU,sBAAsBpS,EAAI+R,GAC/B/T,EAAK2G,SAASgI,UAAUwF,qBAAqBrc,MAAMkI,EAAMhQ,YAE7DqkB,SAAU,SAASrS,EAAIpY,EAAMmqB,EAAWO,GACpC,MAAOtU,GAAK2G,SAASgI,UAAU0F,SAASrS,EAAIpY,EAAMmqB,EAAWO,IAEjEC,YAAa,SAASvS,EAAIpY,EAAM4qB,EAAcpB,GAC1C,MAAOpT,GAAKyU,aAAa3c,MAAMkI,EAAMhQ,YAEzC0kB,cAAe,SAAS1S,EAAIoC,GACxBpE,EAAKhS,IAAI,sCAAwCgS,EAAK+K,QAAQ/I,GAAM,SAAWoC,EAAU,KACzFpE,EAAK2N,QAAQ3L,EAAIoC,IAErB0D,QAASjgB,GAAG4P,KAAKuI,EAAK8H,QAAS9H,GAC/B+K,QAASljB,GAAG4P,KAAKuI,EAAK+K,QAAS/K,GAC/BwK,QAAS3iB,GAAG4P,KAAKuI,EAAKwK,QAASxK,GAC/B2U,QAAS9sB,GAAG4P,KAAKuI,EAAK4U,SAAU5U,GAChC6U,cAAe,SAAS1S,GACpB,MAAOnC,GAAKsK,YAAYnI,KAAMA,KAElC2S,SAAU,SAAS9S,GACf,GAAIM,GAAStC,EAAKsK,YAAYtI,GAAIA,IAAKM,MACvC,OAAOA,KAAWza,GAAGya,OAAO2C,QACxB3C,IAAWza,GAAGya,OAAOyC,WACrBzC,IAAWza,GAAGya,OAAOgD,iBACrBhD,IAAWza,GAAGya,OAAO6C,QAE7BN,mBAAoB7E,EAAK6H,YAAYhD,mBACrCC,cAAe9E,EAAK6H,YAAY/C,cAChCiQ,aAAc,SAAS/S,GACnB,MAAOhC,GAAKsK,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAO8C,WAE1D4P,oBAAqBntB,GAAG4P,KAAKuI,EAAKiV,qBAAsBjV,GACxD8D,UAAW,SAAS9B,EAAIM,GACpBtC,EAAK6H,YAAY/D,UAAU9B,EAAIM,IAgB3C,OAZAza,IAAG+C,KAAK1C,KAAKye,SAASwI,QAAS,SAASlb,EAAMnJ,GAC1CgV,EAAQ7L,GAAQnJ,IAGpBgV,EAAQuP,cAAgBnnB,KAAKwkB,oBAEzBgG,GACA7qB,GAAG+C,KAAK8nB,EAAmB,SAASpb,EAAKxM,GACrCgV,EAAQxI,GAAOxM,IAIhB,GAAIjD,IAAGqtB,wBAAwBpV,EAAS6S,IAGnDwC,oBAAqB,SAASnT,GAC1B9Z,KAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO0C,WAG7CoQ,YAAa,SAASriB,GAClB,GAAc,IAAVA,EACA,MAAOA,GAAQ7K,KAAKye,SAASpb,KAAK8pB,YAAY,EAElD,IAAI9c,IAAI,CACR,GACIxF,IAAgB,IAChBwF,UACKxF,EAAQ,IAEjB,OAAOvJ,MAAK8rB,IAAIviB,EAAO,IAAKwiB,QAAQ,GAAKrtB,KAAKye,SAASpb,KAAK8pB,YAAY9c,IAK5Eid,0BAA2B,WACvB,GAAIxV,GAAO9X,IAEXA,MAAKutB,qBAEL5tB,GAAG+C,KAAK1C,KAAKye,SAAS+O,aAAc,SAAS7qB,EAAK8qB,GAC9C,GAAIjkB,GAAWikB,EAAuBjkB,SAClCsgB,EAAanqB,GAAG6B,UAAWsW,EAAK2G,SAASqL,YAAY,GACrD4D,EAAkB/tB,GAAG6B,UAAWisB,EAEnB3pB,UAAb0F,IACAA,EAAWsO,EAAK2G,SAASjV,UAGzBkkB,EAAgB5D,YAChBnqB,GAAG6B,OAAOsoB,EAAY2D,EAAuB3D,YAAY,GAG7DnqB,GAAG6B,OAAOksB,GACNlkB,SAAUA,EACVsgB,WAAYA,IACb,GAEHhS,EAAK6V,iBAAiBD,MAI9B/L,WAAY,SAAShK,GACjB,GAAIiW,GAAmB5tB,KAAKutB,kBAAkB5V,EAE9C,OAAIiW,GACOA,EAAiBhuB,QAEnB+X,IAAa3X,KAAK6tB,iBAChB7tB,KAAKye,SAAS8E,OADpB,QAYTgD,aAAc,SAASuH,GACnB,GAAIC,GAAQC,EACRC,EAAkBH,CAQtB,IALIG,YAA2BtuB,IAAGwX,YAC9B8W,EAAkBA,EAAgB7W,eAIlC6W,IAAoBtuB,GAAGuJ,OAAO+kB,GAAkB,CAChD,GAAItuB,GAAGuI,OAAO+lB,GACV,MAAOA,GAAgB3H,UAEtB,IAA8C,UAA1C2H,EAAgBhlB,QAAQF,eACU,SAAvCklB,EAAgB/tB,KAAK6I,cAErB,MAAOklB,GAAgBpqB,aAAalE,GAAG4X,aAAaG,oBAYxD,IATAqW,EAASE,EAAgBxrB,qBAAqB,SAE9C9C,GAAG+C,KAAKqrB,EAAQ,SAASprB,EAAK0G,GAC1B,GAAmC,SAA/BA,EAAMxF,aAAa,QAEnB,MADAmqB,GAAY3kB,GACL,IAIX2kB,EACA,MAAOA,GAAUnqB,aAAalE,GAAG4X,aAAaG,uBAK1DqV,qBAAsB,SAASpM,GAC3B,MAAO3gB,MAAKgkB,uBAAuBjC,IAAIpB,IAG3CuN,gBAAiB,WACb,MAAOluB,MAAK2f,YAAYnE,UACpBpB,QACIza,GAAGya,OAAO8C,UACVvd,GAAGya,OAAOgD,gBACVzd,GAAGya,OAAO2C,OACVpd,GAAGya,OAAOY,WACVrb,GAAGya,OAAOyC,UACVld,GAAGya,OAAO6C,UAEfvX,QAKPyoB,mBAAoB,SAASxW,GACzB,GAAI+V,GAAkB1tB,KAAKutB,kBAAkB5V,EAE7C,OAAO+V,GAAkBA,EAAgB5D,WAAa9pB,KAAKye,SAASqL,YAGxEsE,yBAA0B,SAASC,GAC/B,MAAIA,GAAYlT,eAAgBxb,IAAGwX,WAE3BzV,KAAM/B,GAAG+R,YAAY2c,EAAYlT,KAAK/D,eACtC8D,KAAMmT,EAAYlT,KAAK/D,cAAc8D,OAKzCxZ,KAAM1B,KAAKoiB,YAAYtI,GAAIuU,EAAYvU,KAAKpY,KAC5CwZ,KAAMlb,KAAKoiB,YAAYtI,GAAIuU,EAAYvU,KAAKoB,OAIpDoT,0BAA2B,SAASC,GAChC,GAAIzW,GAAO9X,KACPwuB,IAMJ,OAJA7uB,IAAG+C,KAAK6rB,EAAc,SAAS5rB,EAAK0rB;gCAChCG,EAAgB3rB,KAAKiV,EAAKsW,yBAAyBC,MAGhDG,GAIXC,oBAAqB,WACjB,GAAIzuB,KAAKye,SAASiQ,OAAOzgB,KAAOtO,GAAGsO,MAAO,CACtC,GACIsV,GAASvjB,KAAKye,SAASiQ,OAAOnL,OAC9B5L,EAAW4L,EAASvjB,KAAKumB,aAAahD,GAAUvjB,KAAK6tB,iBACrDc,EAAa3uB,KAAKye,QAGlB9G,IAAYA,IAAa3X,KAAK6tB,mBAC9Bc,EAAa3uB,KAAKutB,kBAAkB5V,IAIxCgX,EAAWnlB,UAAW,EAGoB,OAAtCmlB,EAAW7E,WAAW7R,YACtB0W,EAAW7E,WAAW7R,YAfJ,yBAkBlB0W,EAAW7E,WAAW7R,aAAe,0BAIzCtY,GAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjC,GAAIA,EAAOpK,gBAAkBxB,EAIzB,MAHA4L,GAAOxL,YAAY4W,EAAWnlB,UAC9B+Z,EAAOhK,eAAeoV,EAAW1W,cAE1B,MAMvBgQ,uBAAwB,SAAS2G,GAC7B,GAAI9W,GAAO9X,KACP6uB,EAAiBD,EAAQ5f,UAE7B,OAAIrP,IAAG4W,iBAAiBsY,IACpB7uB,KAAK8F,IAAI8oB,EAAQltB,KAAO,kBAAoBktB,EAAQltB,KAAO,gCAAkCktB,EAAQxG,YAC9FyG,EAAepY,KAClB,SAASqY,GACLhX,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,YAC1DwG,EAAQ5X,UAAU8X,IAEtB,WACQF,EAAQ3X,WACRa,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,YAC1DwG,EAAQ3X,aAGRa,EAAKhS,IAAI8oB,EAAQltB,KAAO,wBAA0BktB,EAAQxG,gBAKtEyG,KAAmB,EACnBD,EAAQ5X,UAAU6X,GAGdD,EAAQ3X,WACRjX,KAAK8F,IAAI8oB,EAAQltB,KAAO,mCAAqCktB,EAAQxG,WAAa,iCAClFwG,EAAQ3X,aAGRjX,KAAK8F,IAAI8oB,EAAQltB,KAAO,mCAAqCktB,EAAQxG,WAAa,wBAInFyG,IAIXrQ,eAAgB,SAASrD,EAAMC,EAAS2T,GACpC,GAAIjX,GAAO9X,KACPia,EAAOta,GAAGiN,cACVsO,GAAO,EACPxZ,EAAO/B,GAAG+R,YAAYyJ,GACtB6T,EAAa7T,EAAKlQ,MAAQkQ,EAC1B8T,EAAUjvB,KAAKkvB,sBACXlvB,KAAKkvB,sBACLvvB,GAAG4P,KAAKuI,EAAKqX,sBAAuBrX,IAEvCnY,GAAG+I,QAAQsmB,IAAeA,EAAW9T,MAAQ,IAC9CA,EAAO8T,EAAW9T,MAGtB+T,EAAQD,EAAYttB,EAAMuY,EAAMiB,EAAM6T,EAAoB3T,EAASpb,KAAKye,SAASwI,QAAQC,UACrFxH,WAAY5H,EAAK6H,YACjByH,YAAatP,EAAK0L,aAClB4L,iBAAkB,SAAStV,EAAIqB,GAC3BrD,EAAK+H,SAAS1P,IAAI2J,EAAIqB,GACtBrD,EAAK8K,uBACL9K,EAAKuX,aAAavV,OAK9BqV,sBAAuB,SAAShU,EAAMzZ,EAAMuY,EAAMiB,EAAMoU,EAAUlU,GAC9D,GAAItB,GAAK9Z,KAAK2f,YAAY7E,SACtBb,KAAMA,EACNvY,KAAMA,EACNwZ,KAAMA,EACNE,QAASA,EACTD,KAAMA,GAGVnb,MAAK6f,SAAS1P,IAAI2J,EAAIqB,GAEtBnb,KAAKqvB,aAAavV,GAElB9Z,KAAK4iB,uBAEL0M,EAASzsB,MAAMiX,GAAIA,EAAIqB,KAAMA,KAGjCgN,oBAAqB,SAASld,EAAMskB,GAChC,GAAIC,GAAYvkB,EAAK/K,KAAKmF,MAAM,KAAK,GACjC3D,EAAO6tB,CAGC,OAAR7tB,IACAA,EAAO1B,KAAKye,SAASsJ,MAAMpJ,aAG/Bjd,GAAQ,IAAM8tB,EAEdxvB,KAAK+d,UACDrc,KAAMA,EACNuJ,KAAMA,KAIdwkB,qBAAsB,SAAS3V,GAC3B,GAAI9Z,KAAKoiB,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAOqD,QAAS,CACxD,GAAI/b,GAAO1B,KAAK4f,QAAQ9F,EAExB9Z,MAAK4iB,uBACL5iB,KAAKwiB,eACLxiB,KAAK6f,SAASqD,QAAQpJ,GACtB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOqD,SACzCzd,KAAK8F,IAAI,uBAAyBpE,EAAO,sBAIjDguB,oBAAqB,SAAS5V,EAAI4N,GAC9B,GAAIhmB,GAAO1B,KAAK4f,QAAQ9F,EAExB9Z,MAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOmD,eACzCvd,KAAK8F,IAAI,uBAAyBpE,EAAO,gBAAiB,SAKrDgmB,GAAyC5jB,SAA7B4jB,EAASxU,gBAItBlT,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,4CAA8CgmB,EAAStN,OAAQsN,GAHzG1nB,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,wBAAyBgmB,IAQ3EiG,iBAAkB,SAAS5S,GACvB,GAAIwI,GAASvjB,KAAKupB,qBACdM,OAAQ9O,EAAK+O,WAAW7R,YACxB2R,kBAAmB7O,EAAK+O,WAAWF,kBACnChqB,QAASmb,EAAKnb,QACdoY,QAAS+C,EAAK/C,QACdxO,SAAUuR,EAAKvR,SACfqO,MAAOkD,EAAKsP,gBAGhBrqB,MAAKutB,kBAAkBhK,EAAOpK,eAAiB4B,GAGnD4U,0BAA2B,WACvB3vB,KAAK4vB,aAAejwB,GAAGkwB,aAAe,GAAIlwB,IAAGkwB,YACzC7vB,KAAKye,SAAS5N,KAAMlR,GAAG4P,KAAKvP,KAAK4lB,kBAAmB5lB,MAAOL,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OAG7EA,KAAK4vB,cAAgB5vB,KAAK4vB,aAAaE,gBACvC9vB,KAAKwjB,aAAexjB,KAAKqoB,aACrBroB,KAAKye,SAASwI,QAAQpJ,OAAS7d,KAAK4vB,aAAaG,uBAGrD/vB,KAAKye,SAASuR,WAAahwB,KAAK4vB,aAAaK,cACzCjwB,KAAK4vB,aAAaM,cAClBlwB,KAAKye,SAASwI,QAAQnJ,SAAW9d,KAAK4vB,aAAaM,cAIvDlwB,KAAKwjB,aAAexjB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQpJ,SAIpEsS,kBAAmB,WACf,SAAKxwB,GAAGinB,0BAA4B5mB,KAAKye,SAAS4B,WAAWF,YAIzDngB,KAAKye,SAAS6I,KAAK8I,aACfzwB,GAAG8S,kBAAkB0C,sBAIrBxV,GAAG8S,kBAAkByC,oBAAqBlV,KAAKye,SAAS6I,KAAK+I,aAUzE1G,oBAAqB,SAAS2G,EAAS1e,GACnC,GAAI2e,IAAQ,CAEZ,QAAKD,EAAQ5qB,SAIb/F,GAAG+C,KAAK4tB,EAAS,SAAS3tB,EAAK6tB,GAK3B,GAAI7wB,GAAGwH,SAASqpB,GAAa,CAEzB,GAAIC,GAAW,GAAI5uB,QAAO,MAAQ2uB,EAAa,IAAK,IAEpD,IAAgC,MAA5B5e,EAASoB,MAAMyd,GAEf,MADAF,IAAQ,GACD,KAKZA,IAWX1K,WAAY,SAAS6K,EAAMC,EAAkB1pB,GASzC,QAAS6F,GAAEpL,EAAMkvB,GAAe7qB,EAAUA,EAAQ7D,QAAQR,EAAMkvB,GARhE,GAMIC,GAAsBC,EANtB/qB,EAAU/F,KAAKye,SAASsS,SAASL,GACjC9G,KACAoH,KAAWrhB,OAAOghB,GAClBjvB,EAAOsvB,EAAM,GACbrZ,EAAW3X,KAAKumB,aAAatf,GAC7BgqB,EAAiBjxB,KAAKmuB,mBAAmBxW,EA+B7C,OA1BAhY,IAAG+C,KAAKuuB,EAAerH,kBAAmB,SAASjnB,EAAKuuB,GAKhDvxB,GAAGwH,SAAS+pB,IACZtH,EAAkB/mB,KAAKquB,KAI/BL,EAAuBjH,EAAkBpZ,KAAK,MAAMzH,cAEpD+D,EAAE,SAAU9M,KAAKye,SAAS0S,eAAezvB,IACzCoL,EAAE,eAAgB+jB,GAClB/jB,EAAE,cAAe9M,KAAKktB,YAAY+D,EAAeG,YACjDtkB,EAAE,iBAAkB9M,KAAKktB,YAAY+D,EAAeI,eAEpDP,EAAmB/qB,EAAQiN,MAAM,cACR,OAArB8d,GACAnxB,GAAG+C,KAAKouB,EAAkB,SAASnuB,EAAK2uB,GACpCxkB,EAAEwkB,EAAaN,EAAMruB,MAI7B3C,KAAKye,SAASgI,UAAUC,QAAQ,KAAMhlB,EAAMqE,EAASjC,QAE9CiC,GAYXme,aAAc,SAASpK,EAAI9K,GACvB,GAAIhP,KAAKuxB,qBAAqBzX,GAW1B,MAVA9Z,MAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOgD,iBAErCpO,EACAA,EAAS8K,GAGT9Z,KAAK6f,SAASoE,MAAMnK,IAGjB,GAIfuP,kBAAmB,SAASvP,EAAIM,GAC5B,GAAItC,GAAO9X,KACPwxB,EAAcxxB,KAAKkuB,iBAEnB9T,KAAWza,GAAGya,OAAOiD,kBACrBrd,KAAK6jB,+BAA+BhhB,KAAKiX,GAEpCM,IAAWza,GAAGya,OAAOkD,eAC1Btd,KAAK8jB,4BAA4BjhB,KAAKiX,GAGtB,IAAhB0X,IACCxxB,KAAK6jB,+BAA+Bne,QAAU1F,KAAK8jB,4BAA4Bpe,SAEhF4jB,WAAW,WACPxR,EAAK2Z,eAAe3Z,EAAK+L,+BAAgC/L,EAAKgM,8BAC/D,IAIX1F,iCAAkC,WAC9B,GAAItG,GAAO9X,IAEX,IAAIA,KAAKye,SAASgL,YAAYiI,mBAAqB/xB,GAAGyO,UAAYzO,GAAG2O,YAIjE,KAHAgb,YAAW,WACPzkB,OAAO8sB,MAAM7Z,EAAK2G,SAASsS,SAASa,+BACrC,GACG,GAAIjyB,IAAGwB,MAAMnB,KAAKye,SAASsS,SAASa,+BAIlDC,8BAA+B,SAAS/X,EAAIpY,EAAMowB,EAAU5G,GAGxD,IAAK4G,EAASrmB,QACV,GAAIyf,GAAsB,MAAfA,EAAI9Q,SAAmB0X,EAAShoB,MACvC9J,KAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAM,8BAAgCwpB,EAAI9Q,OAAQ8Q,OAErF,CACD,GAAI6G,GAAcD,EAAShoB,MAAQgoB,EAAShoB,MAAQ9J,KAAKye,SAASpb,KAAK2uB,oBACvEhyB,MAAKye,SAASgI,UAAUC,QAAQ5M,EAAIpY,EAAMqwB,EAAa7G,KAKnE+G,6CAA8C,SAASC,EAAWjoB,EAAOsQ,EAAOsD,EAAQC,GACpF,GAAIhG,GAAO9X,IAEX,IAAIiK,EAAMvE,OAAS6U,EACf,GAAI2X,IAAclyB,KAAKye,SAASqL,WAAWqI,uBAEvC7I,WAAW,WACP,GAAI8I,GAAuBta,EAAKsW,yBAAyBnkB,EAAMsQ,IAC3D5C,EAAWG,EAAKyO,aAAatc,EAAMsQ,GAAOY,MAC1CoI,EAASzL,EAAK6J,WAAWhK,EAE7BG,GAAKmQ,wBACDvmB,KAAM,aACNsN,SAAUrP,GAAG4P,KAAKuI,EAAK2G,SAASgI,UAAU4L,WAAYva,EAAMsa,EAAsB7O,GAClFvM,UAAWrX,GAAG4P,KAAKuI,EAAKwa,2BAA4Bxa,EAAM7N,EAAOsQ,EAAOsD,EAAQC,GAChF7G,UAAWtX,GAAG4P,KAAKuI,EAAKya,2BAA4Bza,EAAM7N,EAAOsQ,EAAOsD,EAAQC,GAChFsK,WAAY,SAAWgK,EAAqB1wB,KAAO,YAAc0wB,EAAqBlX,QAE3F,OAEF,KAAKgX,EACN,KAAO3X,EAAQtQ,EAAMvE,OAAQ6U,IACzBzC,EAAKmV,oBAAoBhjB,EAAMsQ,GAAOT,KAMtD2X,eAAgB,SAASe,EAAYC,GACjCzyB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAe2O,cAAcF,EAAYC,EAAQzyB,KAAKqjB,iBAElFrjB,KAAKye,SAASgI,UAAUiM,cAAc/yB,GAAG6B,UAAWgxB,GAAa7yB,GAAG6B,UAAWixB,IAE/EzyB,KAAK6jB,kCACL7jB,KAAK8jB,gCAeTyI,aAAc,SAASzS,EAAIpY,EAAM4qB,EAAcpB,EAAKlc,GAChD,GAAI8I,GAAO9X,IAIX,IAFA8X,EAAKuL,gBAAgBvJ,GAAMwS,EAAaxU,EAAK2G,SAASwF,MAAM2G,8BAExD9S,EAAK6a,iBAAiB7Y,GAAK,CAC3B,GAAI8Y,GAAyD,IAAvC9a,EAAK2G,SAASwF,MAAM4O,gBAkB1C,OAhBA/a,GAAK+Z,8BAA8BjiB,MAAMkI,EAAMhQ,WAC/CgQ,EAAK2G,SAASgI,UAAU4F,YAAYvS,EAAIpY,EAAMoW,EAAKqL,aAAarJ,IAChEhC,EAAKgb,mBAAmBhZ,EAAIpY,GAE5BoW,EAAK6H,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOgD,iBACzCtF,EAAKsL,eAAetJ,GAAMwP,WAAW,WACjCxR,EAAKhS,IAAI,sBAAwBpE,EAAO,OAEpCsN,EACAA,EAAS8K,GAGThC,EAAK+H,SAASoE,MAAMnK,IAEzB8Y,IAEI,IAIfE,mBAAoB,SAAShZ,EAAIpY,GAC7B1B,KAAK8F,IAAI,WAAa9F,KAAKye,SAASwF,MAAM4O,iBAAmB,4BAA8BnxB,EAAO,QAItG6vB,qBAAsB,SAASzX,GAC3B,GACIlI,GADAmhB,EAAY/yB,KAAK2iB,iBAGrB,OAAI3iB,MAAKqjB,gBAAgBvJ,IACrB9Z,KAAK8F,IAAI,gCAAkCgU,EAAI,SACxC,GAEF9Z,KAAK6f,SAASY,QAAQ3G,IAC3BlI,EAAW5R,KAAK4f,QAAQ9F,GAEpB9Z,KAAKye,SAASgI,UAAUuM,cAAclZ,EAAIlI,MAAc,IAIxDmhB,EAAY,GAAK/yB,KAAK4iB,qBAAuB,EAAImQ,GACjD/yB,KAAK6lB,WAAW,0BACT,IAGX7lB,KAAK8F,IAAI,wBAA0B8L,EAAW,UAAYkI,EAAK,SACxD,MAGP9Z,KAAK8F,IAAI,IAAMgU,EAAK,2BAA4B,UACzC,IAIfwR,UAAW,SAASxR,EAAIpY,GACpB1B,KAAK4iB,uBAELqQ,aAAajzB,KAAKojB,eAAetJ,GAEjC,IAAIoZ,GAAkBvzB,GAAG2F,QAAQtF,KAAKqe,WAAYvE,IAC7C9Z,KAAKye,SAASuR,YAAckD,GAAmB,GAChDlzB,KAAKqe,WAAWrC,OAAOkX,EAAiB,GAG5ClzB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO4C,WAG7CmO,YAAa,SAASrR,EAAIpY,EAAMY,EAAQ4oB,GAoBpC,MAnBK5oB,GAAOmJ,SASJnJ,EAAO6jB,eACPnmB,KAAKmhB,eAAerH,GAAMxX,EAAO6jB,cAGrCnmB,KAAKwiB,eACLxiB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOiD,qBAbzCrd,KAAK4iB,uBACL5iB,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOkD,eAErChb,EAAOtC,KAAKye,SAASwF,MAAM2G,iCAAkC,IAC7D5qB,KAAKqjB,gBAAgBvJ,IAAM,IAYnC9Z,KAAK6xB,8BAA8B/X,EAAIpY,EAAMY,EAAQ4oB,KAE9C5oB,EAAOmJ,SAGlB+b,UAAW,SAAS1N,GAChB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOoD,WAG7CkI,kBAAmB,SAAS5L,EAAI4N,EAAUC,GAC3B3nB,KAAK4f,QAAQ9F,EAEpB6N,GACA3nB,KAAK0vB,oBAAoB5V,EAAI4N,GAG7B1nB,KAAKyvB,qBAAqB3V,IAIlCsQ,eAAgB,SAAS/gB,GACrB,GAAI8pB,EAEJ,IAAIxzB,GAAG8S,kBAAkBoC,cAAe,CACpC,IAAKse,EAAY,EAAGA,EAAY9pB,EAAMgW,MAAM3Z,OAAQytB,IAChDnzB,KAAKomB,sBAAsB/c,EAAMgW,MAAM8T,GAAY9pB,EAGvDrJ,MAAK+d,SAAS1U,EAAMgW,WAGfhW,GAAM3C,MAAMhB,OAAS,GAC1B1F,KAAK+d,SAAS1U,EAGlB1J,IAAG+C,KAAK1C,KAAKsjB,SAAU,SAAS3gB,EAAK4gB,GACjCA,EAAO/J,WAIfwR,YAAa,SAASlR,EAAIpY,EAAMopB,EAAQC,GACpC/qB,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAeqP,qBAAqBtZ,EAAIgR,EAAQC,IAGhFsI,UAAW,SAASvZ,EAAIpY,KAIxB4xB,yBAA0B,SAASxZ,EAAIpY,GACnC1B,KAAKqzB,UAAUzjB,MAAM5P,KAAM8H,WAC3B9H,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAOyC,WACzC7c,KAAKuzB,aAAa3jB,MAAM5P,KAAM8H,WAE1B9H,KAAKye,SAASuR,YACdhwB,KAAKye,SAASgI,UAAU+M,YAAY5jB,MAAM5P,KAAM8H,WAChD9H,KAAKogB,YAAYtG,KAGjB9Z,KAAKyzB,eAAe3Z,GACpB9Z,KAAKye,SAASgI,UAAU+M,YAAY5jB,MAAM5P,KAAM8H,aAIxDwY,gBAAiB,SAASxG,EAAI4Z,EAAmBC,GAC7C,GACIC,GADA3Z,EAAOja,KAAK6iB,QAAQ/I,EAOxB,OAJI4Z,KACAE,EAA4Bj0B,GAAG4P,KAAKmkB,EAAmB1zB,KAAM8Z,EAAIG,EAAM0Z,IAGvE3zB,KAAKmwB,qBACLnwB,KAAKioB,wBACDvmB,KAAM,iBACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAUoN,eAAgB7zB,KAAM8Z,GAChE9C,UAAW4c,GACPj0B,GAAG4P,KAAKvP,KAAK8zB,eAAeC,WAAY/zB,KAAM8Z,EAAIG,EAAM0Z,GAC5DvL,WAAYtO,KAET,IAGP9Z,KAAK8F,IAAI,iCAAmCgU,EAAK,wHACuB,SACjE,IAIfyZ,aAAc,SAASzZ,KAIvBka,iBAAkB,SAASlJ,EAAQC,GAC/B/qB,KAAKye,SAASgI,UAAUwN,gBAAgBnJ,EAAQC,IAGpDS,cAAe,SAAS1R,KAIxB4R,UAAW,SAAS5R,EAAIpY,GACpB1B,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO8C,YAG7C4O,eAAgB,SAAShS,EAAI+R,KAI7BK,sBAAuB,SAASpS,EAAI+R,IAC3B7rB,KAAKqjB,gBAAgBvJ,IAAO9Z,KAAKye,SAASwF,MAAMiQ,aACjDl0B,KAAKmjB,aAAarJ,GAAM,IAIhCsP,sBAAuB,SAAStP,EAAIgC,EAAWD,GAEvCA,IAAclc,GAAGya,OAAO6C,QACxBgW,aAAajzB,KAAKojB,eAAetJ,KAIzCqa,gCAAiC,SAAS5F,GACtC,GAAIzW,GAAO9X,IAEXL,IAAG+C,KAAK6rB,EAAc,SAAS5rB,EAAK0rB,GAChCvW,EAAKmV,oBAAoBoB,EAAYvU,OAI7Csa,gCAAiC,SAASC,EAAuBpqB,EAAO4T,EAAQC,EAAUyF,GACtF,GAAIoC,GACAoN,EAAY/yB,KAAK2iB,kBACjB2R,EAAmCt0B,KAAK4iB,oBAE1B,KAAdmQ,GAAmBuB,GAAoCvB,EACnD9oB,EAAMvE,OAAS,EACf1F,KAAKioB,wBACDvmB,KAAM,aACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAU4L,WAAYryB,KAAMq0B,EAAsB,GAAI9Q,GACtFvM,UAAWrX,GAAG4P,KAAKvP,KAAKsyB,2BAA4BtyB,KAAMiK,EAAO,EAAG4T,EAAQC,GAC5E7G,UAAWtX,GAAG4P,KAAKvP,KAAKuyB,2BAA4BvyB,KAAMiK,EAAO,EAAG4T,EAAQC,GAC5EsK,WAAY,SAAWne,EAAM,GAAGkR,KAAKzZ,KAAO,YAAcuI,EAAM,GAAGkR,KAAKD,OAI5Elb,KAAK6lB,WAAW,iBAIpB7lB,KAAKm0B,gCAAgClqB,GACrC0b,EAAe3lB,KAAKye,SAASsS,SAASwD,kBACjCryB,QAAQ,gBAAiBoyB,GACzBpyB,QAAQ,iBAAkB6wB,GAC/B/yB,KAAKwmB,YAAYb,KAIzB4M,2BAA4B,SAAStoB,EAAOsQ,EAAOsD,EAAQC,GACvD,GAAI0W,GAAYja,EAAQ,CAExBva,MAAKitB,oBAAoBhjB,EAAMsQ,GAAOT,GAAI7P,EAAMsQ,GAAOY,KAAKzZ,MAE5D1B,KAAKiyB,8CAA6C,EAAOhoB,EAAOuqB,EAAW3W,EAAQC,IAGvFwU,2BAA4B,SAASroB,EAAOsQ,EAAOsD,EAAQC,GACvD,GAAIhG,GAAO9X,KACPw0B,EAAYja,EAAQ,EACpB6X,EAAuBpyB,KAAKouB,yBAAyBnkB,EAAMsQ,GAE/Dva,MAAKy0B,wBAAwBxqB,EAAMsQ,GAAQ6X,GACtC3b,KACD,WACIqB,EAAK4c,QAAQzqB,EAAMsQ,GAAOT,GAAI+D,EAAQC,GACtChG,EAAKma,8CAA6C,EAAMhoB,EAAOuqB,EAAW3W,EAAQC,IAEtF,WACIhG,EAAKma,8CAA6C,EAAOhoB,EAAOuqB,EAAW3W,EAAQC,MAK/F0B,uBAAwB,SAASvV,EAAO4T,EAAQC,GAC5C,GAAqB,IAAjB7T,EAAMvE,OAEN,WADA1F,MAAK6lB,WAAW,eAIpB,IAAIwO,GAAwBr0B,KAAKsuB,0BAA0BrkB,GACvD0N,EAAW3X,KAAKumB,aAAatc,EAAM,GAAGkR,MACtCoI,EAASvjB,KAAK2hB,WAAWhK,EAE7B3X,MAAKioB,wBACDvmB,KAAM,kBACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAUkO,gBAAiB30B,KAAMq0B,EAAuB9Q,GACxFvM,UAAWrX,GAAG4P,KAAKvP,KAAKo0B,gCAAiCp0B,KAAMq0B,EAAuBpqB,EAAO4T,EAAQC,EAAUyF,GAC/GtM,UAAWtX,GAAG4P,KAAKvP,KAAKm0B,gCAAiCn0B,KAAMiK,GAC/Dme,WAAY,sBAIpBwM,wBAAyB,WACrB,GAAI9c,GAAO9X,IAEXA,MAAKsqB,gBAAgBrqB,OAAO4E,OAAQ,eAAgB,SAAS4J,GACzD,GAAIqJ,EAAKmK,gBAKL,MAJAxT,GAAIA,GAAK5J,OAAOgwB,MAEhBpmB,EAAEC,YAAcoJ,EAAK2G,SAASsS,SAAS+D,QAEhChd,EAAK2G,SAASsS,SAAS+D,WAQ1ClR,oBAAqB,WACjB,GAAI9L,GAAO9X,KACP4X,EAAU5X,KAAKye,SAASiF,OAGxB/jB,IAAGo1B,SAA6C,MAAlC/0B,KAAKye,SAASiF,QAAQ5F,WAC/B9d,KAAKg1B,WACNr1B,GAAG6B,OAAOoW,GAAU0P,KAAMtnB,KAAKye,SAAS6I,OAExC1P,EAAQ9R,IAAMnG,GAAG4P,KAAKvP,KAAK8F,IAAK9F,MAChC4X,EAAQqd,cAAgBt1B,GAAG4P,KAAKvP,KAAKme,eAAgBne,MAErDA,KAAKg1B,SAAW,GAAIr1B,IAAGo1B,QAAQnd,IAGnC0R,WAAW,WACPxR,EAAKkd,SAASE,UAAUze,KAAK,SAASqb,EAAUpK,GAC5C5P,EAAKqd,0BACLrd,EAAK2G,SAASgI,UAAU2O,yBAAyBtD,GAAU,EAAMpK,IAElE,SAASoK,EAAUpK,GAElB5P,EAAK2G,SAASgI,UAAU2O,yBAAyBtD,GAAU,EAAOpK,MAEvE,KAIXyN,wBAAyB,aAEzBzI,SAAU,SAAS5S,EAAIyC,GACnBvc,KAAK2f,YAAYrD,WAAWxC,EAAIyC,GAChCvc,KAAK+jB,gBAAkB/jB,KAAK+jB,eAAesR,UAAUvb,IAGzD6Y,iBAAkB,SAAS7Y,GACvB,GAAI4F,GAAa1f,KAAK2f,YAAYnE,UAAU1B,GAAIA,GAGhD,WAAK9Z,KAAKqjB,gBAAgBvJ,IACnB9Z,KAAKye,SAASwF,MAAMiQ,YACpBxU,EAAWtF,SAAWza,GAAGya,OAAO6C,SAELnZ,SAA1B9D,KAAKmjB,aAAarJ,KAClB9Z,KAAKmjB,aAAarJ,GAAM,GAGxB9Z,KAAKmjB,aAAarJ,GAAM9Z,KAAKye,SAASwF,MAAMqR,oBAC5Ct1B,KAAKmjB,aAAarJ,IAAO,GAClB,IAOnB2Z,eAAgB,SAAS3Z,GACrB9Z,KAAKqe,WAAWxb,KAAKiX,IAIzBuV,aAAc,SAASvV,GACnB,GAAInC,EAGAA,GADAhY,GAAG8S,kBAAkBoC,cACV7U,KAAK6f,SAASwB,QAAQvH,GAAIwM,WAG1BtmB,KAAKumB,aAAavmB,KAAK6f,SAAS3G,SAASY,IAGpDnC,IACA3X,KAAK4hB,qBAAqB9H,GAAMnC,IAIxCyN,4BAA6B,SAASmQ,GAClCv1B,KAAKye,SAAS5N,KAAKjR,QAAU21B,EAE7Bv1B,KAAK4vB,aAAejwB,GAAGkwB,aAAe,GAAIlwB,IAAGkwB,YACrC7vB,KAAKye,SAAS5N,KAAMlR,GAAG4P,KAAKvP,KAAK4lB,kBAAmB5lB,MAAOL,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OAGjFA,KAAK4vB,cAAgB5vB,KAAK4vB,aAAaE,iBACvC9vB,KAAKwjB,aAAa0F,YAAY,KAAMlpB,KAAK4vB,aAAaG,uBAEtD/vB,KAAKye,SAASuR,WAAahwB,KAAK4vB,aAAaK,cACzCjwB,KAAK4vB,aAAaM,aAClBlwB,KAAKilB,YAAYjlB,KAAK4vB,aAAaM,eAK/CwE,QAAS,SAAS5a,EAAI+D,EAAQC,GAC1B,GAAIpc,GAAO1B,KAAK4f,QAAQ9F,EAEpB+D,IACA7d,KAAKwlB,UAAU3H,EAAQ/D,GAGvBgE,GACA9d,KAAKilB,YAAYnH,EAAUhE,GAG/B9Z,KAAKioB,wBACDvmB,KAAM,WACNsN,SAAUrP,GAAG4P,KAAKvP,KAAKye,SAASgI,UAAU+O,SAAUx1B,KAAM8Z,EAAIpY,GAC9DsV,UAAWrX,GAAG4P,KAAKvP,KAAKszB,yBAA0BtzB,KAAM8Z,EAAIpY,GAC5DuV,UAAWtX,GAAG4P,KAAKvP,KAAKitB,oBAAqBjtB,KAAM8Z,EAAIpY,GACvD0mB,WAAYtO,KAIpBsG,YAAa,SAAStG,GACb9Z,KAAK6f,SAASlW,OAAOmQ,IACtB9Z,KAAK2f,YAAY/D,UAAU9B,EAAIna,GAAGya,OAAO2C,SAIjD+I,mBAAoB,WAIhB,IAHA,GAAI2P,GAAYC,EACZ5d,EAAO9X,KAEJA,KAAKqe,WAAW3Y,QACnB+vB,EAAaz1B,KAAKqe,WAAWpM,QAC7BjS,KAAKogB,YAAYqV,EAIrBC,GAAkB11B,KAAKoiB,YAAYhI,OAAQza,GAAGya,OAAOY,aAAatV,OAC9DgwB,IACA/1B,GAAGmG,IAAI,qBAAuB4vB,EAAkB,yEAChDpM,WAAW,WACPxR,EAAKgO,sBACN,OAYX2O,wBAAyB,SAASpG,EAAa+D,GAC3C,GAAIta,GAAO9X,KACPmb,EAAQ,WACJ,MAAIkT,GAAYlT,eAAgBxb,IAAGwX,UACxBkX,EAAYlT,KAAK/D,cAErBiX,EAAYlT,QAEvBzZ,EAAO0wB,EAAqB1wB,KAC5BwZ,EAAOkX,EAAqBlX,KAC5BvD,EAAW3X,KAAKumB,aAAa8H,EAAYlT,MACzC8V,EAAiBjxB,KAAKmuB,mBAAmBxW,GACzCge,EAAkB,GAAIh2B,IAAG4L,OAQ7B,OANAoqB,GAAgBlf,KACZ,aACA,WACIqB,EAAKmV,oBAAoBoB,EAAYvU,GAAIpY,KAG7C/B,GAAG6I,cAAc2S,KAAUnb,KAAK2pB,oBAAoBsH,EAAerH,kBAAmBloB,IACtF1B,KAAK6lB,WAAW,YAAankB,EAAMyZ,GAC5Bwa,EAAgBhqB,WAGtB3L,KAAKye,SAASqL,WAAW8L,YAAuB,IAAT1a,EAKxCA,EAAO,GAAK+V,EAAeG,WAAalW,EAAO+V,EAAeG,WAC9DpxB,KAAK6lB,WAAW,YAAankB,EAAMyZ,GAC5Bwa,EAAgBhqB,WAGvBuP,EAAO,GAAKA,EAAO+V,EAAeI,cAClCrxB,KAAK6lB,WAAW,eAAgBnkB,EAAMyZ,GAC/Bwa,EAAgBhqB,YAGvBhM,GAAGk2B,iBAAmBl2B,GAAG8S,kBAAkBgD,eAAiB9V,GAAGuI,OAAOiT,GACtE,GAAIxb,IAAGk2B,gBAAgB1a,EAAMxb,GAAG4P,KAAKuI,EAAKhS,IAAKgS,IAAOge,SAAS7E,EAAe8E,OAAOtf,KACjFkf,EAAgBlqB,QAChB,SAASuqB,GACLle,EAAK+N,WAAWmQ,EAAY,aAAct0B,EAAMyZ,GAChDwa,EAAgBhqB,YAKxBgqB,EAAgBlqB,UAGbkqB,IA3BH31B,KAAK6lB,WAAW,aAAcnkB,EAAMyZ,GAC7Bwa,EAAgBhqB,YA6B/BsqB,eAAgB,WACZ,GAAIne,GAAMoe,EAAcnqB,CAExB+L,GAAO9X,KAEPk2B,EAAe,SAASx0B,EAAMsN,EAAUrH,GACpC,GAAIwuB,EAEJ,KACI,MAAOnnB,GAASY,MAAMkI,EAAMnQ,GAEhC,MAAOyuB,GACHD,EAAWC,EAAUrwB,SAAWqwB,EAAU9vB,WAC1CwR,EAAKhS,IAAI,wBAA0BpE,EAAO,gBAAkBy0B,EAAU,UAK9E,KAAKpqB,IAAQ/L,MAAKye,SAASgI,WACtB,WACG,GAAI4P,GAAcC,CAClBD,GAAetqB,EACfuqB,EAAexe,EAAK2G,SAASgI,UAAU4P,GACvCve,EAAK2G,SAASgI,UAAU4P,GAAgB,WACpC,MAAOH,GAAaG,EAAcC,EAAcxuB,oBCr7DvE,WACG,YAEAnI,IAAG42B,kBAAoB,SAAS/e,GAC5B,GAAIM,GAAO9X,IAGXA,MAAKye,UACDuE,OAAO,EACPO,OAAQ,KACR/Z,UAAU,EACVud,eAAgB,EAChByP,6BAA6B,EAC7BxG,YAAY,EACZyG,kBAAkB,EAElBxP,SACIE,iBACArJ,SAAU,iBACV4Y,cAAe,aACfC,gBAAgB,EAChBxM,UAAW,SACXtD,OAAQ,OACR+P,mBAAmB,EACnB/Y,UACAgZ,cAAc,EACdC,oBAAoB,EACpBC,kBAAmB,kBACnB7P,SAAU,UAGd4C,YACIF,qBACAwH,UAAW,EACXC,aAAc,EACd0B,UAAW,EACXZ,wBAAwB,EACxBla,YAAa,KACb8d,OACIiB,UAAW,EACXC,SAAU,EACVC,UAAW,EACXC,SAAU,GAEdvB,YAAY,GAGhBnP,WACI+O,SAAU,SAAS1b,EAAIpY,KACvB8xB,YAAa,SAAS1Z,EAAIpY,KAC1BupB,WAAY,SAASnR,EAAIpY,EAAM4qB,EAAc8K,KAC7C1E,cAAe,SAASF,EAAYC,KACpCrH,SAAU,SAAStR,EAAIpY,KACvB+pB,SAAU,SAAS3R,EAAIpY,KACvBkqB,cAAe,SAAS9R,EAAIpY,EAAMmqB,KAClCI,qBAAsB,SAASnS,EAAI+R,EAAWS,EAAcpB,KAC5DiB,SAAU,SAASrS,EAAIlI,EAAUia,EAAWO,KAC5CvB,WAAY,SAAS/Q,EAAIpY,EAAMopB,EAAQC,KACvCkJ,gBAAiB,SAASnJ,EAAQC,KAClCrE,QAAS,SAAS5M,EAAIpY,EAAM+f,EAAQ4V,KACpChL,YAAa,SAASvS,EAAIpY,EAAM41B,KAChCtE,cAAe,SAASlZ,EAAIpY,KAC5BizB,gBAAiB,SAAS4C,KAC1BlF,WAAY,SAASkF,KACrB1D,eAAgB,SAAS/Z,KACzByN,SAAU,SAASzN,KACnB2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,KACzCO,gBAAiB,SAASjd,KAC1BsQ,eAAgB,SAASzB,EAAIgC,EAAWD,KACxCuZ,yBAA0B,SAAStD,EAAUrmB,EAASic,MAG1DqJ,UACIyG,UAAW,qEACXC,UAAW,yDACXC,aAAc,4DACdC,WAAY,yDACZC,aAAc,sBACdrD,kBAAmB,6EACnBsD,oBAAqB,qBACrBC,mBAAoB,qBACpBC,oBAAqB,4BACrBC,mBAAoB,4BACpBC,sBAAuB,mDACvBnD,QAAS,8EACTlD,6BAA8B,6KAGlC3N,OACIiQ,YAAY,EACZoB,gBAAiB,EACjBzC,iBAAkB,EAClBjI,6BAA8B,gBAGlCb,SACIE,YAAa,yBACbD,YAAa,0BAGjBhV,UACImL,SAAS,EACT+X,YACI/X,SAAS,GAEbgY,WAAW,EACXC,YACIpM,UAAW,cACXqM,eAAgB,mBAChBC,UAAW,cACXC,cAAe,kBACfC,WAAY,gBAEhBC,SAAU,SAAS3e,GACf,MAAO,MAGXrO,SACIqS,SAAU,KAEVyG,QAAS,SAASzK,GACd,MAAO,OAGX4e,aAAa,EAEb7R,OAAQ,OAERhJ,OAAQ,SAAS/D,GACb,MAAO,OAGX6e,mBAIR7iB,QACIqK,SAAS,EACTyY,gBAAiB,EACjBR,YACIS,SAAU,YAEdC,WAAY,SAASnY,GACjB,WAIRwQ,eAAgB,SAAS4H,GACrB,MAAOA,IAGX11B,MACI2uB,qBAAsB,gCACtB3H,eAAgB,aAChB8C,aAAc,KAAM,KAAM,KAAM,KAAM,KAAM,OAGhD9M,YACIF,SAAS,EACT0G,OAAQ,SACR/I,SAAU,iBACVqJ,iBACAtJ,WAGJyJ,MACI8I,UAAU,EACV4I,iBAAiB,EACjB3I,UAAU,GAGd3R,OACIC,YAAa,aAGjBoJ,OACID,cAAe,KACfnJ,YAAa,gBAGjB+P,QACIzgB,KAAK,EAGLsV,OAAQ,MASZiK,gBAIA9J,SACI5F,SAAU,KACVD,UACAsJ,iBACAxD,gBAAgB,GAIpB9S,MAEIjR,QAAS,UAGTowB,YAAY,EAGZiJ,iBAAiB,GAIrBljB,SACImjB,cAAe,KAGfC,cAAc,EAGdC,QAAQ,EAIRC,YAAa,KAEbC,eAAgB,GAEhBC,YAAa,kBAEbC,aAAa,EAGbC,UAGJhQ,aACIC,gBAAgB,EAChBgI,mBAAmB,EACnBxH,kBAAkB,IAK1BvqB,GAAG6B,OAAOxB,KAAKye,SAAUjH,GAAG,GAE5BxX,KAAKsjB,YACLtjB,KAAKutB,qBACLvtB,KAAK4hB,wBAEL5hB,KAAKi2B,iBACLj2B,KAAKsqB,gBAAmB,GAAI3qB,IAAGkS,eAE/B7R,KAAKqe,cACLre,KAAKmjB,gBACLnjB,KAAKojB,kBACLpjB,KAAKqjB,mBACLrjB,KAAKmhB,kBAELnhB,KAAK4iB,qBAAuB,EAC5B5iB,KAAKwiB,aAAe,EACpBxiB,KAAK2f,YAAc3f,KAAKmpB,2BAExBnpB,KAAK2vB,4BAEL3vB,KAAKwkB,oBAAsBxkB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQE,eACnEnnB,KAAK4kB,8BAAgC5kB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAW8G,eAEhFnnB,KAAKglB,uBAAyBhlB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAWxC,QAEzE7d,KAAK8hB,eAAiB9hB,KAAKqoB,aAAaroB,KAAKye,SAASwI,QAAQnJ,UAC9D9d,KAAK8kB,yBAA2B9kB,KAAKqoB,aAAaroB,KAAKye,SAAS4B,WAAWvC,UAE3E9d,KAAK6f,SAAW7f,KAAKuqB,uBAErBvqB,KAAK8zB,eAAiBn0B,GAAGinB,yBAA2B5mB,KAAK2mB,uBAErD3mB,KAAKye,SAAS8E,SACdvjB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKye,SAAS8E,OACvB1L,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGPnZ,KAAKstB,4BAELttB,KAAKyuB,sBAEDzuB,KAAKye,SAASsJ,MAAMD,gBAChBnoB,GAAGkoB,aACH7nB,KAAKyjB,cAAgBzjB,KAAK4nB,sBAG1B5nB,KAAK8F,IAAI,iCAAkC,UAInD9F,KAAKye,SAASgY,kBAAoBz2B,KAAK40B,0BAEvC50B,KAAKkhB,gBAAkBvhB,GAAG+5B,gBAAkB,GAAI/5B,IAAG+5B,eAAe/5B,GAAG4P,KAAKvP,KAAK8F,IAAK9F,OACpFA,KAAK4jB,sBAEL5jB,KAAK6jB,kCACL7jB,KAAK8jB,+BAEL9jB,KAAK25B,QAAWh6B,GAAG0kB,QAAU,GAAI1kB,IAAG0kB,OAAOrkB,KAAKye,SAAS1I,QAASpW,GAAG4P,KAAKvP,KAAK8F,IAAK9F,WAChFA,KAAK25B,QAAQxZ,UACbngB,KAAKkvB,sBAAwBvvB,GAAG4P,KAAKvP,KAAK25B,QAAQC,cAAe55B,KAAK25B,UAGtEh6B,GAAGk6B,eAAiBl6B,GAAG8S,kBAAkBoD,cACzC7V,KAAK+jB,eAAiB,GAAIpkB,IAAGk6B,cACzBl6B,GAAG4P,KAAKvP,KAAKg0B,iBAAkBh0B,MAE/B,SAAS8Z,GACL,GAAIggB,GAAQhiB,EAAK6H,YAAYnE,UAAU1B,GAAIA,GAC3C,OAAQggB,IAASA,EAAM5e,MAAS,KAK5Clb,KAAK2iB,kBAAoB3iB,KAAKye,SAASqL,WAAWiJ,UAElD/yB,KAAKgkB,uBAAyBhkB,KAAKqoB,gBAIvC1oB,GAAG42B,kBAAkBlwB,UAAY1G,GAAG+d,cACpC/d,GAAG6B,OAAO7B,GAAG42B,kBAAkBlwB,UAAW1G,GAAGomB,mBC3UjDpmB,GAAGo6B,cAAgB,SAASviB,GACxB,YA2CA,SAASwiB,KACL,MAAOr6B,IAAG2F,SAAS,MAAO,OAAQ,QAASsS,EAAQiP,SAAW,EAMlE,QAASoT,GAAyB1V,GAC9B,GAAI2V,IAAoB,CASxB,OAPAv6B,IAAG+C,KAAKw3B,EAAmB,SAASv3B,EAAKw3B,GACrC,GAAIx6B,GAAG2F,SAAS,SAAU,kBAAmB,mBAAoB,gBAAiB60B,GAAU,EAExF,MADAD,IAAoB,GACb,IAIRA,EAGX,QAASE,GAAMlP,GAEX,MAAOtT,GAAQ0P,KAAK8I,UAAoCtsB,SAAxBonB,EAAIhY,gBAIxC,QAASmnB,KACL,GAAI3S,EAeJ,QAbI7iB,OAAO+E,gBAAkB/E,OAAOgF,iBAChC6d,EAAW/nB,GAAG+J,oBAEmB5F,SAA7B4jB,EAASxU,kBACTwU,EAAW,GAAItU,gBAEfsU,EAASlc,OAAS,aAClBkc,EAAShc,QAAU,aACnBgc,EAAS4S,UAAY,aACrB5S,EAAS6S,WAAa,eAIvB7S,EAIX,QAAS8S,GAAY1gB,EAAI2gB,GACrB,GAAI/S,GAAWgT,EAAY5gB,IAAO4gB,EAAY5gB,GAAIoR,GAkBlD,OAhBKxD,KAEGA,EADA+S,EACWA,EAGP7iB,EAAQ0P,KAAK8I,SACFiK,IAGA16B,GAAG+J,oBAItBgxB,EAAY5gB,GAAIoR,IAAMxD,GAGnBA,EAIX,QAASiT,GAAQ7gB,GACb,GAEI8gB,GAFAvqB,EAAI1Q,GAAG2F,QAAQu1B,EAAO/gB,GACtBsT,EAAMxV,EAAQmP,qBAGX2T,GAAY5gB,GACnB+gB,EAAM7e,OAAO3L,EAAG,GAEZwqB,EAAMn1B,QAAU0nB,GAAO/c,EAAI+c,IAC3BwN,EAASC,EAAMzN,EAAM,GACrB0N,EAAYF,IAIpB,QAAS3P,GAAWnR,EAAIihB,GACpB,GAAI7P,GAAMsP,EAAY1gB,GAClB+M,EAASjP,EAAQiP,OACjBc,EAAUoT,KAAa,CAE3BJ,GAAQ7gB,GAEJ6N,EACA7hB,EAAI+gB,EAAS,gBAAkB/M,EAAK,cAAe,SAE7CsgB,EAAMlP,IAAS8P,EAAqB9P,EAAI9Q,UAC9CuN,GAAU,EACV7hB,EAAI+gB,EAAS,gBAAkB/M,EAAK,+BAAiCoR,EAAI9Q,OAAQ,UAGrFxC,EAAQqT,WAAWnR,EAAIoR,EAAKvD,GAGhC,QAASsT,GAAUnhB,GACf,GAEI+D,GAFAqd,EAAiBR,EAAY5gB,GAAIqhB,iBACjCC,EAAiBxjB,EAAQwjB,cAqB7B,OAlBIxjB,GAAQwP,YAAYrF,MACpBlE,EAASjG,EAAQwP,YAAYrF,IAAIjI,IAGjCohB,GACAv7B,GAAG+C,KAAKw4B,EAAgB,SAASx5B,EAAMkB,GACnCib,EAASA,MACTA,EAAOnc,GAAQkB,IAInBw4B,GACAz7B,GAAG+C,KAAK04B,EAAgB,SAAS15B,EAAMkB,GACnCib,EAASA,MACTA,EAAOnc,GAAQkB,IAIhBib,EAGX,QAASid,GAAYhhB,EAAIuhB,GACrB,GAIIC,GAJApQ,EAAMsP,EAAY1gB,EAAIuhB,GACtBxU,EAASjP,EAAQiP,OACjBhJ,EAASod,EAAUnhB,GACnByhB,EAAUb,EAAY5gB,GAAIyhB,OA+C9B,OA5CA3jB,GAAQ4jB,OAAO1hB,GAEfwhB,EAAMG,EAAU3hB,EAAI+D,EAAQ6c,EAAY5gB,GAAI4hB,uBAGxCtB,EAAMlP,IACNA,EAAI1f,OAASmwB,EAAkB7hB,GAC/BoR,EAAIxf,QAAUkwB,EAAmB9hB,IAGjCoR,EAAI2Q,mBAAqBC,EAA8BhiB,GAG3DiiB,EAA0BjiB,GAG1BoR,EAAI8Q,KAAKnV,EAAQyU,GAAK,GAIlB1jB,EAAQ0P,KAAK8I,UAAYxY,EAAQ0P,KAAK0R,kBAAoBoB,EAAMlP,KAChEA,EAAIhY,iBAAkB,GAG1B+oB,EAAWniB,GAEXhU,EAAI,WAAa+gB,EAAS,gBAAkB/M,GAExCyhB,EACArQ,EAAIgR,KAAKX,GAEJY,IAAgCte,EACrCqN,EAAIgR,OAECre,GAAUjG,EAAQwkB,aAAexkB,EAAQwkB,YAAYrzB,cAAczD,QAAQ,sCAAwC,EACxH4lB,EAAIgR,KAAKv8B,GAAGkQ,QAAQgO,EAAQ,KAEvBA,GAAUjG,EAAQwkB,aAAexkB,EAAQwkB,YAAYrzB,cAAczD,QAAQ,qBAAuB,EACvG4lB,EAAIgR,KAAKhrB,KAAKmrB,UAAUxe,IAGxBqN,EAAIgR,KAAKre,GAGNqN,EAGX,QAASuQ,GAAU3hB,EAAI+D,EAAQ6d,GAC3B,GAAI5d,GAAWlG,EAAQyP,cAActF,IAAIjI,GACrCwiB,EAAY5B,EAAY5gB,GAAIwiB,SAehC,OAZiBx4B,SAAbw4B,IACAxe,GAAY,IAAMwe,GAGlBH,GAA+Bte,IAC/BC,EAAWne,GAAGkQ,QAAQgO,EAAQC,IAG9B4d,IACA5d,EAAWne,GAAGkQ,QAAQ6rB,EAAuB5d,IAG1CA,EAKX,QAASge,GAA8BhiB,GACnC,MAAO,YACgC,IAA/B0gB,EAAY1gB,GAAIyiB,YAChBtR,EAAWnR,IAKvB,QAASiiB,GAA0BjiB,GAC/B,GAAI+Q,GAAajT,EAAQiT,UAErBA,KACA2P,EAAY1gB,GAAInQ,OAAO4wB,WAAa,SAAS9rB,GACrCA,EAAE+tB,kBACF3R,EAAW/Q,EAAIrL,EAAEqc,OAAQrc,EAAEsc,SAQ3C,QAAS4Q,GAAkB7hB,GACvB,MAAO,YACHmR,EAAWnR,IAMnB,QAAS8hB,GAAmB9hB,GACxB,MAAO,YACHmR,EAAWnR,GAAI,IAIvB,QAASmiB,GAAWniB,GAChB,GAAIoR,GAAMsP,EAAY1gB,GAClBqN,EAAgBvP,EAAQuP,cACxBsV,EAAkB/B,EAAY5gB,GAAI4iB,sBAClC7V,EAASjP,EAAQiP,OACjB8V,IAGCvC,GAAMlP,KACPtT,EAAQglB,cAAgB1R,EAAI2R,iBAAiB,SAAUjlB,EAAQglB,cAG3DhlB,EAAQklB,qCAKHllB,EAAQ0P,KAAK8I,UAAc4J,MAAoBC,EAAyB9S,KACzE+D,EAAI2R,iBAAiB,mBAAoB,kBACzC3R,EAAI2R,iBAAiB,gBAAiB,eAI1CjlB,EAAQwkB,aAA2B,SAAXvV,GAAgC,QAAXA,GAC7CqE,EAAI2R,iBAAiB,eAAgBjlB,EAAQwkB,aAGjDz8B,GAAG6B,OAAOm7B,EAAYh9B,GAAG6G,WAAW2gB,GAAiBA,EAAcrN,GAAMqN,GACzExnB,GAAG6B,OAAOm7B,EAAYF,GAEtB98B,GAAG+C,KAAKi6B,EAAY,SAASj7B,EAAMkB,GAC/BsoB,EAAI2R,iBAAiBn7B,EAAMkB,MAKvC,QAASo4B,GAAqB+B,GAC1B,MAAOp9B,IAAG2F,QAAQsS,EAAQolB,wBAAwBplB,EAAQiP,QAASkW,IAAiB,EAGxF,QAASE,GAAcnjB,EAAIuhB,EAAQiB,EAAWnB,EAAkBO,EAAuBgB,EAAmBnB,GAYtG,GAXAb,EAAY5gB,IACRwiB,UAAWA,EACXnB,iBAAkBA,EAClBO,sBAAuBA,EACvBgB,kBAAmBA,EACnBnB,QAASA,GAGHV,EAAMh4B,KAAKiX,IAGVlC,EAAQmP,eACf,MAAO+T,GAAYhhB,EAAIuhB,GA7U/B,GAAIv1B,GAAKq2B,EACLtB,KACAH,KACA9iB,GACIglB,aAAc,KACdM,cAAe,QAAS,OAAQ,OAChCrW,OAAQ,OACRuV,YAAa,oCACbrV,eAAgB,EAChBI,iBACAE,iBACAD,eACAgU,kBACA0B,oCAAoC,EACpCE,yBACIG,QAAS,IAAK,IAAK,KACnBC,OAAQ,IAAK,IAAK,IAAK,IAAK,KAC5BC,MAAO,IAAK,IAAK,IAAK,IAAK,KAC3BC,KAAM,IAAK,IAAK,IAAK,IAAK,KAC1BC,KAAM,MAEVjW,MACI8I,UAAU,EACV4I,iBAAiB,GAErBlzB,IAAK,SAAS4B,EAAK1B,KACnBw1B,OAAQ,SAAS1hB,KACjBmR,WAAY,SAASnR,EAAI4N,EAAUC,KACnCkD,WAAY,KAMpB,IAHAlrB,GAAG6B,OAAOoW,EAASJ,GACnB1R,EAAM8R,EAAQ9R,IAEVnG,GAAG2F,QAAQsS,EAAQslB,aAActlB,EAAQiP,QAAU,EACnD,KAAM,IAAI1lB,OAAM,IAAMyW,EAAQiP,OAAS,wDA8S3CsV,GAAiD,QAAnBvkB,EAAQiP,QAAuC,WAAnBjP,EAAQiP,OAElElnB,GAAG6B,OAAOxB,MAENw9B,cAAe,SAAS1jB,GACpB,GAAI2jB,GAAM5f,EAAQ0G,EAASgX,EAASmC,EAAahC,CAEjD,QAEIiC,SAAU,SAASC,GAEf,MADAH,GAAOG,EACA59B,MAOX69B,WAAY,SAAS1C,GAEjB,MADAtd,GAASsd,EACFn7B,MAGX89B,gBAAiB,SAASC,GAEtB,MADArC,GAAwBqC,EACjB/9B,MAIXg+B,YAAa,SAAStB,GAElB,MADAnY,GAAUmY,EACH18B,MAIXi+B,YAAa,SAASC,GAElB,MADA3C,GAAU2C,EACHl+B,MAIXm+B,gBAAiB,WAEb,MADAT,IAAc,EACP19B,MAIXk8B,KAAM,SAASb,GAKX,MAJIqC,IAAe/9B,GAAG2F,SAAS,MAAO,UAAWsS,EAAQiP,SAAW,IAChEhJ,EAAOugB,aAAc,GAAIC,OAAOC,WAG7BrB,EAAcnjB,EAAIuhB,EAAQoC,EAAM5f,EAAQ6d,EAAuBnX,EAASgX,MAK3FgD,SAAU,SAASzkB,GACf6gB,EAAQ7gB,OC1YpBna,GAAG6+B,cAAgB,SAASzjB,GACxB,YAEA,IAAI0jB,GAAQ1jB,EAAK0jB,MACbC,KACAtT,EAAWqT,EAAMrT,SACjBxL,EAAU6e,EAAM7e,OAEpBjgB,IAAG6B,OAAOxB,MACNmQ,IAAK,SAAS2J,EAAI6kB,GACdD,EAAU5kB,GAAM6kB,EAChBD,EAAU5kB,GAAI/J,SAGlB0P,OAAQ,SAAS3F,GACb,GAAIhC,GAAO9X,KACPqrB,EAA2B,GAAI1rB,IAAG4L,OACjB6f,GAAStR,EAAI8F,EAAQ9F,GAAKuR,GAEhC5U,KAAK,WACZqB,EAAK2I,QAAQ3G,KACb4kB,EAAU5kB,GAAIykB,UAAW,EACzBzmB,EAAKoL,QAAQpJ,IAEjBuR,EAAyB5f,aAIjCyX,QAAS,SAASpJ,SACP4kB,GAAU5kB,IAGrB8kB,oBAAqB,SAAS9kB,GAC1B,MAAO4kB,GAAU5kB,GAAI1K,KAGzBqR,QAAS,SAAS3G,GACd,MAAyBhW,UAAlB46B,EAAU5kB,IAGrBN,MAAO,WACHklB,MAGJG,cAAe,SAAS/kB,GACpB,MAAO4kB,GAAU5kB,IAGrBglB,qBAAsB,SAAShlB,EAAIilB,GAC/BL,EAAU5kB,GAAI1K,IAAM2vB,GAGxBC,aAAc,SAASllB,GACnB,QAAS4kB,EAAU5kB,GAAIykB,aCpDnC5+B,GAAGqtB,wBAA0B,SAASxV,EAAGiT,GACrC,YAEA,IAGcwU,GAAsBn5B,EAAKmpB,EAHrCiQ,EAAal/B,KACbm/B,GAAmB,EACnBC,GAA6B,EAGjCxnB,GACIwP,eACAL,eAAgB,EAChB/R,UACImL,SAAS,EACT3W,UACI2W,SAAS,IAGjBra,IAAK,SAAS4B,EAAK1B,KACnB6kB,WAAY,SAAS/Q,EAAIlI,EAAUkZ,EAAQC,KAC3CE,WAAY,SAASnR,EAAIlI,EAAUkgB,EAAU5G,KAC7CE,SAAU,SAAStR,EAAIlI,KACvB2Z,aAAc,SAASzR,KACvB2R,SAAU,SAAS3R,EAAIlI,KACvBga,cAAe,SAAS9R,EAAIlI,EAAUia,KACtCI,qBAAsB,SAASnS,EAAI+R,EAAWiG,EAAU5G,KACxDmB,YAAa,SAASvS,EAAIlI,EAAUkgB,EAAU5G,KAC9CiB,SAAU,SAASrS,EAAIlI,EAAUia,EAAWO,KAC5CI,cAAe,SAAS1S,EAAIoC,KAC5B0D,QAAS,SAAS9F,KAClB2S,QAAS,SAAS3S,EAAIyC,KACtBqQ,SAAU,SAAS9S,KACnB6C,mBAAoB,SAAS7C,KAC7B8C,cAAe,SAAS9C,KACxB+S,aAAc,SAAS/S,MAG3BulB,GAEInoB,KAAM,SAAS4C,EAAIwlB,EAAUxN,EAAU5G,GACnC,GAAIW,GAAYoD,EAAQsQ,cAAczlB,EAAIwlB,EAE1CrQ,GAAQ4P,cAAc/kB,GAAI0lB,kBAAmB,QAEtCvQ,GAAQ4P,cAAc/kB,GAAI/J,KAAK0vB,cAAcH,GACpDrQ,EAAQ4P,cAAc/kB,GAAIgR,QAAUe,EAAU3Q,KAE9CtD,EAAQqU,qBAAqBnS,EAAImV,EAAQyQ,yBAAyB7T,GAAYiG,EAAU5G,IAK5FyU,SAAU,SAAS7lB,GACf,GAAIoB,GAAOtD,EAAQ0K,QAAQxI,GACvBpY,EAAOkW,EAAQgI,QAAQ9F,EAE3BhU,GAAI,qCAAuCgU,EAAK,qBAChDmV,EAAQ2Q,eAAe9lB,GAAIrD,KACvB,SAASqb,EAAU5G,GACfplB,EAAI,2BAA6BgU,EAEjC,IAAI+lB,GAAoBl2B,EAAOm2B,kBAAkBhO,GAAU,EAE3Dla,GAAQiT,WAAW/Q,EAAIpY,EAAMwZ,EAAMA,GACnC+T,EAAQ8Q,+BAA+BjmB,GACvCnQ,EAAOq2B,QAAQlmB,EAAI+lB,EAAmB3U,IAE1C,SAAS4G,EAAU5G,GACf,GAAI+U,GAAqBt2B,EAAOm2B,kBAAkBhO,GAAU,EAE5DhsB,GAAI,yCAA2CgU,EAAK,MAAQmmB,EAAmBn2B,MAAO,UAGlFm2B,EAAmBzmB,OAClB0R,GAAOtT,EAAQ5C,SAASvJ,QAAQktB,cAAcrzB,QAAQ4lB,EAAI9Q,SAAW,IAEtEilB,EAAQ7lB,MAAMM,GAGblC,EAAQyU,YAAYvS,EAAIpY,EAAMu+B,EAAoB/U,IACnDvhB,EAAOq2B,QAAQlmB,EAAImmB,EAAoB/U,MAMvDgV,cAAe,SAASZ,EAAUxlB,EAAIgY,EAAU5G,GAC5C,GAAIxpB,GAAOkW,EAAQgI,QAAQ9F,EAE3BhU,GAAI,qCAAuCgU,EAAK,WAAawlB,GAE7DrQ,EAAQkR,iBAAiBrmB,EAAIwlB,EAE7B,IACIc,GADAC,EAAmB12B,EAAOm2B,kBAAkBhO,GAAU,EAG1D,IAAIuO,EAAiB7mB,MACjB6lB,EAAQ7lB,MAAMM,OAEb,CACD,GAAIwmB,GAAwBrR,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,UAE/DH,GAAgBE,EAAwB3gC,GAAG2F,QAAQg7B,EAAuBhB,IAAY,EAClFc,GAAiB,IACjBnR,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,WAAWvkB,OAAOokB,EAAe,GACpEnR,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAUC,QAAQnB,IAMxDrQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,gBAG5BtB,IACAnQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,eAAgB,EAE/C56B,EAAInG,GAAG8H,OAAO,mFAAoFyJ,KAAKmrB,UAAUj2B,OAAOu6B,KAAK1R,EAAQ2R,SAAS9mB,KAAO5I,KAAKmrB,UAAUpN,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,cACvM5gC,GAAG+C,KAAKusB,EAAQ2R,SAAS9mB,GAAK,SAAS+mB,EAAMC,GACzCh7B,EAAInG,GAAG8H,OAAO,sDAAuDqS,EAAI+mB,EAAMC,EAAMvE,aACrFuE,EAAMC,QAGND,EAAME,YAAa,IAIvB/R,EAAQgS,0BAA0BnnB,GAIlConB,EAAkBC,KAAKrnB,GAAI,IAG1BlC,EAAQyU,YAAYvS,EAAIpY,EAAM2+B,EAAkBnV,IAIjDvhB,EAAOq2B,QAAQlmB,EAAIumB,EAAkBnV,KAKjDkW,aAAc,SAAStnB,GACnB,QAASmV,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAU96B,QAG1D27B,SAAU,SAASvnB,GACf,GAAIwnB,GAAUrS,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAUvuB,OAM3D,OAJIqvB,IAAWrS,EAAQsS,gBAAgBznB,KACnCwnB,EAAU,MAGPA,GAGX9nB,MAAO,SAASM,GACZhU,EAAI,8FAAgGgU,EAAI,SAExGmV,EAAQ8Q,+BAA+BjmB,GACvCmV,EAAQuS,mBAAmB1nB,GAC3BmV,EAAQ4P,cAAc/kB,GAAIgR,OAAS,EACnCmE,EAAQ4P,cAAc/kB,GAAI0lB,kBAAmB,GAGjDiC,SAAU,SAAS3nB,GACf,GAAIoB,GAAOtD,EAAQ0K,QAAQxI,GACvBpY,EAAOkW,EAAQgI,QAAQ9F,GACvBwlB,EAAWD,EAAQgC,SAASvnB,GAC5B+R,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCZ,EAAYzP,EAAQ4P,cAAc/kB,GAClC+e,EAAW6F,EAAUc,iBACrBkC,EAAmBhD,EAAU1pB,SAASurB,cAe1C,IAbwB,MAApB7B,EAAU5T,SACV4T,EAAU5T,OAAS,GAInB+N,GAAYjhB,EAAQuU,SAASrS,EAAIpY,EAAMmqB,EAAW6S,EAAUtS,qBAAsB,IAClFiT,EAAQ7lB,MAAMM,GACdwlB,EAAWD,EAAQgC,SAASvnB,GAC5B+R,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCzG,GAAW,GAIC,MAAZyG,GAAgD,IAA5BoC,EAAiBh8B,OACrC25B,EAAQM,SAAS7lB,OAIhB,CACD4nB,EAAiB7+B,KAAKy8B,GACtBrQ,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,WAAamB,EAE5CtC,GACA8B,EAAkBlF,KAAKliB,EAAIwlB,GAG3BF,GAA8B8B,EAAkBS,aAAe1S,EAAQ4P,cAAc/kB,GAAI9E,SAASwrB,UAAU96B,QAC5G25B,EAAQoC,SAAS3nB,GAGO,IAAxB+R,EAAU5gB,KAAKiQ,OACfpV,EAAInG,GAAG8H,OAAO,+DAAgE63B,EAAUxlB,GAAK,SAC7FulB,EAAQa,cAAcZ,EAAUxlB,EAAI,8BAA+B,MAG5ClC,GAAQgU,cAAc9R,EAAIpY,EAAMutB,EAAQyQ,yBAAyB7T,IAEvEpV,KACjB,SAASmrB,GACL,GAAKhqB,EAAQiV,aAAa/S,GAGrB,CACDhU,EAAInG,GAAG8H,OAAO,oEAAqEqS,EAAIwlB,EAAUzT,EAAUphB,MAAQ,EAAGohB,EAAUnhB,IAAKwQ,GAErI,IAAI2mB,IACAvC,SAAUA,EACVxlB,GAAIA,EACJgoB,UAAWF,EACX/I,SAAUA,EAGd5J,GAAQ8S,YAAYF,GAAiBprB,KAEjC,SAAiBqb,EAAU5G,GACvBplB,EAAI,wCAA0CgU,EAAK,WAAawlB,GAEhErQ,EAAQkR,iBAAiBrmB,EAAIwlB,EAE7B,IAAIoC,GAAmBzS,EAAQ4P,cAAc/kB,GAAI9E,SAASurB,eACtDF,EAAmB12B,EAAOm2B,kBAAkBhO,GAAU,GACtDkQ,EAAqBriC,GAAG2F,QAAQo8B,EAAkBpC,EAEtDx5B,GAAInG,GAAG8H,OAAO,8CAA+C63B,EAAUxlB,IAEvEulB,EAAQnoB,KAAK4C,EAAIwlB,EAAUe,EAAkBnV,GAEzC8W,GAAsB,GACtBN,EAAiB1lB,OAAOgmB,EAAoB,GAGhD/S,EAAQgT,0BAA0BnoB,GAE7BulB,EAAQ+B,aAAatnB,IAAmC,IAA5B4nB,EAAiBh8B,OAGzC25B,EAAQ+B,aAAatnB,GAC1BulB,EAAQoC,SAAS3nB,GAGjBhU,EAAInG,GAAG8H,OAAO,oGAAqGqS,EAAI5I,KAAKmrB,UAAUqF,KANtIrC,EAAQM,SAAS7lB,IAWzB,SAAiBgY,EAAU5G,GACvBmU,EAAQa,cAAcZ,EAAUxlB,EAAIgY,EAAU5G,KAGjDhU,KAAK,WACF+X,EAAQiT,SAASpoB,EAAIwlB,SAlD7Bx5B,GAAInG,GAAG8H,OAAO,6EAA8EqS,EAAIwlB,KAuDxG,SAASx1B,GACLu1B,EAAQa,cAAcZ,EAAUxlB,EAAIhQ,EAAO,WAO/Do3B,GACIiB,SACAC,eACAC,YAEAV,UAAW,WACP,GAAIvU,GAAMxV,EAAQmP,eACdub,EAAwB,EACxBC,EAAkB,CAOtB,OALA5iC,IAAG+C,KAAKw+B,EAAkBkB,YAAa,SAASzhB,EAAQ6hB,GACpDF,IACAC,GAAmBC,EAAiB98B,SAGjC0nB,GAAO8T,EAAkBiB,MAAMz8B,OAAS48B,EAAwBC,IAM3EpB,KAAM,SAASrnB,EAAI2oB,GACf,GAGI7H,GAHA8H,GAAaD,EACbE,EAAehjC,GAAG2F,QAAQ47B,EAAkBmB,SAAUvoB,GACtD8oB,EAAmBjjC,GAAG2F,QAAQ47B,EAAkBiB,MAAOroB,SAGpDonB,GAAkBkB,YAAYtoB,GAEjCnQ,EAAOk5B,eAAe/oB,YAAena,IAAGwX,YACxCrR,EAAI,uCAAyCgU,EAAK,qCAC3CmV,GAAQ4P,cAAc/kB,GAAIqB,MAIjCwnB,GAAgB,EAChBzB,EAAkBmB,SAASrmB,OAAO2mB,EAAc,GAG3CD,GAAaE,GAAoB,IACtC1B,EAAkBiB,MAAMnmB,OAAO4mB,EAAkB,GAEjDhI,EAASsG,EAAkBmB,SAASpwB,QAChC2oB,GAAU,IACVsG,EAAkBiB,MAAMt/B,KAAK+3B,GAC7BjxB,EAAOc,MAAMmwB,MAKzBkI,sBAAuB,WACnB,GAAIC,KAqBJ,OAjBApjC,IAAG+C,KAAKw+B,EAAkBkB,YAAa,SAASzhB,EAAQqiB,GAChDA,GAAUA,EAAOt9B,QACjBq9B,EAAmBlgC,KAAKogC,SAAStiB,MAMzChhB,GAAG+C,KAAKw+B,EAAkBiB,MAAO,SAASx/B,EAAKge,GACtCugB,EAAkBkB,YAAYzhB,IAC/BoiB,EAAmBlgC,KAAKogC,SAAStiB,MAKzCoiB,EAAqBA,EAAmBpzB,OAAOuxB,EAAkBmB,WAKrEa,kBAAmB,SAASppB,GACxB,MAAOna,IAAG2F,QAAQ47B,EAAkBiB,MAAOroB,IAAO,GAGtDkiB,KAAM,SAASliB,EAAIwlB,GAKf,MAJgB,OAAZA,GACA4B,EAAkBmB,SAASx/B,KAAKiX,KAGhConB,EAAkBS,cACF,MAAZrC,GACA4B,EAAkBmB,SAASc,MAC3BjC,EAAkBiB,MAAMt/B,KAAKiX,IAG5B,WACG,GAAIspB,GAAkBlC,EAAkBkB,YAAYtoB,MACpDspB,GAAgBvgC,KAAKy8B,GACrB4B,EAAkBkB,YAAYtoB,GAAMspB,MAIrC,IAMf5pB,MAAO,WACH0nB,EAAkBmB,YAClBnB,EAAkBiB,WAI1BkB,GACInH,KAAM,SAASpiB,EAAIpY,GACf,GAAIg9B,GAAYzP,EAAQ4P,cAAc/kB,EAEtC,KAAK4kB,EAED,WADA54B,GAAI,yEAA2EgU,EAAI,OAIvF4kB,GAAU5T,OAAS,EAEnBhlB,EAAI,qCAAuCgU,GAC3CmV,EAAQqU,WAAWxpB,GAAIrD,KACnB,SAASqb,EAAUuJ,GACfv1B,EAAI,uCAAyCgU,EAE7C,IAAIumB,GAAmB12B,EAAOm2B,kBAAkBhO,GAAU,GACtD5W,EAAOtD,EAAQ0K,QAAQxI;+CAE3BlC,GAAQiT,WAAW/Q,EAAIpY,EAAMwZ,EAAMA,GACnCvR,EAAO45B,aAAazpB,EAAIumB,GACxB12B,EAAOq2B,QAAQlmB,EAAIumB,EAAkBhF,IAGzC,SAASvJ,EAAUuJ,GACfv1B,EAAI,oCAAsCgU,EAE1C,IAAIumB,GAAmB12B,EAAOm2B,kBAAkBhO,GAAU,EAErDla,GAAQyU,YAAYvS,EAAIpY,EAAM2+B,EAAkBhF,IACjD1xB,EAAOq2B,QAAQlmB,EAAIumB,EAAkBhF,OAOzD1xB,GACI8V,OAAQ,SAAS3F,GACbhU,EAAI,cAAgBgU,GACpBlC,EAAQwP,YAAYrmB,OAAO+Y,GAC3BonB,EAAkBC,KAAKrnB,IAG3BkmB,QAAS,SAASlmB,EAAIgY,EAAUuJ,GAC5B,GAAI35B,GAAOkW,EAAQgI,QAAQ9F,EAE3BlC,GAAQqT,WAAWnR,EAAIpY,EAAMowB,EAAUuJ,GAEnCpM,EAAQ4P,cAAc/kB,IACtBmV,EAAQuU,YAAcvU,EAAQuU,WAAW1pB,GAG7ConB,EAAkBC,KAAKrnB,IAK3B+oB,eAAgB,SAAS/oB,GACrB,MAAQmV,GAAQwU,UAAYxU,EAAQwU,SAAS3pB,IACxCmV,EAAQ5N,SAAW4N,EAAQ5N,QAAQvH,IAG5C4pB,YAAa,WAITzU,EAAU,IAHQxE,EAAY9qB,GAAG8qB,GAAa9qB,GAAGgkC,cACtBhkC,GAAG8S,kBAAkBoC,cAAgB,MAAQ,QAEvB,iBAC7C+C,GAEIkV,oBAAqBlV,EAAQkV,oBAC7BH,cAAe/U,EAAQ+U,cACvB/M,QAAShI,EAAQgI,QACjB0C,QAAS1K,EAAQ0K,QACjBO,QAASjL,EAAQiL,QACjB/c,IAAKA,EACLslB,SAAUxT,EAAQwT,SAClBP,WAAYjT,EAAQiT,WACpB2B,cAAe5U,EAAQ4U,cACvBoX,aAAc,SAAS9pB,GACnBlC,EAAQgE,UAAU9B,EAAIna,GAAGya,OAAO+C,sBAKxC8R,EAAQ4U,+BACR5U,EAAQ4U,iCAIhBC,4BAA6B,SAAShqB,GAClC,MAAOlC,GAAQgV,SAAS9S,IAM5BiqB,WAAY,SAASjqB,EAAI7O,GAIrB,MAAIA,KAASgkB,EAAQ5N,QAAQvH,IAAO7O,YAAgBtL,IAAGwX,WAKnDS,EAAQ2T,aAAazR,GAErBhU,EAAI,+CAAiDgU,GACrD7O,EAAKqM,SAASb,KAAK,SAASutB,GACxBl+B,EAAI,mCAAqCgU,GAGzCmV,EAAQgV,WAAWnqB,EAAIkqB,GAGvBpsB,EAAQ6U,QAAQ3S,EAAIkqB,EAAc9oB,MAGlC+T,EAAQuS,mBAAmB1nB,GAE3BnQ,EAAOu6B,uBAAuBpqB,IAIlC,SAAS6L,GACL,GAAIwe,KAEAxe,KACAwe,EAAcr6B,MAAQ6b,GAG1B7f,EAAInG,GAAG8H,OAAO,yDAA0DqS,EAAI6L,GAAe,SAE3F/N,EAAQqT,WAAWnR,EAAIlC,EAAQgI,QAAQ9F,GAAKna,GAAG6B,OAAO2iC,EAAelF,GAAuB,MAC5Ft1B,EAAOu6B,uBAAuBpqB,GAC9BonB,EAAkBC,KAAKrnB,MAOxB,GAHInQ,EAAOu6B,uBAAuBpqB,IAO7CoqB,uBAAwB,SAASpqB,GAC7B,GAAIsqB,GAAaxsB,EAAQ+E,mBAAmB7C,GACxCuqB,GAAiB,CAoBrB,OAlBID,IAAcA,EAAW1+B,QACzBI,EAAI,0CAA4CgU,GAEhDna,GAAG+C,KAAK0hC,EAAY,SAASzhC,EAAK2hC,GAC9B,GAAI36B,EAAOm6B,4BAA4BQ,IAAgBrV,EAAQ5N,QAAQijB,GACnED,EAAiBC,IAAcxqB,EAC/BnQ,EAAO46B,IAAID,OAEV,IAAI36B,EAAOm6B,4BAA4BQ,GACxC,OAAO,MAKfD,GAAiB,EACjB16B,EAAO46B,IAAIzqB,IAGRuqB,GAGXd,aAAc,SAASzpB,EAAIgY,GACEhuB,SAArBguB,EAAS5V,SACTtE,EAAQ4U,cAAc1S,EAAIgY,EAAS5V,UAO3C4jB,kBAAmB,SAAS0E,EAAkBhS,GAC1C,GAAIV,GAAW0S,CAcf,OAVK7kC,IAAGuG,SAASs+B,KACb1S,KAEInyB,GAAGwH,SAASq9B,KAAsBhS,IAClCV,EAAShoB,MAAQ06B,IAIzB1S,EAASrmB,QAAU+mB,EAEZV,GAGXyS,IAAK,SAASzqB,GACV,GAAIpY,GAAOkW,EAAQgI,QAAQ9F,EAE3B,KAAKolB,EAAWze,QAAQ3G,GACpB,KAAM,IAAIna,IAAGwB,MAAM2Y,EAAK,qCAG5BlC,GAAQ6T,SAAS3R,EAAIpY,GAAM+U,KACvB,SAASqb,GACDA,GAAYA,EAASlc,OACrBgC,EAAQgE,UAAU9B,EAAIna,GAAGya,OAAO6C,QAChCgS,EAAQrZ,MAAMkE,GACdonB,EAAkBC,KAAKrnB,IAGnBqlB,GAAoBlQ,EAAQwV,qBAAqB3qB,GACjDulB,EAAQoC,SAAS3nB,GAGjBupB,EAAOnH,KAAKpiB,EAAIpY,IAK5B,SAASoI,GAKL,GAJAA,EAAQA,MAERhE,EAAIgU,EAAK,qEAAuEhQ,EAAO,UAElF8N,EAAQyU,YAAYvS,EAAIpY,EAAMoI,EAAMwiB,kBAAqB,CAC1D,GAAIwF,GAAWnoB,EAAOm2B,kBAAkBh2B,EAAMwiB,cAAc,EAC5D3iB,GAAOq2B,QAAQlmB,EAAIgY,OAMnCrnB,MAAO,SAASqP,GACZ,GAAI4qB,GAAe/6B,EAAOk5B,eAAe/oB,EAEzC,OAAI4qB,GACO/6B,EAAOo6B,WAAWjqB,EAAI4qB,IAG7B/6B,EAAO46B,IAAIzqB,IACJ,IAKnBna,IAAG6B,OAAOxB,MAINmQ,IAAK,SAAS2J,EAAIqB,GACd8T,EAAQ9e,IAAIP,MAAM5P,KAAM8H,YAM5B6B,OAAQ,SAASmQ,GACb,QAAIonB,EAAkBlF,KAAKliB,IAChBnQ,EAAOc,MAAMqP,IAK5BmK,MAAO,SAASnK,GAWZ,MANIslB,KACAnQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK2wB,eAAgB,GAK/CQ,EAAkBgC,kBAAkBppB,GAC7BnQ,EAAOc,MAAMqP,GAObolB,EAAWv1B,OAAOmQ,IAOjC2F,OAAQ,SAAS3F,GACb,GAAI6qB,GAAe1V,EAAQxP,OAAO3F,EAE9Bna,IAAG4W,iBAAiBouB,GACpBA,EAAaluB,KAAK,WACd9M,EAAO8V,OAAO3F,KAGb6qB,KAAiB,GACtBh7B,EAAO8V,OAAO3F,IAOtBgG,UAAW,WACP,GACIzP,GADA0yB,EAAqB7B,EAAkB4B,uBAK3C,IAAIC,EAAmBr9B,OACnB,IAAK2K,EAAI0yB,EAAmBr9B,OAAS,EAAG2K,GAAK,EAAGA,IAC5C6uB,EAAWzf,OAAOsjB,EAAmB1yB,GAI7C6wB,GAAkB1nB,SAKtB6H,QAAS,SAASvH,GACd,MAAImV,GAAQwU,UAAYxU,EAAQwU,SAAS3pB,GAC9BmV,EAAQwU,SAAS3pB,GAAI1C,cAGzB6X,EAAQ5N,SAAW4N,EAAQ5N,QAAQvH,IAI9C8qB,UAAW,SAAS9qB,GAChB,SAAUmV,EAAQwU,WAAYxU,EAAQwU,SAAS3pB,KAGnDZ,SAAU,SAASY,GACf,GAAImV,EAAQ/V,SACR,MAAO+V,GAAQ/V,SAASY,IAIhCN,MAAO,WACH1T,EAAI,4BACJo5B,EAAWpf,YACXohB,EAAkB1nB,QAClByV,EAAQzV,SAGZ0J,QAAS,SAASpJ,GACd,GAAIolB,EAAWze,QAAQ3G,GACnB,MAAOmV,GAAQ/L,QAAQpJ,IAO/B2G,QAAS,SAAS3G,GACd,MAAOmV,GAAQxO,QAAQ3G,IAG3BiJ,gBAAiB,SAASjJ,GACtB,GAAI1K,GAAM6f,EAAQxO,QAAQ3G,IACtBmV,EAAQ4V,oBACR5V,EAAQ4V,mBAAmB/qB,EAE/B,SAAI1K,KACSqE,aAAapE,QAAQD,IAMtCiT,sBAAuB,WACnB,MAAI4M,GAAQ5M,sBACD4M,EAAQ5M,4BAavBuc,oBAAqB,SAAS9kB,GAC1B,GAAIolB,EAAWze,QAAQ3G,GACnB,MAAOmV,GAAQ2P,oBAAoB9kB,IAS3ClE,MAAO,SAASkE,GACZ,SAAIolB,EAAWpc,YAAYhJ,IAAOmV,EAAQrZ,OAASspB,EAAWze,QAAQ3G,IAAOmV,EAAQrZ,MAAMkE,MACvFonB,EAAkBC,KAAKrnB,GACvBmV,EAAQgS,0BAA0BnnB,IAC3B,IAKfgrB,mBAAoB,SAAShrB,GACzB,QAASmV,EAAQ6V,oBAAsB7V,EAAQ6V,mBAAmBhrB,IAItEgJ,YAAa,SAAShJ,GAClB,QAASmV,EAAQnM,aAAemM,EAAQnM,YAAYhJ,MAI5Dna,GAAG6B,OAAOoW,EAASJ,GACnB1R,EAAM8R,EAAQ9R,IACdq5B,EAAmBvnB,EAAQ5C,SAASmL,SAAWxgB,GAAG8S,kBAAkBuC,SACpEoqB,EAA6BD,GAAoBvnB,EAAQ5C,SAASkjB,WAAW/X,QAE7E8e,EAAwB,WACpB,GAAInN,KAIJ,OAFAA,GAASla,EAAQ+S,oBAAqB,EAE/BmH,KAGXnoB,EAAO+5B,eC1zBX/jC,GAAGolC,qBAAuB,SAASvtB,GAC/B,YAEA,IAAII,IACI9R,IAAK,SAASC,EAASC,MAE3Bg/B,IAEJrlC,IAAG6B,OAAOoW,EAASJ,GAEnB7X,GAAG6B,OAAOxB,MACNilC,eAAgB,SAASnrB,EAAI9K,GACzB,GAAIk2B,GAA2B,SAASrQ,GAChC7lB,EAAS6lB,EAAMlwB,MAGnBE,QAAO+P,YACPowB,EAAyBlrB,GAAMna,GAAGkF,QAAQ5E,OAAO,UAAWilC,GAG5Dp/B,IAAI,wDAAyD,UAIrEq/B,sBAAuB,SAASrrB,GAC5B,GAAIjV,OAAO+P,YAAa,CACpB,GAAIwwB,GAAWJ,EAAyBlrB,EACpCsrB,IACAA,SCvBpBzlC,GAAG0lC,kBAAoB,SAAStqB,GAC5B,YAoBA,SAASuqB,GAAYxrB,SACVyrB,GAAiBzrB,GAKpB0rB,IACAvS,aAAawS,EAA0B3rB,UAChC2rB,GAA0B3rB,GACjC4rB,EAAoBP,sBAAsBrrB,GAG9C,IAAI6rB,GAASr8B,SAASs8B,eAAe3W,EAAQ4W,eAAe/rB,GACxD6rB,KAIAA,EAAO70B,aAAa,MAAO,qBAE3BnR,GAAGgmC,GAAQ5kC,UAQnB,QAAS+kC,GAAuBC,GAC5B,MAAOA,GAAW1gC,MAAM,KAAK,GAUjC,QAAS2gC,GAAoBtkC,GACzB,GAAIikC,GAAShmC,GAAGgP,UAAU,yCAA2CjN,EAAO,OAO5E,OALAikC,GAAO70B,aAAa,KAAMpP,GAE1BikC,EAAO7lC,MAAMC,QAAU,OACvBuJ,SAAS28B,KAAKl1B,YAAY40B,GAEnBA,EAUX,QAASO,GAA4BP,EAAQ32B,GACzC,GAAI+2B,GAAaJ,EAAO7rB,GACpB6G,EAASmlB,EAAuBC,EAGpCI,GAFWtjB,EAAQlC,IAEK3R,EAIxBu2B,EAAiB5kB,GAAUhhB,GAAGgmC,GAAQ1lC,OAAO,OAAQ,WAC7CgvB,EAAQ/V,SAASyH,KACjB7a,EAAI,mEAAqEigC,EAAa,KAEtFN,EAA0BM,GAAczc,WAAW,WAC/C,GAAI3D,GAAe,gEAAkEogB,CACrFjgC,GAAI6f,EAAc,SAClB3W,GACIlF,MAAO6b,KAEZ,QAMX+f,EAAoBT,eAAec,EAAY,SAAShgC,GACpDD,EAAI,2CAA6CC,EAAU,IAC3D,IAGIqgC,GAFAtU,GADSgU,EAAuBC,GACrB9W,EAAQoX,mBAAmBtgC,IACtCkU,EAAO6X,EAAS7X,IAGhBA,IAAQksB,EAAgBlsB,IACxBnU,EAAI,qCAAuCigC,GAC3C9S,aAAawS,EAA0BM,UAChCN,GAA0BM,GAEjC9W,EAAQqX,iBAAiBP,GAEzBK,EAAiBD,EAAgBlsB,SAE1BksB,GAAgBlsB,GACvByrB,EAAoBP,sBAAsBY,GAC1CK,EAAetU,IAET7X,GACNnU,EAAI,IAAMC,EAAU,2CAxHhC,GAAI6R,GAAUmD,EAAKnD,QACfqX,EAAUjvB,KACVy+B,EAAQ1jB,EAAK0jB,MACb8H,EAAwB5mC,GAAGiN,cAC3Bu5B,KACAZ,KACAE,KACAD,EAAS5tB,EAAQ4tB,OACjBrb,EAAYvS,EAAQuS,UACpBtH,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,IACZ4/B,EAAsB,GAAI/lC,IAAGolC,sBAAsBj/B,IAAKA,GAkH5DnG,IAAG6B,OAAOxB,KAAM,GAAIL,IAAG6+B,cAAczjB,IAErCpb,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OAIIgE,IAAK,SAAS2J,EAAIkU,GACd7hB,EAAOgE,IAAI2J,GAAKzQ,MAAO2kB,IAEvBA,EAAUld,aAAa,OAAQqZ,GAG3B6D,EAAUltB,YACVnB,GAAGquB,GAAWjtB,UAItBmiB,QAAS,SAASpJ,GACdwrB,EAAYxrB,GACZ3N,EAAO+W,QAAQpJ,IAGnB2G,QAAS,SAAS3G,GACd,MAAO3N,GAAOsU,QAAQ3G,IACkBhW,SAApCmrB,EAAQ4P,cAAc/kB,GAAIzQ,UAK1C1J,GAAG6B,OAAOxB,MACNkZ,SAAU,SAASY,GACf,MAAOmV,GAAQ4P,cAAc/kB,GAAIzQ,OAWrCm9B,iBAAkB,SAASb,EAAQ32B,GAE/B,GAAIy3B,EAEAjB,GACAU,EAA4BP,EAAQ32B,GAGpCu2B,EAAiBI,EAAO7rB,IAAMna,GAAGgmC,GAAQ1lC,OAAO,OAAQ,WAMpD,GALA6F,EAAI,yBAA2B6/B,EAAO7rB,IAKjC6rB,EAAO7kC,WAAZ,CAIA,IAEI,GAAI6kC,EAAOe,iBACPf,EAAOe,gBAAgBT,MACkB,SAAzCN,EAAOe,gBAAgBT,KAAKn3B,UAK5B,OAGR,MAAOhF,GAEHhE,EAAI,8EAAgFgE,EAAM/D,QAAU,IAAK,SACzG0gC,GAAsBh7B,SAAS,GAGnCuD,EAASy3B,OAWrBE,cAAe,SAAS7sB,GAGpB,MAAOksB,GAFU/W,EAAQ4W,eAAe/rB,KAU5CwsB,iBAAkB,SAASxsB,GACMhW,SAAzByhC,EAAiBzrB,KACjByrB,EAAiBzrB,WACVyrB,GAAiBzrB,KAQhC+rB,eAAgB,SAASllB,GACrB,MAAOA,GAAS,IAAM4lB,GAY1BK,mBAAoB,SAAS7rB,GACzB,GAAI8L,GAAS9L,EAAK8L,OACd/I,EAAW/C,EAAK+C,SAChBD,EAAS9C,EAAK8C,OACdgZ,EAAe9b,EAAK8b,aACpBgQ,EAAa9rB,EAAK8rB,WAClBh2B,EAAOlR,GAAGgP,UAAU,iBAAmBkY,EAAS,2CAChDyU,EAAMxd,CAcV,OAZI+Y,GACAl3B,GAAGiR,WAAWiN,EAAQhN,GAGtByqB,EAAM37B,GAAGkQ,QAAQgO,EAAQC,GAG7BjN,EAAKC,aAAa,SAAUwqB,GAC5BzqB,EAAKC,aAAa,SAAU+1B,GAC5Bh2B,EAAK/Q,MAAMC,QAAU,OACrBuJ,SAAS28B,KAAKl1B,YAAYF,GAEnBA,GAOXw1B,mBAAoB,SAASS,GACzB,GAAIhV,KAEJ,KACIA,EAAWnyB,GAAGqR,UAAU81B,GAE5B,MAAOh9B,GACHhE,EAAI,0DAA4DgE,EAAM/D,QAAU,IAAK,SAGzF,MAAO+rB,OCnSnBnyB,GAAGonC,iBAAmB,SAAShsB,GAC3B,YAqCA,SAASgmB,GAAMjnB,GACXna,GAAG+C,KAAKusB,EAAQ2R,SAAS9mB,GAAK,SAASktB,EAAO9b,GAC1C,GAAI+b,GAAgBhY,EAAQiY,kBAAkBptB,EAAIktB,EAElD9b,GAAI2Q,mBAAqB,KACzB3Q,EAAIvhB,OAAO4wB,WAAa,KACxBrP,EAAI6V,QACJkG,GAAiBA,EAAc1I,UAAY0I,EAAc1I,SAASzkB,KA1C1E,GAAImV,GAAUjvB,KACVyqB,EAAY1P,EAAKnD,QAAQ6S,UACzBgU,EAAQ1jB,EAAK0jB,MACbzpB,EAAW+F,EAAKnD,QAAQ5C,SACxBmyB,EAAe,SAASrtB,GACpB,GAAI4kB,GAAYzP,EAAQ4P,cAAc/kB,EAEtC,IAAI4kB,EAAUpG,UACV,MAAOoG,GAAUpG,SAIjB,IAAIA,GAAYtjB,EAASyjB,QAOzB,OALI94B,IAAG6G,WAAW8xB,KACdA,EAAYA,EAAUxe,EAAIwI,EAAQxI,KAGtC4kB,EAAUpG,UAAYA,EACfA,GAGfxiB,EAASiF,EAAKnD,QAAQ9B,OACtBsxB,EAAapyB,GAAY+F,EAAKnD,QAAQ5C,SAASmL,SAAWxgB,GAAG8S,kBAAkBuC,SAC/EqyB,EAAgBvxB,GAAUiF,EAAKnD,QAAQ9B,OAAOqK,SAAWinB,GAAcznC,GAAG8S,kBAAkBqD,OAC5F8J,EAAU6e,EAAM7e,QAChB0C,EAAUmc,EAAMnc,QAChBO,EAAU4b,EAAM5b,QAChBhB,EAAc4c,EAAM5c,YACpB8K,EAAgB8R,EAAM9R,cACtBH,EAAgBiS,EAAMjS,cACtB3B,EAAa4T,EAAM5T,WACnB/kB,EAAM24B,EAAM34B,IACZgnB,EAAsB2R,EAAM3R,mBAahCntB,IAAG6B,OAAOxB,KAAM,GAAIL,IAAG6+B,cAAczjB,IAErCpb,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OAIIgE,IAAK,SAAS2J,EAAIwtB,GACd,GAAI3nC,GAAGuI,OAAOo/B,IAAgB3nC,GAAGuJ,OAAOo+B,GACpCn7B,EAAOgE,IAAI2J,GAAKqB,KAAMmsB,QAErB,CAAA,KAAIA,YAAuB3nC,IAAGwX,WAI/B,KAAM,IAAIhW,OAAM,2CAHhBgL,GAAOgE,IAAI2J,GAAK2kB,MAAO6I,IAM3BrY,EAAQsY,eAAeztB,GACvButB,GAAiBpY,EAAQuY,uBAAuB1tB,IAGpDoJ,QAAS,SAASpJ,GACdinB,EAAMjnB,GACNmV,EAAQ8Q,+BAA+BjmB,GACvCmV,EAAQuU,WAAW1pB,GACnB3N,EAAO+W,QAAQpJ,OAK3Bna,GAAG6B,OAAOxB,MAENmgC,iBAAkB,SAASrmB,EAAIwlB,GAC3B,GAAIZ,GAAYzP,EAAQ4P,cAAc/kB,EAElC4kB,UACOA,GAAU3uB,KAAK03B,aAAanI,IAI3C4C,SAAU,SAASpoB,EAAIwlB,GACnB,GAAIoI,GAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAEtC23B,GAAUC,YACHD,GAAUC,KAAKrI,GAEtBoI,EAAUE,sBACHF,GAAUE,eAAetI,IAMxCM,eAAgB,SAAS9lB,EAAI+tB,GACzB,GAAIC,GAAe7Y,EAAQsS,gBAAgBznB,GAAM,EAC7CoR,EAAM+D,EAAQ8Y,QAAQjuB,EAAIguB,EAE9B,OAAID,IACO,GAAIloC,IAAG4L,SAAUE,QAAQo8B,EAAe3c,GAAMA,IAGlD,GAAIvrB,IAAG4L,SAAUE,WAAYyf,IAGxC7J,QAAS,SAASvH,GACd,MAAOmV,GAAQxO,QAAQ3G,IAAOmV,EAAQ4P,cAAc/kB,GAAIqB,MAG5DsoB,SAAU,SAAS3pB,GACf,MAAOmV,GAAQxO,QAAQ3G,IAAOmV,EAAQ4P,cAAc/kB,GAAI2kB,OAO5Dpc,sBAAuB,WACnB,GAAI2lB,KAuBJ,OArBA/Y,GAAQgZ,sBAAsB,SAAS74B,EAAKsQ,GACxCuP,EAAQgS,0BAA0B,KAAMvhB,EAAW1K,SAASurB,WAAa7gB,EAAW1K,SAASwrB,UAE7F,IAAI77B,IACAjD,KAAMge,EAAWhe,KACjB8+B,UAAW9gB,EAAW1K,SAASwrB,UAC/BtlB,KAAMwE,EAAWxE,KACjBjB,KAAMyF,EAAWzF,KAGjByF,GAAWtQ,MACXzK,EAAKyK,IAAMsQ,EAAWtQ,KAGtBsQ,EAAW0M,mBACXznB,EAAKynB,iBAAmB1M,EAAW0M,kBAGvC4b,EAAmBnlC,KAAK8B,KAGrBqjC,GAGXlD,mBAAoB,SAAShrB,GACzB,MAAOmV,GAAQ4P,cAAc/kB,GAAI0lB,kBAGrC1c,YAAa,SAAShJ,GAClB,QAAS9E,GAAYia,EAAQxO,QAAQ3G,KAChCmV,EAAQ4P,cAAc/kB,GAAIouB,cAGnCjH,0BAA2B,SAASnnB,EAAIquB,EAAeC,GACnD,GAAI1J,GAAYzP,EAAQ4P,cAAc/kB,OAClCuuB,EAAiB3J,EAAU1pB,aAC3BurB,EAAa4H,GAAiBE,EAAc9H,WAC5CC,EAAY4H,GAAgBC,EAAc7H,SAE1CD,KACAz6B,EAAInG,GAAG8H,OAAO,yDAA0DyJ,KAAKmrB,UAAUkE,KACvFA,EAAW+H,UACX3oC,GAAG+C,KAAK69B,EAAY,SAAS59B,EAAK28B,GAC9BkB,EAAUC,QAAQnB,KAEtBiB,EAAW76B,OAAS,IAI5BkQ,MAAO,SAASkE,GACZ,GAAImV,EAAQxO,QAAQ3G,GAIhB,MAHAhU,GAAInG,GAAG8H,OAAO,4DAA6DqS,EAAI8F,EAAQ9F,KACvFmV,EAAQ4P,cAAc/kB,GAAIyuB,QAAS,EACnCxH,EAAMjnB,IACC,GAIf0nB,mBAAoB,SAAS1nB,GACzB,GAAI9E,GAAYia,EAAQxO,QAAQ3G,GAAK,CACjC,GACI0uB,GACAn4B,EAFA0G,EAAQkY,EAAQ4P,cAAc/kB,EAQlC,UAJO/C,GAAM/B,SAEb+B,EAAM/B,YACNwzB,EAAcvZ,EAAQsS,gBAAgBznB,GAClC0uB,EAAc,GAAKxzB,EAASmjB,UAAW,CAKvC,IAJAphB,EAAM/B,SAASmL,SAAU,EACzBpJ,EAAM/B,SAASyzB,MAAQD,EACvBzxB,EAAM/B,SAASwrB,aAEVnwB,EAAI,EAAGA,EAAIm4B,EAAan4B,IACzB0G,EAAM/B,SAASwrB,UAAU39B,KAAKwN,EAGlC4e,GAAQsY,eAAeztB,OAGvB/C,GAAM/B,SAASmL,SAAU,IAKrC8jB,WAAY,SAASnqB,EAAI4uB,GACjBzZ,EAAQxO,QAAQ3G,KAChBmV,EAAQ4P,cAAc/kB,GAAIqB,KAAOutB,IAIzClF,WAAY,SAAS1pB,GACjB,GAAI4tB,GAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAE1CpQ,IAAG+C,KAAKglC,EAAUE,eAAgB,SAASe,SAChCjB,GAAUE,eAAee,KAGpChpC,GAAG+C,KAAKglC,EAAUC,KAAM,SAASgB,SACtBjB,GAAUC,KAAKgB,MAW9BC,WAAY,SAAS9uB,EAAI+uB,GACrB,MAAO5Z,GAAQ6Z,aAAahvB,EAAI+uB,EAAalpC,GAAG+J,sBAGpDw9B,kBAAmB,SAASptB,EAAI+uB,GAC5B,GAAIvJ,GAA0B,MAAfuJ,GAAsB,EAAKA,CAC1C,OAAO5Z,GAAQ4P,cAAc/kB,GAAI/J,KAAK63B,eAAetI,IAGzDC,cAAe,SAASzlB,EAAIivB,GACxB,GAAIzQ,GAAY6O,EAAartB,GACzBkvB,EAAW1mB,EAAQxI,GACnBtP,EAAaykB,EAAQ5N,QAAQvH,GAC7BmvB,EAAa3Q,EAAYyQ,EACzBG,EAAWD,EAAa3Q,GAAa0Q,EAAWA,EAAWC,EAAa3Q,EACxEkQ,EAAcvZ,EAAQsS,gBAAgBznB,GACtC2tB,EAAeznC,KAAK6+B,cAAc/kB,GAAI/J,KAAK03B,aAI3Cx8B,EAAOw8B,EAAasB,IAAeppC,GAAG4K,UAAUC,EAAYy+B,EAAYC,EAI5E,OAFAzB,GAAasB,GAAc99B,GAGvBk+B,KAAMJ,EACNt+B,MAAOw+B,EACPv+B,IAAKw+B,EACLE,MAAOZ,EACPv9B,KAAMA,EACNiQ,KAAMguB,EAAWD,IAIzBvJ,yBAA0B,SAAS7T,GAC/B,OACIG,UAAWH,EAAUsd,KACrBE,UAAWxd,EAAUphB,MAAQ,EAC7B6+B,QAASzd,EAAUnhB,IACnB8tB,WAAY3M,EAAUud,QAQ9BvE,mBAAoB,SAAS/qB,GACzB,GACIpY,GAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,GACfwe,EAAY6O,EAAartB,GACzBgE,EAAW+D,EAAY/H,GACvBgf,EAAahjB,EAAOgjB,WAAWhf,GAC/ByvB,EAAiB5pC,GAAG8H,OAAO,2BAA4BgjB,EANvC,MAMiE/oB,EAAMwZ,EAAMod,EAAWxa,EAM5G,OAJAgb,GAAW0Q,QAAQ,SAASp6B,GACxBm6B,GAAkB,IAAMn6B,IAGrBm6B,GAGXE,aAAc,SAAS3vB,GACnB,MAAOmV,GAAQ5N,QAAQvH,GAAI5Z,MAG/BwpC,oBAAqB,SAAS5vB,GAC1B,MAAOmV,GAAQ4P,cAAc/kB,GAAI9E,UAOrCusB,gBAAiB,SAASznB,GACtB,GAAI9E,EAAU,CACV,GAAIg0B,GAAW1mB,EAAQxI,GACnBwe,EAAY6O,EAAartB,EAE7B,OAAOxY,MAAKqoC,KAAKX,EAAW1Q,KAIpCyP,QAAS,SAASjuB,EAAI+uB,GAClB,GAAIvJ,GAA0B,MAAfuJ,GAAsB,EAAKA,CAC1C,OAAO5Z,GAAQ4P,cAAc/kB,GAAI/J,KAAK43B,KAAKrI,IAG/CsB,SAAU,SAAS9mB,GACf,MAAOmV,GAAQ4P,cAAc/kB,GAAI/J,KAAK43B,MAK1CM,sBAAuB,SAASj5B,GACxBq4B,GACA1nC,GAAG+C,KAAK+Q,aAAc,SAASrE,EAAKnI,GAChC,GAAwD,IAApDmI,EAAI9J,QAAQ3F,GAAG8H,OAAO,aAAcgjB,IAAmB,CAEvDzb,EAASI,EADQ8B,KAAKC,MAAMlK,QAO5CsgC,eAAgB,SAASztB,GACrBmV,EAAQ4P,cAAc/kB,GAAI/J,MACtB63B,kBACAnI,iBACAkI,QACAF,kBAIRmC,kBAAmB,SAAS9vB,GACxBmV,EAAQ4P,cAAc/kB,GAAIouB,cAAe,GAK7CnI,+BAAgC,SAASjmB,GACrC,GAAIyvB,EAEJ,UAAIlC,GAAiBpY,EAAQnM,YAAYhJ,KACrCyvB,EAAiBta,EAAQ4V,mBAAmB/qB,GAExCyvB,GAAkB91B,aAAapE,QAAQk6B,OACvC91B,aAAao2B,WAAWN,IACjB,IASnB/B,uBAAwB,SAAS1tB,GAC7B,GACIyvB,GAAgBO,EADhB/yB,EAAQkY,EAAQ4P,cAAc/kB,EAK9ButB,IAA+BvjC,SAAdiT,EAAM3H,MACvBm6B,EAAiBta,EAAQ4V,mBAAmB/qB,GAC5CgwB,EAAgBr2B,aAAapE,QAAQk6B,GAGjCO,IACAA,EAAgB54B,KAAKC,MAAM24B,GAIvBnd,EAAcmd,EAAc7vB,MAC5BgV,EAAQ2a,kBAAkB9vB,IAG1BhU,EAAInG,GAAG8H,OAAO,0DAA2DqS,EAAI8F,EAAQ9F,KAErF0S,EAAc1S,EAAIgwB,EAAc7vB,MAEhClD,EAAM3H,IAAM06B,EAAc16B,IAC1B2H,EAAM/B,SAAW80B,EAAc90B,SAC/B+B,EAAM+T,OAASgf,EAAchf,OAC7B/T,EAAMqV,iBAAmB0d,EAAc1d,iBACvCrV,EAAMyoB,kBAAmB,EAEzBvQ,EAAQgS,0BAA0BnnB,OAOlDmoB,0BAA2B,SAASnoB,GAChC,GACIyvB,GAAgBO,EADhB/yB,EAAQkY,EAAQ4P,cAAc/kB,EAIlC,IAAIutB,GAAiBpY,EAAQnM,YAAYhJ,GAAK,CAC1C,GAAIsS,GAAmBU,EAAoBhT,EAE3CyvB,GAAiBta,EAAQ4V,mBAAmB/qB,GAE5CgwB,GACIpoC,KAAMke,EAAQ9F,GACdoB,KAAMoH,EAAQxI,GACdG,KAAM4I,EAAQ/I,GACd1K,IAAK2H,EAAM3H,IACX4F,SAAU+B,EAAM/B,SAChB8V,OAAQ/T,EAAM+T,OACdif,YAAa1L,KAAKkG,OAGlBnY,IACA0d,EAAc1d,iBAAmBA,EAGrC,KACI3Y,aAAaC,QAAQ61B,EAAgBr4B,KAAKmrB,UAAUyN,IAExD,MAAOhgC,GACHhE,EAAInG,GAAG8H,OAAO,0DAA2DqS,EAAIhQ,EAAMxD,YAAa,WAK5G0jC,yBAA0B,SAASlwB,EAAIwlB,EAAUhH,GAC7C,GAAIpN,GAAM+D,EAAQ8Y,QAAQjuB,EAAIwlB,GAC1B59B,EAAOke,EAAQ9F,GACfmwB,GACI5G,OAAQ,SAASvY,EAAQC,GACrB,GAAIie,GAAW1mB,EAAQxI,EAEnBgR,KAAWC,EACXF,EAAW/Q,EAAIpY,EAAMsnC,EAAUA,GAG/Bne,EAAW/Q,EAAIpY,EAAOopB,GAAUke,EAAWA,EAAW,EAAIle,EAASke,IAI3E3J,QAAS,SAASvU,EAAQC,GACtB,GAAI0U,GAAgBxQ,EAAQ4P,cAAc/kB,GAAI/J,KAAK0vB,cAC/CyK,EAAiCjb,EAAQ4P,cAAc/kB,GAAIgR,OAC3Dqf,EAAmBrf,EACnBsf,EAAkBrf,EAClBwN,EAAgBjW,EAAQxI,GACxBuwB,EAAuBF,GAAoBC,EAAkB9R,GAC7DgS,EAAqBJ,CAEzBzK,GAAcH,GAAY+K,EAE1B1qC,GAAG+C,KAAK+8B,EAAe,SAASH,EAAUiL,GACtCD,GAAsBC,IAG1B1f,EAAW/Q,EAAIpY,EAAM4oC,EAAoB/R,IAIrDrN,GAAIvhB,OAAO4wB,WAAa,SAAS9rB,GAC7B,GAAIA,EAAE+tB,iBAAkB,CAGpByN,EADwB,MAAb3R,EAAoB,SAAW,WACjB7pB,EAAEqc,OAAQrc,EAAEsc,UAcjD+d,aAAc,SAAShvB,EAAI+uB,EAAa3d,EAAKsf,GACzC,GAAIC,GAAwB,MAAf5B,GAAsB,EAAKA,EACpCnB,EAAYzY,EAAQ4P,cAAc/kB,GAAI/J,IAW1C,OATA23B,GAAUC,KAAOD,EAAUC,SAC3BD,EAAUE,eAAiBF,EAAUE,mBAErCF,EAAUC,KAAK8C,GAAUvf,EAErBsf,IACA9C,EAAUE,eAAe6C,GAAUD,GAGhCtf,GAIX2Y,8BAA+B,WAC3B,GAAI6G,GAAiB50B,EAAO8iB,eAE5B3J,GAAQgZ,sBAAsB,SAAS74B,EAAKsQ,GACxC,GAAIirB,GAAiB,GAAItM,MAAK3e,EAAWqqB,YAGzCY,GAAeC,QAAQD,EAAeE,UAAYH,GAE9CC,EAAerM,WAAaD,KAAKkG,QACjCz+B,EAAI,2CAA6CsJ,GACjDqE,aAAao2B,WAAWz6B,OAWpCq1B,qBAAsB,SAAS3qB,GAC3B,GAAI/C,GAAQkY,EAAQ4P,cAAc/kB,EAGlC,IAAI/C,EAKA,MAJKA,GAAM/B,UACPia,EAAQuS,mBAAmB1nB,GAGxB/C,EAAM/B,SAASmL,YCziBtCxgB,GAAGinB,wBAA0B,SAASpP,GAClC,YAqBA,SAASszB,KACL,MAAqC,SAAjClzB,EAAQiP,OAAOC,eAEXikB,QAAS,aAtBrB,GAAIC,GACApzB,GACIiP,OAAQ,SACRG,cAAe,SACfK,iBACAN,eAAgB,EAChBI,cAAe,SAASrN,GAAK,UAC7BsN,eACAE,MACI8I,UAAU,EACV4I,iBAAiB,GAErBlzB,IAAK,SAAS4B,EAAK1B,KACnBuhB,SAAU,SAASzN,KACnB2N,iBAAkB,SAAS3N,EAAI4N,EAAUC,KAGjDhoB,IAAG6B,OAAOoW,EAASJ,GAYnBwzB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdM,cAAe,OAAQ,UACvBrW,OAAQjP,EAAQiP,OAChBQ,cAAezP,EAAQyP,cACvBD,YAAaxP,EAAQwP,YACrBgU,eAAgB0P,IAChB/jB,eAAgBnP,EAAQmP,eACxBI,cAAe,SAASrN,GACpB,MAAOlC,GAAQuP,cAAcpF,IAAIjI,IAErChU,IAAK8R,EAAQ9R,IACb01B,OAAQ5jB,EAAQ2P,SAChB0D,WAAYrT,EAAQ6P,iBACpBH,KAAM1P,EAAQ0P,QAGlB3nB,GAAG6B,OAAOxB,MACN+zB,WAAY,SAASja,EAAIG,EAAM0Z,GAC3B,GAAInJ,GAAoBmJ,KAExB/b,GAAQ9R,IAAI,sCAAwCgU,GAE7B,WAAnBlC,EAAQiP,OACRmkB,EAAUxN,cAAc1jB,GACnB6jB,SAAS1jB,GACT4jB,WAAWrT,GACX0R,QAGL1R,EAAkB5S,EAAQoP,eAAiB/M,EAC3C+wB,EAAUxN,cAAc1jB,GACnB+jB,WAAWrT,GACX0R,YCpDrB,WAMI,QAAS+O,GAAkBC,GACvB,GAGIC,GAHAC,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTvnC,EAASsF,SAASC,cAAc,SAGpC,OAAI6hC,GAAKE,EAAK,UACVtnC,EAAOwnC,MAAQxnC,EAAO0U,OAAS,EAC/ByyB,EAAMnnC,EAAOynC,WAAW,MACxBN,EAAIO,UAAUR,GAAME,EAAK,EAAG,GAIoB,IAAzCD,EAAIQ,aAAa,EAAG,EAAG,EAAG,GAAGhnC,KAAK,IAUjD,QAASinC,GAAqBV,EAAKE,EAAIE,GACnC,GAIIH,GAAKxmC,EAAMknC,EAAOC,EAJlB9nC,EAASsF,SAASC,cAAc,UAChCwiC,EAAK,EACLC,EAAKV,EACLW,EAAKX,CAUT,KAPAtnC,EAAOwnC,MAAQ,EACfxnC,EAAO0U,OAAS4yB,EAChBH,EAAMnnC,EAAOynC,WAAW,MACxBN,EAAIO,UAAUR,EAAK,EAAG,GACtBvmC,EAAOwmC,EAAIQ,aAAa,EAAG,EAAG,EAAGL,GAAI3mC,KAG9BsnC,EAAKF,GACRF,EAAQlnC,EAAgB,GAAVsnC,EAAK,GAAS,GACd,IAAVJ,EACAG,EAAKC,EAELF,EAAKE,EAETA,EAAMD,EAAKD,GAAO,CAItB,OADAD,GAASG,EAAKX,EACI,IAAVQ,EAAe,EAAIA,EAM/B,QAASI,GAAqBhB,EAAKjgC,EAAM2M,EAASu0B,GAC9C,GAAInoC,GAASsF,SAASC,cAAc,UAChCtF,EAAO2T,EAAQ3T,MAAQ,aACvBqH,EAAU,GAAI3L,IAAG4L,OASrB,OAPA6gC,GAAoBlB,EAAKjgC,EAAMjH,EAAQ4T,EAASu0B,GAC3C11B,KAAK,WACFnL,EAAQG,QACJzH,EAAOI,UAAUH,EAAM2T,EAAQ1T,SAAW,OAI/CoH,EAGX,QAAS+gC,GAAoCtxB,GAGzC,IAAKpb,GAAGsO,MACJ,KAAM,IAAItO,IAAGwB,MAAM,kEAGvB,IAAI4Z,EAAKuxB,WAAavxB,EAAKwxB,UANX,OAOZ,OACIC,UAAWlrC,KAAKC,MAAMD,KAAKmrC,KARnB,QAQqC1xB,EAAKuxB,WAAavxB,EAAKwxB,aACpEG,SAAUprC,KAAKC,MAAMD,KAAKmrC,KATlB,QASoC1xB,EAAKwxB,UAAYxxB,EAAKuxB,eAQ9E,QAASF,GAAoBlB,EAAKjgC,EAAMjH,EAAQ4T,EAASu0B,GACrD,GAMIQ,GANAvB,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTC,EAAQ5zB,EAAQ4zB,MAChB9yB,EAASd,EAAQc,OACjByyB,EAAMnnC,EAAOynC,WAAW,MACxBngC,EAAU,GAAI3L,IAAG4L,OAKrB,OAFA4/B,GAAIyB,OAEAh1B,EAAQi1B,OACDC,GACH7hC,KAAMA,EACNjH,OAAQA,EACR+xB,MAAOmV,EACP6B,YAAazB,EACb0B,WAAY5B,EACZ6B,YAAar1B,EAAQq1B,YACrBJ,OAAQj1B,EAAQi1B,OAChBK,aAAcx0B,EACdy0B,YAAa3B,KAIhB7rC,GAAG8S,kBAAkBwD,2BACtB02B,EAAqBN,GACjBE,UAAWf,EACXc,WAAY5zB,IAGZi0B,IACAhtC,GAAGmG,IAAInG,GAAG8H,OAAO,iFACb+jC,EAAO9yB,EAAQi0B,EAAmBD,SAAUC,EAAmBH,WAC/D,QAEJhB,EAAQmB,EAAmBD,SAC3Bh0B,EAASi0B,EAAmBH,YAIpCY,EAAoBppC,EAAQwnC,EAAO9yB,EAAQd,EAAQq1B,aAI/CttC,GAAGsO,MACF,WACOg9B,EAAkBC,KAClBE,GAAM,EACNE,GAAM,EAGV,IAOI+B,GAAQC,EAAIC,EAPZC,EAAI,KACJC,EAAYnkC,SAASC,cAAc,UACnCmkC,EAAkBvB,EAAWP,EAAqBV,EAAKE,EAAIE,GAAM,EACjEqC,EAAKrsC,KAAKqoC,KAAK6D,EAAIhC,EAAQJ,GAC3BwC,EAAKtsC,KAAKqoC,KAAK6D,EAAI90B,EAAS4yB,EAAKoC,GACjC3B,EAAK,EACL8B,EAAK,CAMT,KAHAJ,EAAUjC,MAAQiC,EAAU/0B,OAAS80B,EACrCH,EAASI,EAAUhC,WAAW,MAEvBM,EAAKT,GAAI,CAGZ,IAFAgC,EAAK,EACLC,EAAK,EACED,EAAKlC,GACRiC,EAAOS,UAAU,EAAG,EAAGN,EAAGA,GAC1BH,EAAO3B,UAAUR,GAAMoC,GAAKvB,GAC5BZ,EAAIO,UAAU+B,EAAW,EAAG,EAAGD,EAAGA,EAAGD,EAAIM,EAAIF,EAAIC,GACjDN,GAAME,EACND,GAAMI,CAEV5B,IAAMyB,EACNK,GAAMD,EAEVzC,EAAI4C,UACJN,EAAYJ,EAAS,QAIzBlC,EAAIO,UAAUR,EAAK,EAAG,EAAGM,EAAO9yB,GAGpC1U,EAAOgqC,iBAAmBhqC,EAAOgqC,kBACjC1iC,EAAQG,UAEDH,GAGX,QAASwhC,GAAqCmB,GAC1C,GAAIhjC,GAAOgjC,EAAWhjC,KAClB8qB,EAAQkY,EAAWlY,MACnBgX,EAAckB,EAAWlB,YACzBC,EAAaiB,EAAWjB,WACxBC,EAAcgB,EAAWhB,YACzB3hC,EAAU,GAAI3L,IAAG4L,QACjBshC,EAASoB,EAAWpB,OACpBqB,EAAe5kC,SAASC,cAAc,UACtC4kC,EAAsBD,EAAazC,WAAW,MAC9C2C,EAAeH,EAAWjqC,OAC1BkpC,EAAee,EAAWf,aAC1BC,EAAcc,EAAWd,WAyB7B,OAvBAC,GAAoBc,EAAclB,EAAYD,EAAaE,GAE3DmB,EAAa11B,OAASw0B,EACtBkB,EAAa5C,MAAQ2B,EAErBgB,EAAoBzC,UAAU3V,EAAO,EAAG,GAExC8W,GACI5hC,KAAMA,EACNyN,OAAQw0B,EACRnX,MAAOA,EACPmY,aAAcA,EACdE,aAAcA,EACd5C,MAAO2B,IAEN12B,KACG,WACI23B,EAAaJ,iBAAmBI,EAAaJ,kBAC7C1iC,EAAQG,WAEZH,EAAQK,SAGTL,EAOX,QAAS8hC,GAAoBppC,EAAQwnC,EAAO9yB,EAAQu0B,GAChD,OAAQA,GACJ,IAAK,GACL,IAAK,GACL,IAAK,GACL,IAAK,GACDjpC,EAAOwnC,MAAQ9yB,EACf1U,EAAO0U,OAAS8yB,CAChB,MACJ,SACIxnC,EAAOwnC,MAAQA,EACfxnC,EAAO0U,OAASA,EAExB,GAAIyyB,GAAMnnC,EAAOynC,WAAW,KAC5B,QAAQwB,GACJ,IAAK,GAED9B,EAAIkD,UAAU7C,EAAO,GACrBL,EAAI/pB,OAAM,EAAI,EACd,MACJ,KAAK,GAED+pB,EAAIkD,UAAU7C,EAAO9yB,GACrByyB,EAAImD,OAAOhtC,KAAKitC,GAChB,MACJ,KAAK,GAEDpD,EAAIkD,UAAU,EAAG31B,GACjByyB,EAAI/pB,MAAM,GAAG,EACb,MACJ,KAAK,GAED+pB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAI/pB,MAAM,GAAG,EACb,MACJ,KAAK,GAED+pB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAIkD,UAAU,GAAI31B,EAClB,MACJ,KAAK,GAEDyyB,EAAImD,OAAO,GAAMhtC,KAAKitC,IACtBpD,EAAIkD,UAAU7C,GAAQ9yB,GACtByyB,EAAI/pB,OAAM,EAAI,EACd,MACJ,KAAK,GAED+pB,EAAImD,QAAO,GAAOhtC,KAAKitC,IACvBpD,EAAIkD,WAAW7C,EAAO,IAUlC,QAASgD,GAAaC,EAAUC,GAC5B,GAAI52B,GAAO9X,IAEP6E,QAAOO,MAAQqpC,YAAoBrpC,OAClC,WACG,GAAI8lC,GAAM,GAAIyD,OACVC,EAAM/pC,OAAO+pC,KAAO/pC,OAAO+pC,IAAIC,gBAAkBhqC,OAAO+pC,IACpD/pC,OAAOiqC,WAAajqC,OAAOiqC,UAAUD,gBAAkBhqC,OAAOiqC,UAAY,IAClF,KAAKF,EAAO,KAAMztC,OAAM,uDACxB+pC,GAAI6D,IAAMH,EAAIC,gBAAgBJ,GAC9B32B,EAAK7M,KAAOwjC,EACZA,EAAWvD,KAGduD,EAASpD,cAAiBoD,EAASlD,gBACpCkD,EAASjjC,OAAS,WACd,GAAIwjC,GAAYl3B,EAAKm3B,kBACjBD,KACAl3B,EAAKm3B,mBAAqB,KAG1B3lB,WAAW,WACP,IAAK,GAAIjZ,GAAI,EAAG3D,EAAMsiC,EAAUtpC,OAAQ2K,EAAI3D,EAAK2D,IAC7C2+B,EAAU3+B,MAEf,KAGXo+B,EAAS/iC,QAAUgjC,EACnB1uC,KAAKivC,uBAETjvC,KAAKyuC,SAAWA,EAMpBD,EAAanoC,UAAU6oC,OAAS,SAASjjC,EAAQ2L,GAC7CA,EAAUA,KAEV,IASIu3B,GATAr3B,EAAO9X,KACPovC,EAAWpvC,KAAKyuC,SAASpD,aACzBgE,EAAYrvC,KAAKyuC,SAASlD,cAC1BC,EAAQ5zB,EAAQ4zB,MAChB9yB,EAASd,EAAQc,OACjBue,EAAWrf,EAAQqf,SACnBD,EAAYpf,EAAQof,UACpBmV,GAAYnsC,KAAKiL,MAA2B,eAAnBjL,KAAKiL,KAAK/K,KACnC+I,EAAUgD,EAAOhD,QAAQF,aAG7B,IAAI/I,KAAKivC,mBAEL,WADAjvC,MAAKivC,mBAAmBpsC,KAAK,WAAaiV,EAAKo3B,OAAOjjC,EAAQ2L,IAI9D4zB,KAAU9yB,EACVA,EAAU22B,EAAY7D,EAAQ4D,GAAa,EACpC12B,IAAW8yB,EAClBA,EAAS4D,EAAW12B,EAAS22B,GAAc,GAE3C7D,EAAQ4D,EACR12B,EAAS22B,GAETpY,GAAYuU,EAAQvU,IACpBuU,EAAQvU,EACRve,EAAU22B,EAAY7D,EAAQ4D,GAAa,GAE3CpY,GAAate,EAASse,IACtBte,EAASse,EACTwU,EAAS4D,EAAW12B,EAAS22B,GAAc,GAG/CF,GAAQ3D,MAAOA,EAAO9yB,OAAQA,GAC9B/Y,GAAG+C,KAAKkV,EAAS,SAAS03B,EAAYC,GAClCJ,EAAIG,GAAcC,IAGN,QAAZtmC,EACC,WACG,GAAIumC,GAAevjC,EAAO8iC,GAC1B7C,GAAqBp0B,EAAK22B,SAAU32B,EAAK7M,KAAMkkC,EAAKhD,GAC/C11B,KAAK,SAASpS,GACX4H,EAAO8iC,IAAM1qC,EACbmrC,IAAiBvjC,EAAO8iC,KAAO9iC,EAAOT,cAG/B,WAAZvC,GACPmjC,EAAoBpsC,KAAKyuC,SAAUzuC,KAAKiL,KAAMgB,EAAQkjC,EAAKhD,GAElC,kBAAlBnsC,MAAKyvC,UACZzvC,KAAKyvC,SAASxjC,IAItBtM,GAAG6uC,aAAeA,KCtYtB7uC,GAAG+5B,eAAiB,SAAS5zB,GACzB,YAEA,SAAS4pC,GAAMC,GACX,MAAoC,QAA7BA,EAAG1mC,QAAQF,cAGtB,QAAS6mC,GAASD,GACd,MAAoC,WAA7BA,EAAG1mC,QAAQF,cAGtB,QAAS8mC,KACL,MAAmC/rC,WAA5B,GAAI6qC,QAAQmB,YAGvB,QAASC,KACL,GAAI/rC,GAASsF,SAASC,cAAc,SAEpC,OAAOvF,GAAOynC,YAAcznC,EAAOynC,WAAW,MAMlD,QAASuE,GAAwBC,GAE7B,GAAIC,GAAeD,EAAa5qC,MAAM,KAClC3D,EAAOwuC,EAAaA,EAAaxqC,OAAS,GAAGL,MAAM,KAAK,GACxDmqB,EAAY7vB,GAAG0R,aAAa3P,EAIhC,QAFA8tB,EAAYA,GAAaA,EAAUzmB,eAG/B,IAAK,OACL,IAAK,MACD,MAAO,YACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,OACL,IAAK,MACD,MAAO,cASnB,QAASonC,GAAc7U,GACnB,GACI8U,GAAgBC,EAAgBC,EADhCC,EAAejnC,SAASC,cAAc,IAS1C,OANAgnC,GAAaC,KAAOlV,EAEpB8U,EAAiBG,EAAaE,SAC9BH,EAAaC,EAAaG,KAC1BL,EAAiBE,EAAaI,SAE1BP,EAAernC,gBAAkBlE,OAAO+rC,SAASH,SAAS1nC,gBAI1DsnC,EAAetnC,gBAAkBlE,OAAO+rC,SAASD,SAAS5nC,eAK1DunC,IAAezrC,OAAO+rC,SAASF,OAAS/wC,GAAGqN,MAOnD,QAAS6jC,GAAyB3F,EAAK5/B,GACnC4/B,EAAI1/B,OAAS,WACT0/B,EAAI1/B,OAAS,KACb0/B,EAAIx/B,QAAU,KACdJ,EAAQG,QAAQy/B,IAGpBA,EAAIx/B,QAAU,WACVw/B,EAAI1/B,OAAS,KACb0/B,EAAIx/B,QAAU,KACd5F,EAAI,6BAA8B,SAClCwF,EAAQK,QAAQu/B,EAAK,+BAI7B,QAAS4F,GAAgC9sC,EAAQsH,GAO7CtH,EAAOgqC,gBAAkB,WACrB1iC,EAAQG,QAAQzH,IAQxB,QAAS+sC,GAAkCnwB,EAAatV,GACpD,GAAI0lC,GAAatB,EAAM9uB,IAAgBgvB,EAAShvB,EAahD,OAXI8uB,GAAM9uB,GACNiwB,EAAyBjwB,EAAatV,GAEjCskC,EAAShvB,GACdkwB,EAAgClwB,EAAatV,IAG7CA,EAAQK,QAAQiV,GAChB9a,EAAInG,GAAG8H,OAAO,iDAAkDmZ,EAAY3X,SAAU,UAGnF+nC,EAKX,QAASC,GAAKzmC,EAAY8W,EAAW1J,GACjC,GAAIs5B,GAAc,GAAIvxC,IAAG4L,QACrB6c,EAAa,GAAIzoB,IAAGwxC,SAAS3mC,EAAY1E,GACzC+a,EAAUjJ,EAAQiJ,QAElBuY,EAA2B,MAAlBxhB,EAAQwhB,QAAwBxhB,EAAQwhB,OACjDgY,EAAsB,WAClB9vB,EAAU5V,QAAU,KACpB4V,EAAU9V,OAAS,KACnB1F,EAAI,mDAAoD,SACxDorC,EAAYvlC,QAAQ2V,EAAW,gCAiDvC,OA9CA8G,GAAWipB,gBAAgB56B,KACvB,SAASxS,GAGL,GAAIqtC,IACIngC,MAAO,WACH,OAAO,GAAIxR,IAAG4L,SAAUE,YAGhC8lC,EAAOnY,EAAS,GAAIz5B,IAAG6xC,KAAKhnC,EAAY1E,GAAOwrC,EAC/CG,EAAQ,GAAI9xC,IAAG6uC,aAAahkC,EAAY4mC,EAExCL,GAAkCzvB,EAAW4vB,IAC7CK,EAAKpgC,QAAQsF,KACT,SAAS86B,GACL,GAAItE,GAAcsE,GAAQA,EAAKG,WAE/BD,GAAMvC,OAAO5tB,GACT2V,SAAUpW,EACVmW,UAAWnW,EACXosB,YAAaA,EACbhpC,KAAMA,EACN4oC,OAAQj1B,EAAQmJ,wBAIxB,SAAS4wB,GACL7rC,EAAInG,GAAG8H,OAAO,iEAAkEkqC,IAEhFF,EAAMvC,OAAO5tB,GACT2V,SAAUpW,EACVmW,UAAWnW,EACX5c,KAAMA,EACN4oC,OAAQj1B,EAAQmJ,0BAOpC,WACIjb,EAAI,mBACJorC,EAAYvlC,QAAQ2V,EAAW,qBAIhC4vB,EAGX,QAASU,GAAyBtW,EAAKuW,EAAaZ,EAAMpwB,EAASE,GAC/D,GAAI+wB,GAAU,GAAInD,OACdoD,EAAgB,GAAIpyC,IAAG4L,OAE3BwlC,GAAkCe,EAASC,GAEvC5B,EAAc7U,KACdwW,EAAQhC,YAAc,aAG1BgC,EAAQ/C,IAAMzT,EAEdyW,EAAct7B,KACV,WACIs6B,EAAkCc,EAAaZ,GAEnC,GAAItxC,IAAG6uC,aAAasD,GAC1B5C,OAAO2C,GACT5a,SAAUpW,EACVmW,UAAWnW,EACX5c,KAAM+rC,EAAwB1U,GAC9BuR,OAAQ9rB,KAIhBkwB,EAAKtlC,SAIb,QAASqmC,GAA+B1W,EAAK4P,EAAK+F,EAAMpwB,GACpDkwB,EAAkC7F,EAAK+F,GAKvCtxC,GAAGurC,GAAKjqC,KACJg2B,SAAUpW,EAAU,KACpBmW,UAAWnW,EAAU,OAGzBqqB,EAAI6D,IAAMzT,EAWd,QAAS2W,GAAY3W,EAAKha,EAAW1J,GACjC,GAAIq5B,GAAO,GAAItxC,IAAG4L,QACd6V,EAAQxJ,EAAQwJ,MAChBP,EAAUO,EAAQxJ,EAAQiJ,QAAU,IA8BxC,OA3BIO,IAASsuB,EAAMpuB,GAGXyuB,IAIII,EAAc7U,KAASuU,IACvBmC,EAA+B1W,EAAKha,EAAW2vB,EAAMpwB,GAGrD+wB,EAAyBtW,EAAKha,EAAW2vB,EAAMpwB,GAInDmxB,EAA+B1W,EAAKha,EAAW2vB,EAAMpwB,GAIpD+uB,EAAStuB,GACdswB,EAAyBtW,EAAKha,EAAW2vB,EAAMpwB,GAG1CkwB,EAAkCzvB,EAAW2vB,KAClD3vB,EAAUytB,IAAMzT,GAGb2V,EAGXtxC,GAAG6B,OAAOxB,MAWNuhB,SAAU,SAAS2wB,EAAe5wB,EAAW1J,GACzC,MAAIjY,IAAGwH,SAAS+qC,IACZpsC,EAAI,4DACGmsC,EAAYC,EAAe5wB,EAAW1J,SAG7C9R,EAAI,iDACGmrC,EAAKiB,EAAe5wB,EAAW1J,WAMlD5X,KAAKmyC,YACLnyC,KAAKmyC,SAASzC,MAAQA,EACtB1vC,KAAKmyC,SAASvC,SAAWA,EACzB5vC,KAAKmyC,SAAShC,cAAgBA,EAC9BnwC,KAAKmyC,SAASnC,wBAA0BA,GChT5CrwC,GAAG6xC,KAAO,SAAShnC,EAAY1E,GAC3B,YAYA,SAASssC,GAAkBC,GAIvB,IAHA,GAAI/vC,GAAS,EACTgwC,EAAM,EAEHD,EAAI3sC,OAAS,GAChBpD,GAAU2gC,SAASoP,EAAIpqC,UAAU,EAAG,GAAI,IAAM3G,KAAKgxC,IAAI,EAAGA,GAC1DD,EAAMA,EAAIpqC,UAAU,EAAGoqC,EAAI3sC,QAC3B4sC,GAAO,CAGX,OAAOhwC,GAKX,QAASiwC,GAAWC,EAAQlnC,GACxB,GAAImnC,GAAYD,EACZE,EAAapnC,CAwBjB,OAvBkBxH,UAAd2uC,IACAA,EAAY,EACZC,EAAa,GAAI/yC,IAAG4L,SAGxB5L,GAAGqL,cAAcR,EAAYioC,EAAW,GAAGh8B,KAAK,SAAS47B,GACrD,GACIM,GADA3/B,EAAQ,cAAcpP,KAAKyuC,EAG3Br/B,GACiB,MAAbA,EAAM,IACN2/B,EAAgB1P,SAASoP,EAAIxqC,MAAM,EAAG,GAAI,IAC1C0qC,EAAWE,EAAYE,EAAgB,EAAGD,IAG1CA,EAAWjnC,QAAQgnC,GAIvBC,EAAW/mC,QAAQ,iCAIpB+mC,EAIX,QAASE,KACL,GAAItnC,GAAU,GAAI3L,IAAG4L,OAgBrB,OAdA5L,IAAGqL,cAAcR,EAAY,EAAG,GAAGiM,KAAK,SAAS47B,GACjB,IAAxBA,EAAI/sC,QAAQ,QACZgG,EAAQK,QAAQ,qBAGhB4mC,IAAa97B,KAAK,SAAS+7B,GACvBlnC,EAAQG,QAAQ+mC,IAEpB,SAAS1oC,GACLwB,EAAQK,QAAQ7B,OAKrBwB,EAIX,QAASunC,GAAeC,GACpB,GAAIxnC,GAAU,GAAI3L,IAAG4L,OAMrB,OAJA5L,IAAGqL,cAAcR,EAAYsoC,EAAY,GAAI,GAAGr8B,KAAK,SAAS47B,GAC1D/mC,EAAQG,QAAgB,SAAR4mC,KAGb/mC,EAIX,QAASynC,GAAiBD,EAAWE,GACjC,GAAI1nC,GAAU,GAAI3L,IAAG4L,OAWrB,OATA5L,IAAGqL,cAAcR,EAAYsoC,EAAY,GAAI,GAAGr8B,KAAK,SAAS47B,GAC1D,GAAIW,EACA,MAAO1nC,GAAQG,QAAQ2mC,EAAkBC,GAGzC/mC,GAAQG,QAAQw3B,SAASoP,EAAK,OAI/B/mC,EAIX,QAAS2nC,GAAOH,EAAWI,GACvB,GAAIV,GAASM,EAAY,GACrBjoC,EAAqB,GAAbqoC,CAEZ,OAAOvzC,IAAGqL,cAAcR,EAAYgoC,EAAQ3nC,GAIhD,QAASsoC,GAAcC,GAInB,IAHA,GAAIv5B,MACA24B,EAAS,EAENA,EAAS,IAAMY,EAAO1tC,QACzBmU,EAAQhX,KAAKuwC,EAAOvrC,MAAM2qC,EAAQA,EAAS,KAC3CA,GAAU,EAGd,OAAO34B,GAIX,QAASw5B,GAAaL,EAAcE,GAChC,GACII,GAAa3zC,GAAG6B,UAAW+xC,GAC3BC,IAsBJ,OApBA7zC,IAAG+C,KAAKwwC,EAAY,SAASvwC,EAAKm3B,GAC9B,GAGI2Z,GAAWxqC,EAASyqC,EAHpBC,EAAQ7Z,EAAMjyB,MAAM,EAAG,GACvBiS,EAAKk5B,EAAeZ,EAAkBuB,GAAS1Q,SAAS0Q,EAAO,IAC/DC,EAAgBN,EAAWhuC,QAAQwU,EAYvC,IATI85B,GAAiB,IACjB3qC,EAAU4qC,EAAS/5B,GAAIpY,KACvBgyC,EAAeG,EAAS/5B,GAAIjP,MAC5B4oC,EAAY3Z,EAAMjyB,MAbL,GAAA,GAa4D,EAAf6rC,GAC1DF,EAAKvqC,GAAW+pC,EAAeZ,EAAkBqB,GAAaxQ,SAASwQ,EAAW,IAElFH,EAAWt3B,OAAO43B,EAAe,IAGX,IAAtBN,EAAW5tC,OACX,OAAO,IAIR8tC,EApJX,GAAID,IAAW,KACXM,GACIC,KACIpyC,KAAM,cACNmJ,MAAO,GAmJnBlL,IAAG6B,OAAOxB,MAONmR,MAAO,WACH,GAAI4iC,GAAS,GAAIp0C,IAAG4L,QAChByoC,EAAiB,SAASjuC,GACtBD,EAAInG,GAAG8H,OAAO,kCAAmC1B,IACjDguC,EAAOpoC,QAAQ5F,GA0BvB,OAvBA6sC,KAAgBn8B,KAAK,SAASw9B,GAC1BnuC,EAAInG,GAAG8H,OAAO,mDAAwE3D,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,OAEtHmxC,EAAeoB,GAAYx9B,KAAK,SAASu8B,GAErCltC,EAAInG,GAAG8H,OAAO,+BAAgCurC,EAAe,SAAW,QAExED,EAAiBkB,EAAYjB,GAAcv8B,KAAK,SAASy9B,GAErDpuC,EAAInG,GAAG8H,OAAO,kCAAmCysC,IAEjDjB,EAAOgB,EAAYC,GAAez9B,KAAK,SAAS28B,GAC5C,GAAIF,GAAaC,EAAcC,GAC3Be,EAAYd,EAAaL,EAAcE,EAE3CptC,GAAI,sCAEJiuC,EAAOtoC,QAAQ0oC,IAChBH,IACJA,IACJA,IACJA,GAEID,KAKf/zC,KAAKmyC,YACLnyC,KAAKmyC,SAASC,kBAAoBA,GC7MtCzyC,GAAGwxC,SAAW,SAAS3mC,EAAY1E,GAC/B,YAEA,SAASsuC,GAAeC,EAAYC,GAChC,GAAIC,IAAe,EACfC,KAAuB7kC,OAAO0kC,EASlC,OAPA10C,IAAG+C,KAAK8xC,EAAmB,SAAS7xC,EAAK8xC,GACrC,GAAwD,IAApDH,EAAkBhvC,QAAQmvC,GAE1B,MADAF,IAAe,GACR,IAIRA,EAGX50C,GAAG6B,OAAOxB,MASNqxC,cAAe,WACX,GAAIv5B,GAAO9X,KACPooB,EAAa,GAAIzoB,IAAG4L,QACpBmpC,GAAc,EACdhzC,EAA2BoC,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,IAsC/D,OApCAoE,GAAInG,GAAG8H,OAAO,gEAAiE/F,IAE/EoE,EAAI,oDAEA9F,KAAK20C,qBACL7uC,EAAI,sDAEJnG,GAAGqL,cAAcR,EAAY,EAAG,GAAGiM,KAAK,SAAS47B,GAC7C1yC,GAAG+C,KAAKoV,EAAK88B,uBAAwB,SAAS3wC,EAAM4G,GAChD,GAAIupC,EAAevpC,EAAOwnC,GAQtB,OALa,eAATpuC,GAAyBtE,GAAG8S,kBAAkBuD,gBAC9C0+B,GAAc,EACdtsB,EAAW3c,QAAQxH,KAGhB,IAIf6B,EAAInG,GAAG8H,OAAO,iDAAkD/F,EAAMgzC,EAAc,GAAK,QAEpFA,GACDtsB,EAAWzc,WAGnB,WACI7F,EAAI,+BAAiCpE,EAAO,gDAC5C0mB,EAAWzc,aAIfyc,EAAWzc,UAGRyc,GAWXusB,kBAAmB,WACf,GAAIE,GAAWrqC,EAAWtK,KAEtB40C,EAAoBn1C,GAAG2F,QAAQc,OAAOu6B,KAAK3gC,KAAK40C,wBAAyBC,IAAa,EACtFH,GAAc,EACdhzC,EAA2BoC,SAApB0G,EAAW9I,KAAqB,OAAS8I,EAAW9I,IAa/D,OAXIozC,KAEIJ,EADa,eAAbG,GACcl1C,GAAG8S,kBAAkBuD,eAO1C0+B,GAAe5uC,EAAIpE,EAAO,gEAEpBgzC,MAKnB/0C,GAAGwxC,SAAS9qC,UAAUuuC,wBAClBG,aAAc,SACdC,YAAa,SACbC,YAAa,SACbC,YAAa,OACbC,cAAe,WAAY,aCpG/Bx1C,GAAGk2B,gBAAkB,SAAS5qB,EAAMnF,GAChC,YAMA,SAASsvC,GAAiBC,GACtB,GAAIC,IAAa,CASjB,OAPA31C,IAAG+C,KAAK2yC,EAAQ,SAASE,EAAO7uC,GAC5B,GAAIA,EAAQ,EAER,MADA4uC,IAAa,GACN,IAIRA,EAQX,QAASE,KACL,GAAIC,GAAoB,GAAI91C,IAAG4L,OA6B/B,OA3BA,IAAI5L,IAAGwxC,SAASlmC,EAAMnF,GAAKurC,gBAAgB56B,KAAK,WAC5C,GAAIsf,GAAQ,GAAI4Y,OACZrT,EAAMz2B,OAAO+pC,KAAO/pC,OAAO+pC,IAAIC,gBAAkBhqC,OAAO+pC,IAClD/pC,OAAOiqC,WAAajqC,OAAOiqC,UAAUD,gBAAkBhqC,OAAOiqC,UAC9D,IAENxT,IACAvF,EAAMrqB,QAAU,WACZ5F,EAAI,4DAA6D,SACjE2vC,EAAkB9pC,WAGtBoqB,EAAMvqB,OAAS,WACXiqC,EAAkBhqC,SACd+/B,MAAOxrC,KAAKwrC,MACZ9yB,OAAQ1Y,KAAK0Y,UAIrBqd,EAAMgZ,IAAMzT,EAAIuT,gBAAgB5jC,KAGhCnF,EAAI,+DAAgE,SACpE2vC,EAAkB9pC,YAEvB8pC,EAAkB9pC,SAEd8pC,EASX,QAASC,GAAgBL,EAAQM,GAC7B,GAAIC,EA0BJ,OAxBAj2C,IAAG+C,KAAK2yC,EAAQ,SAASQ,EAAWC,GAChC,GAAIA,EAAa,EAAG,CAChB,GAAIC,GAAe,0BAA0BnyC,KAAKiyC,GAC9CG,EAAoBD,EAAa,GAAGzmC,OAAO,GAAGvG,cAAgBgtC,EAAa,GAAGluC,MAAM,GACpFouC,EAAcN,EAAWK,EAG7B,QAAQD,EAAa,IACjB,IAAK,MACD,GAAIE,EAAcH,EAEd,MADAF,GAAeC,GACR,CAEX,MACJ,KAAK,MACD,GAAII,EAAcH,EAEd,MADAF,GAAeC,GACR,MAOpBD,EAWX51C,KAAK81B,SAAW,SAASuf,GACrB,GAAIa,GAAmB,GAAIv2C,IAAG4L,OAoB9B,OAlBAzF,GAAI,iCAEAsvC,EAAiBC,GACjBG,IAAiB/+B,KAAK,SAASk/B,GAC3B,GAAIC,GAAeF,EAAgBL,EAAQM,EAEvCC,GACAM,EAAiBvqC,QAAQiqC,GAGzBM,EAAiBzqC,WAEtByqC,EAAiBzqC,SAGpByqC,EAAiBzqC,UAGdyqC,IC7Hfv2C,GAAGo1B,QAAU,SAASha,GAClB,YAaA,SAASo7B,GAAoBrkB,GACzB,GAAInyB,GAAG8G,QAAQqrB,GACX,OAAO,CAGXla,GAAQ9R,IAAI,oCAAqC,SAGrD,QAASswC,GAAgBC,EAAW5qC,EAASic,EAAUpc,GACnD,GAAIgrC,IAAmB,CAEvB7qC,GAAUA,GAAW0qC,EAAoBE,GAErC5qC,GACA9L,GAAG+C,KAAK2zC,EAAW,SAAS1zC,EAAKg8B,GAE7B,GAAqB,MAAjBA,EAAS1kB,KACTq8B,GAAmB,EACnB1+B,EAAQ9R,IAAInG,GAAG8H,OAAO,oEAAqE9E,GAAM,aAEhG,IAAqB,MAAjBg8B,EAASj9B,KACd40C,GAAmB,EACnB1+B,EAAQ9R,IAAInG,GAAG8H,OAAO,oEAAqE9E,GAAM,aAGjG,KAEI,MADAiV,GAAQqd,cAAc0J,IACf,EAEX,MAAO4X,GACHD,GAAmB,EACnB1+B,EAAQ9R,IAAIywC,EAAIxwC,QAAS,SAIjC,OAAO,IAIfuF,EAAQG,IAAY6qC,EAAmB,UAAY,WAAWD,EAAW3uB,GAlD7E,GAAI9P,IACAkG,SAAU,KACVD,UACAsJ,iBACAG,QACA2N,cAAe,SAASjP,KACxBlgB,IAAK,SAASC,EAASC,KAG3BrG,IAAG6B,OAAOoW,EAASmD,GAAM,GA8CzB/a,KAAKk1B,QAAU,WAEX,GAAIshB,GAAgB,GAAI72C,IAAG4L,QACvBkrC,EAA0B,SAAS3kB,EAAUrmB,EAASic,GAClD0uB,EAAgBtkB,EAAUrmB,EAASic,EAAU8uB,IAEjDE,EAAmB/2C,GAAG6B,UAAWoW,EAOrC,OANgB,IAAIjY,IAAGg3C,qBACfh3C,GAAG6B,OAAOk1C,GAAmBzrB,WAAYwrB,KAGvCG,cAEHJ,ICrEf72C,GAAGg3C,qBAAuB,SAAS57B,GAC/B,YAiBA,SAASkQ,GAAWnR,EAAI4N,EAAUC,GAC9B,GAAImK,GAAW,IAGf,IAA6B,MAAzBpK,EAASmvB,aACT,IACI/kB,EAAWnyB,GAAGqR,UAAU0W,EAASmvB,cAErC,MAAON,GACH3+B,EAAQ9R,IAAI,qCAAuCywC,EAAIxwC,QAAS,SAChE4hB,GAAU,EAIlB/P,EAAQqT,WAAW6G,GAAWnK,EAASD,GA7B3C,GAAIsjB,GACApzB,GACIkG,SAAU,KACVqJ,iBACAtJ,UACAyJ,MACI8I,UAAU,EACV4I,iBAAiB,GAErB/N,WAAY,SAAS6G,EAAUrmB,EAASic,KACxC5hB,IAAK,SAAS4B,EAAK1B,KAG3BrG,IAAG6B,OAAOoW,EAASmD,GAmBnBiwB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdM,cAAe,OACfrW,OAAQ,MACRQ,eACItF,IAAK,WACD,MAAOnK,GAAQkG,WAGvBqJ,cAAevP,EAAQuP,cACvBrhB,IAAK8R,EAAQ9R,IACbmlB,WAAYA,EACZ3D,KAAM1P,EAAQ0P,QAGlB3nB,GAAG6B,OAAOxB,MACN42C,YAAa,WACT,GAAI/4B,GAASle,GAAG6B,UAAWoW,EAAQiG,OAEnCjG,GAAQ9R,IAAI,0BAEZklC,EAAUxN,cAAc,kBACnBK,WAAWhgB,GACXsgB,kBACAjC,WCzDjBv8B,GAAG0kB,OAAS,SAAStJ,EAAMjV,GACvB,YAEA,IACIib,GAAuBhG,EAAKme,cAC5B4d,EAAkB/7B,EAAKoe,aACvBC,EAASre,EAAKqe,OACdC,EAActe,EAAKse,YACnBC,EAAiBve,EAAKue,eAAiB,IACvCyd,EAAoBh8B,EAAKwe,YACzBC,EAAcze,EAAKye,YACnBC,EAAQz5B,KAAKg3C,gBAAgBj8B,EAAK0e,MAGtC95B,IAAG6B,OAAOxB,MAGNmgB,QAASxgB,GAAG8S,kBAAkBsD,SAAW0jB,EAAM/zB,OAAS,EAExDuxC,eAAgB,SAASC,EAAkBC,EAAkBC,GACzD,GAAIt/B,GAAO9X,KACPq3C,KACAC,EAAeF,EAAuBnsC,KAAOmsC,EAAuBnsC,KAAOmsC,CAkD/E,OAjDiB,IAAIz3C,IAAGwxC,SAASmG,EAAcxxC,GAGhC6uC,qBAEXh1C,GAAG+C,KAAK+2B,EAAO,SAAS92B,EAAK40C,GACzB,GAAIC,GAAa1/B,EAAK2/B,sBAClBpe,YAAaA,EACbqe,cAAeH,EAAWr3C,KAC1By3C,QAASL,EAAap3C,MAG1Bm3C,GAAQx0C,MACJoX,KAAMta,GAAGiN,cACTlL,KAAMoW,EAAK8/B,SAAST,GAChBz1C,KAAM61C,EAAW71C,KACjBxB,KAAMs3C,EACNG,QAASL,EAAap3C,OAE1B+K,KAAM,GAAItL,IAAGwX,UAAUmgC,EACvB33C,GAAG4P,KAAKuI,EAAK+/B,qBAAsB//B,GAC/BiJ,qBAAsBA,EACtBF,QAAS02B,EAAW12B,QACpBuY,OAAQA,EACRl5B,KAAMs3C,EACNtzC,QAASo1B,EACTwe,WAAYf,EACZvd,YAAaA,EACb1zB,IAAKA,SAKjBuxC,EAAQx0C,MACJoX,KAAMi9B,EACNx1C,KAAMy1C,EACNj8B,KAAMo8B,EAAap8B,KACnBjQ,KAAM6rC,EAAkBQ,EAAe,QAI3CD,EAAQx0C,MACJoX,KAAMi9B,EACNx1C,KAAMy1C,EACNj8B,KAAMo8B,EAAap8B,KACnBjQ,KAAMqsC,IAIPD,GAGXzd,cAAe,SAASze,EAAMzZ,EAAMuY,EAAMiB,EAAMoU,EAAUlU,EAAS4L,EAAe+wB,GAC9E,GAAIjgC,GAAO9X,KAEPg4C,GADW78B,EAAKmL,YAAenL,EAAKlQ,MAAQkQ,EAAKlQ,KAAKqb,eAEtD2xB,EAAa,KACb7oB,EAAmB2oB,EAAI3oB,iBACvB1P,EAAaq4B,EAAIr4B,WACjB0H,EAAc2wB,EAAI3wB,YAClB/L,EAAe1b,GAAGiN,aAEtBjN,IAAG+C,KAAKoV,EAAKm/B,eAAeh9B,EAAMvY,EAAMyZ,GAAO,SAASxY,EAAKgZ,GACzD,GACI7B,GADAo+B,EAAWv8B,EAAOT,IAGlBS,GAAO1Q,eAAgBtL,IAAGwX,YAC1B+gC,GAAW,GAGfp+B,EAAK4F,EAAW5E,SACZb,KAAM0B,EAAO1B,KACbvY,KAAMia,EAAOja,KACbwZ,KAAMg9B,EACN98B,QAASA,EACTC,aAAcA,IAGdM,EAAO1Q,eAAgBtL,IAAGwX,UAC1B6gC,EAAUn1C,KAAKiX,GAGfm+B,EAAan+B,EAGb6B,EAAO1Q,MACPmkB,EAAiBtV,EAAI6B,EAAO1Q,MAC5BqkB,EAASzsB,MAAMiX,GAAIA,EAAIqB,KAAMQ,EAAO1Q,QAGpCyU,EAAW9D,UAAU9B,EAAIna,GAAGya,OAAO0C,YAOxB,OAAfm7B,IACAt4C,GAAG+C,KAAKs1C,EAAW,SAASr1C,EAAKw1C,GAC7B,GAAIt6B,IACAu6B,aAAc14B,EAAWlE,UAAU1B,GAAIm+B,IAAah+B,KACpDo+B,aAAc34B,EAAWlE,UAAU1B,GAAIm+B,IAAa/8B,KAKxD2C,GAAOmJ,GAAiBtH,EAAWlE,UAAU1B,GAAIq+B,IAAWl+B,KAE5DyF,EAAWlD,YAAY27B,EAAUF,GACjC7wB,EAAY8B,YAAYivB,EAAUt6B,KAKlCm6B,EAAUtyC,QACT,WACG,GAAI4yC,KACJA,GAAMtxB,GAAiBtH,EAAWlE,UAAU1B,GAAIm+B,IAAah+B,KAC7DmN,EAAY8B,YAAY+uB,EAAYK,WAQ5D34C,GAAG6B,OAAO7B,GAAG0kB,OAAOhe,WAChB8d,WAAY,SAASrK,EAAIsK,EAAO2zB,GAC5B,YAEA,KAAKp4C,GAAG8S,kBAAkBsD,QACtB,KAAM,IAAIpW,IAAGwB,MAAM,4CAGvB,IAAIo3C,GAAgB,GAAI54C,IAAG4L,QACvBzF,EAAMiyC,EAAIjyC,IACVqV,EAAO48B,EAAI12B,QAAQvH,GACnB4F,EAAaq4B,EAAIr4B,WAAWlE,UAAU1B,GAAIA,IAC1CpY,EAAOge,GAAcA,EAAWhe,KAChCuY,EAAOyF,GAAcA,EAAWzF,KAChCu+B,GACItf,cAAe9U,EAAM8U,cACrBC,cAAc,EACdC,OAAQhV,EAAMgV,OACdC,YAAajV,EAAMlkB,MAAQ,KAC3Bo5B,eAAgBlV,EAAMlgB,QACtB6yC,kBAAmB,kBACnBtd,QAAS/3B,KAAM,GAAImf,QAASuD,EAAMvD,WAEtC43B,EAAS,GAAI94C,IAAG0kB,OAAOm0B,EAAgB1yC,EAuB3C,OArBKnG,IAAG0kB,QAAW1kB,GAAG8S,kBAAkBgD,eAAkB0F,EAOrDxb,GAAG4P,KAAK,WAEL,GAAIoM,GAAS88B,EAAOxB,eAAeh9B,EAAMvY,EAAMyZ,GAAM,EAEjDQ,IAAUA,EAAO1Q,eAAgBtL,IAAGwX,UACpCwE,EAAO1Q,KAAKqM,SAASb,KAAK8hC,EAAc9sC,QAAS8sC,EAAc5sC,UAG/D7F,EAAIgU,EAAK,4BAA6B,SACtCy+B,EAAc5sC,YAEnB3L,SAjBHu4C,EAAc5sC,UAEd7F,EAAI,iDAAmDgU,EAAK,uFAC6B,UAiBtFy+B,GAKXd,qBAAsB,SAAS18B,GAC3B,YAEA,IAAI28B,GAAgB38B,EAAK28B,cACrBre,EAActe,EAAKse,YACnBqf,EAAgB39B,EAAK48B,OAIzB,OAAKte,IAAgBqe,EAQhBA,GAKD/3C,GAAG2F,QAAQc,OAAOu6B,KAAKhhC,GAAGwxC,SAAS9qC,UAAUuuC,wBAAyB8C,IAAkB,EAClE,eAAlBA,EACO/3C,GAAG8S,kBAAkBuD,aAAe0hC,EAAgBre,EAGxDqe,EATAre,EARe,eAAlBqf,EACO,YAEJA,GAqBfd,SAAU,SAAS38B,EAAc09B,GAC7B,YAEA,IAAIC,GAAa39B,EAAazJ,YAAY,KACtCqnC,EAAcF,EAAwBz4C,MAAQ,YAC9Cw4C,EAAgBC,EAAwBhB,QACxCmB,EAAa,GACbC,EAAYp5C,GAAG0R,aAAa4J,GAC5B+9B,EAAgB,EAmBpB,OAjBIL,GAAwBj3C,MAAQi3C,EAAwBj3C,KAAK8F,OAAO9B,SACpEszC,EAAgB,KAAOL,EAAwBj3C,KAAO,KAGtDk3C,GAAc,GACdE,EAAa79B,EAAaxJ,OAAO,EAAGmnC,GAEhCF,IAAkBG,IAClBE,EAAYF,EAAYxzC,MAAM,KAAK,IAGvCyzC,GAAcE,EAAgB,IAAMD,GAGpCD,EAAa79B,EAAe+9B,EAGzBF,GAIX9B,gBAAiB,SAASvd,GACtB,YAIA,OAFAA,GAAQ95B,GAAG6B,UAAWi4B,GAEfA,EAAMwf,KAAK,SAASC,EAAGC,GAC1B,MAAID,GAAEr4B,QAAUs4B,EAAEt4B,QACP,EAEPq4B,EAAEr4B,QAAUs4B,EAAEt4B,SACP,EAEJ,KAIfg3B,qBAAsB,SAAS98B,EAAMq+B,GACjC,YAEA,IAAIthC,GAAO9X,KACP+gB,EAAuBhG,EAAKgG,qBAC5Bjb,EAAMiV,EAAKjV,IACX+a,EAAU9F,EAAK8F,QACfuY,EAASre,EAAKqe,OACdl5B,EAAO6a,EAAK7a,KACZgE,EAAU6W,EAAK7W,QACf4zC,EAAa/8B,EAAK+8B,WAClBte,EAAcze,EAAKye,aAAmC,eAApB4f,EAAWl5C,MAAkC,eAATA,EACtEq4C,EAAgB,GAAI54C,IAAG4L,QACvB8tC,EAAiB,GAAI15C,IAAG+5B,eAAe5zB,GACvC9B,EAASsF,SAASC,cAAc,SA8BpC,OA5BAzD,GAAI,6CAA+CszC,EAAW13C,MAE9D23C,EAAe93B,SAAS63B,EAAYp1C,GAAS6c,QAASA,EAASuY,OAAQA,EAAQrY,qBAAsBA,IAAuBtK,KAAK,WAC7H,GAAI6iC,GAAqBt1C,EAAOI,UAAUlE,EAAMgE,GAC5Cq1C,EAAgB,WACZzzC,EAAI,yCAA2CszC,EAAW13C,KAC1D,IAAIuJ,GAAOtL,GAAGwE,cAAcm1C,EAC5Bf,GAAc9sC,QAAQR,GAG1BuuB,GACA1hB,EAAK0hC,kBAAkBJ,EAAYE,EAAoBxzC,GAAK2Q,KAAK,SAASgjC,GACtEH,EAAqBG,EACrBF,KAEJ,WACIzzC,EAAI,wFAAyF,SAC7FyzC,MAIJA,KAEL,WACCzzC,EAAI,iDAAmDszC,EAAW13C,KAAM,SACxE62C,EAAc5sC,QAAQmsC,KAGnBS,GAIXiB,kBAAmB,SAASE,EAAeJ,EAAoBxzC,GAC3D,YAEA,IAAI6zC,GAAS,GAAItuC,YACbuuC,EAAkB,GAAIj6C,IAAG4L,QACzBsuC,EAAuB,EAc3B,OAZAF,GAAOnuC,OAAS,WACZquC,EAAuBF,EAAOr3C,OAC9Bs3C,EAAgBnuC,QAAQ9L,GAAGm6C,aAAa/L,QAAQ8L,EAAsBP,KAG1EK,EAAOjuC,QAAU,WACb5F,EAAI,mBAAqB4zC,EAAch4C,KAAO,2DAA4D,SAC1Gk4C,EAAgBjuC,WAGpBguC,EAAOI,cAAcL,GAEdE,GAGXI,eAAgB,SAAS31C,GACrB;YAEA,IAAIE,GAAYE,EAAYH,EAAaE,CAsBzC,OAlBID,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlC7F,KAAKi6C,YAAY31C,EAAaG,IAGzCw1C,YAAa,SAASt1C,EAAMV,GACxB,YAEA,IAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,OChZ3CtE,GAAGm6C,aAAe,WAGjB,GAAIA,KA+KD,OA7KAA,GAAaI,QAAU,oEAMvBJ,EAAaK,SAAW,SAAS9wC,GAE7B,GACI+wC,GAAMC,EACNC,EAAMC,EAAMC,EAFZC,EAAS,GACGC,EAAO,GACDC,EAAO,GACzBtqC,EAAI,CAER,GACI+pC,GAAO/wC,EAAMgH,KACbgqC,EAAOhxC,EAAMgH,KACbqqC,EAAOrxC,EAAMgH,KAEbiqC,EAAOF,GAAQ,EACfG,GAAgB,EAAPH,IAAa,EAAMC,GAAQ,EACpCG,GAAgB,GAAPH,IAAc,EAAMK,GAAQ,EACrCC,EAAc,GAAPD,EAEHE,MAAMP,GACPG,EAAOG,EAAO,GACNC,MAAMF,KACdC,EAAO,IAGVF,EAASA,EACNz6C,KAAKk6C,QAAQ5qC,OAAOgrC,GACpBt6C,KAAKk6C,QAAQ5qC,OAAOirC,GACpBv6C,KAAKk6C,QAAQ5qC,OAAOkrC,GACpBx6C,KAAKk6C,QAAQ5qC,OAAOqrC,GACvBP,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SACvBtqC,EAAIhH,EAAM3D,OAEnB,OAAO+0C,IAGXX,EAAa/L,QAAU,SAAS8M,EAAgBC,GAI5C,IAAKD,EAAe7nC,MAFO,2BAI1B,MAAO8nC,EAGR,IAAIC,GAAW/6C,KAAKg7C,SAASH,EAAe34C,QAPjB,0BAO+C,KACtE+4C,EAAWj7C,KAAKk7C,eAAeH,GAE/BhlB,EAAQ/1B,KAAKm7C,iBAAiBL,EAAmBG,EAErD,OAZ2B,0BAYGj7C,KAAKm6C,SAASpkB,IAKhD+jB,EAAaqB,iBAAmB,SAASL,EAAmBG,GAEpD,GAAIG,GAAYp7C,KAAKq7C,aAAaJ,GAC9BK,EAAgBt7C,KAAKu7C,WAAWT,EAAmBM,EAGvD,OAFc,IAAIz1C,YAAW21C,IAMrCxB,EAAauB,aAAe,SAASJ,GAG7B,IAAK,GADDO,GACKC,EAAI,EAAGA,EAAIR,EAASv1C,OAAQ+1C,IAGjC,GADAD,EAAMP,EAASQ,GACD,KAAVD,EAAI,GAAsB,KAAVA,EAAI,GAEpB,MAAOA,EAGf,WAIR1B,EAAayB,WAAa,SAAST,EAAmBM,GAE9C,GAAIM,GAAYZ,EAAkB54C,QAAQ,0BAA2B,IACjEy5C,EAAM37C,KAAKg7C,SAASU,GACpBE,EAAgBD,EAAIr2C,QAAQ,IAAI,GAChCu2C,EAAMF,EAAI9zC,MAAM,EAAG+zC,GACnBE,EAAMH,EAAI9zC,MAAM+zC,GAChBG,EAAQF,CAIb,OAFCE,GAAQA,EAAMpsC,OAAOyrC,GACrBW,EAAQA,EAAMpsC,OAAOmsC,IAM7BhC,EAAaoB,eAAiB,SAASc,GAKnC,IAHA,GAAIC,GAAO,EACPhB,OAGJ,CACI,GAA2B,KAAvBe,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAAW,KACjE,IAA2B,KAAvBD,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAElDA,GAAQ,MAGZ,CACI,GAAIv2C,GAAmC,IAA1Bs2C,EAAcC,EAAO,GAAWD,EAAcC,EAAO,GAC9DC,EAAWD,EAAOv2C,EAAS,EAC3B81C,EAAMQ,EAAcn0C,MAAMo0C,EAAMC,EACpCjB,GAASp4C,KAAK24C,GACdS,EAAOC,EAEX,GAAID,EAAOD,EAAct2C,OAAQ,MAGrC,MAAOu1C,IAKXnB,EAAakB,SAAW,SAAS3xC,GAE7B,GACI+wC,GAAMC,EACNC,EAAMC,EAAMC,EADAE,EAAO,GACDC,EAAO,GACzBtqC,EAAI,EACJsrC,IAIJ,IADiB,sBACF/3C,KAAKyF,GAChB,KAAM,IAAIlI,OAAM,uHAGpBkI,GAAQA,EAAMnH,QAAQ,sBAAuB,GAE7C,GACIo4C,GAAOt6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCkqC,EAAOv6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCmqC,EAAOx6C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MACzCsqC,EAAO36C,KAAKk6C,QAAQ50C,QAAQ+D,EAAMiG,OAAOe,MAEzC+pC,EAAQE,GAAQ,EAAMC,GAAQ,EAC9BF,GAAgB,GAAPE,IAAc,EAAMC,GAAQ,EACrCE,GAAgB,EAAPF,IAAa,EAAKG,EAE3BgB,EAAI94C,KAAKu3C,GAEG,IAARI,GACDmB,EAAI94C,KAAKw3C,GAEA,IAARM,GACDgB,EAAI94C,KAAK63C,GAGZN,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SAEvBtqC,EAAIhH,EAAM3D,OAEnB,OAAOi2C,IAIJ7B,KC7KXn6C,GAAGk6B,cAAgB,SAAS7qB,EAAUsT,GAClC,YAEA,IAAI65B,MACAC,EAAc,EACdC,EAAY,EAEZC,GAAiB,EACjBC,GAAgB,EAChBC,EAAgB,SAAS1xB,EAAQC,GACzBD,IAAWwxB,GAAkBvxB,IAAUwxB,GACvCvtC,EAAS8b,EAAQC,GAGrBuxB,EAAiBxxB,EACjByxB,EAAgBxxB,GAQpB0xB,EAAmB,SAAShqB,EAAQiqB,GAChC,GAAIC,IAAO,CASX,OAPAh9C,IAAG+C,KAAK+vB,EAAQ,SAAS9vB,EAAKi6C,GAC1B,GAAIj9C,GAAG2F,QAAQo3C,EAAWE,IAAa,EAEnC,MADAD,IAAO,GACA,IAIRA,GAGXvxB,EAAW,SAAStR,GAChB+iC,EAAoB/iC,GAAI,GAAI,SACrBqiC,GAAgBriC,IAG3B4Y,EAAgB,SAASF,EAAYC,EAAQiqB,IACnB,IAAlBjqB,EAAO/sB,QAAgB+2C,EAAiBhqB,EAAQiqB,MAChDF,EAAcH,EAAWA,GACzBr8C,KAAKwZ,UAIbsjC,EAAQ,SAAShjC,GACb,GAAIoB,GAAOoH,EAAQxI,EAGfoB,GAAO,IACP2hC,EAAoB/iC,EAAI,EAAGoB,GAC3BihC,EAAgBriC,IAAOgR,OAAQ,EAAGC,MAAO7P,KAYjD2hC,EAAsB,SAAS/iC,EAAIijC,EAAWC,GAC1C,GAAIC,GAAYd,EAAgBriC,GAAMqiC,EAAgBriC,GAAIgR,OAAS,EAC/DoyB,EAAWf,EAAgBriC,GAAMqiC,EAAgBriC,GAAIiR,MAAQ,CAE7DgyB,MAAc,GAAMC,KAAa,GACjCZ,GAAea,EACfZ,GAAaa,IAGTH,IACAX,GAAeW,EAAYE,GAE3BD,IACAX,GAAaW,EAAWE,IAIhCV,EAAcJ,EAAaC,GAGnC18C,IAAG6B,OAAOxB,MAEN0yB,cAAeA,EAGfnX,eAAgB,SAASzB,EAAIgC,EAAWD,GAChCA,IAAclc,GAAGya,OAAO4C,UAAYnB,IAAclc,GAAGya,OAAO0C,SAC5DsO,EAAStR,GAEJ+B,IAAclc,GAAGya,OAAOY,YAC7B8hC,EAAMhjC,IAKdsZ,qBAAsB,SAAStZ,EAAIgR,EAAQC,GACvC8xB,EAAoB/iC,EAAIgR,EAAQC,GAChCoxB,EAAgBriC,IAAOgR,OAAQA,EAAQC,MAAOA,IAIlDsK,UAAW,SAASvb,GAChBgjC,EAAMhjC,IAGVN,MAAO,WACH2iC,KACAC,EAAc,EACdC,EAAY,MCzHxB18C,GAAGkoB,aAAe,SAASrQ,GACvB,YAYA,SAAS2lC,GAAQl2C,GACb,MAAOA,GAAK/G,MACwB,IAAhC+G,EAAK/G,KAAKoF,QAAQ,UAG1B,QAAS83C,KACLC,EAAqB19C,GAAGiY,EAAQkQ,eAAe7nB,OAAO,QAAS,SAAS40B,GACpE,GAAIyoB,GAAgBzoB,EAAMyoB,aAEtBA,IACA39C,GAAG+C,KAAK46C,EAAcrzC,MAAO,SAAStH,EAAKsE,GACvC,GAAIk2C,EAAQl2C,GAAO,CACf,GAAIgE,GAAOhE,EAAKs2C,WAChB3lC,GAAQ6O,UAAUuB,cAAc/c,QAOpD,QAASuyC,KACDH,GACAA,IAhCR,GAAIzlC,GAASylC,CAEbzlC,IACIkQ,cAAe,KACfrB,WACI3gB,IAAK,SAASC,EAASC,KACvBgiB,cAAe,SAAS/c,OA8BhCtL,GAAG6B,OAAOoW,EAASJ,GACnB4lC,IAEAz9C,GAAG6B,OAAOxB,MACNwZ,MAAO,WACHgkC,QCpCZ79C,GAAGkwB,YAAc,SAASjY,EAAS6lC,EAAa33C,GAC5C,YAgCA,SAAS43C,GAAqBC,GACtBA,EAAO95C,aAAa,YACpBiU,EAAKoY,YAAcytB,EAAO95C,aAAa,WAM/C,QAAS+5C,GAAaD,EAAQE,GAC1B,IAAIF,EAAOG,eAAkBH,EAAOG,gBAKhC,OAAO,CAJPh4C,GAAI,yDAA0D,SAC9D+3C,IAQR,QAASE,GAAoBJ,GACzB,GAAIE,GAAeF,EAAOK,MAG1Br+C,IAAGg+C,GAAQ19C,OAAO,SAAU,SAAS40B,GACjCA,EAAQA,GAAShwB,OAAOgwB,MAEpBA,EAAMrmB,eACNqmB,EAAMrmB,iBAGNqmB,EAAMnmB,aAAc,EAGxBkvC,EAAaD,EAAQE,IAAiBJ,MAK1CE,EAAOK,OAAS,WACZJ,EAAaD,EAAQE,IAAiBJ,KAM9C,QAASQ,GAAgBN,GAarB,MAZIA,KACIh+C,GAAGwH,SAASw2C,KACZA,EAASr0C,SAASs8B,eAAe+X,IAGjCA,IACA73C,EAAI,8BACJ43C,EAAqBC,GACrB1kB,GAAmB8kB,EAAoBJ,KAIxCA,EAzFX,GAAI7lC,GAAQ9X,KACRi5B,EAAkBrhB,EAAQqhB,gBAC1B0kB,EAAS/lC,EAAQhY,QACjBowB,EAAapY,EAAQoY,UAGzBrwB,IAAG6B,OAAOxB,MAINkwB,YAAa,KAIbD,cAAeD,EAGfF,gBAAgB,EAGhBC,sBAAuB,WAEnB,MAAc,OAAV4tB,EACO,KAGJ7lC,EAAKomC,UAAUP,MAkE9BA,EAASM,EAAgBN,GACzB39C,KAAK8vB,iBAAmB6tB,GAG5Bh+C,GAAG6B,OAAO7B,GAAGkwB,YAAYxpB,WAGrB63C,UAAW,SAASrtC,GAChB,YACA,IAAIf,MACAquC,EAAoB,SAASj+C,GACzB,GAAIk+C,IACA,SACA,QACA,QACA,SAGJ,OAAOz+C,IAAG2F,QAAQ84C,EAAiBl+C,EAAK6I,eAAiB,GAE7Ds1C,EAAkB,SAASn+C,GACvB,MAAOP,IAAG2F,SAAS,WAAY,SAAUpF,EAAK6I,gBAAkB,GAEpEu1C,EAAc,SAAS3O,GACnB,SAAI0O,EAAgB1O,EAAGzvC,OAAUyvC,EAAG4O,UAI7B5O,EAAG98B,UAAsC,WAA1B88B,EAAGzvC,KAAK6I,eAElCy1C,EAAc,SAASC,GACnB,GAAI/3C,GAAQ,IASZ,OAPA/G,IAAG+C,KAAK/C,GAAG8+C,GAAQ17C,WAAY,SAASJ,EAAKK,GACzC,GAAoC,WAAhCA,EAAMiG,QAAQF,eAA8B/F,EAAM07C,SAElD,MADAh4C,GAAQ1D,EAAM0D,OACP,IAIRA,EAmBf,OAhBA/G,IAAG+C,KAAKmO,EAAK8tC,SAAU,SAASh8C,EAAKgtC,GACjC,IAAKhwC,GAAG+I,QAAQinC,GAAI,IAAsC,aAA7BA,EAAG1mC,QAAQF,gBACpCo1C,EAAkBxO,EAAGzvC,OACpBo+C,EAAY3O,IAIZ,GAAiC,WAA7BA,EAAG1mC,QAAQF,gBAA+Bu1C,EAAY3O,GAAK,CAChE,GAAIjpC,GAAQ83C,EAAY7O,EAEV,QAAVjpC,IACAoJ,EAAI6/B,EAAGjuC,MAAQgF,QANnBoJ,GAAI6/B,EAAGjuC,MAAQiuC,EAAGjpC,QAWnBoJ,KCzJfnQ,GAAGgkC,YAAchkC,GAAGgkC,gBACpBhkC,GAAGgkC,YAAY0B,kBAAoB,SAASztB,EAAS6mB,GACjD,YAUA,SAASmgB,GAAqB9kC,EAAI6rB,GAG9B,GAAI7T,GAAU+sB,EAAKC,CAGnB,KAEID,EAAMlZ,EAAOe,iBAAmBf,EAAOoZ,cAAcz1C,SACrDw1C,EAAYD,EAAI5Y,KAAKn3B,UAErBhJ,EAAI,yCACJA,EAAI,eAAiBg5C,GAEjBA,GAAaA,EAAU9rC,MAAM,YAC7B8rC,EAAYD,EAAI5Y,KAAKhjC,WAAWA,WAAW+7C,WAG/CltB,EAAW7C,EAAQoX,mBAAmByY,GAE1C,MAAOh1C,GACHhE,EAAI,wDAA0DgE,EAAM/D,QAAU,IAAK,SACnF+rB,GAAYrmB,SAAS,GAGzB,MAAOqmB,GAMX,QAASmtB,GAAWnlC,EAAI6rB,GACpB,GAAI9nB,GAASjG,EAAQwP,YAAYrF,IAAIjI,GACjC+M,EAA0C,QAAjCjP,EAAQiP,OAAO9d,cAA0B,MAAQ,OAC1D+U,EAAWlG,EAAQyP,cAActF,IAAIjI,GACrCpY,EAAOke,EAAQ9F,EAKnB,OAHA+D,GAAOjG,EAAQsP,UAAYrE,EAAQ/I,GACnC+D,EAAOjG,EAAQ8e,eAAiBh1B,EAEzButB,EAAQ2X,oBACX/f,OAAQA,EACR/I,SAAUA,EACVD,OAAQA,EACRgZ,aAAcjf,EAAQif,aACtBgQ,WAAYlB,EAAOjkC,OArD3B,GAAIutB,GAAUjvB,KACV4f,EAAU6e,EAAM7e,QAChBiD,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,GAsDhB9F,MAAKsjC,WAAa,SAASxpB,GACvB,GAGIjJ,GAHAxH,EAAQ4lB,EAAQ/V,SAASY,GACzB6rB,EAAS1W,EAAQ0X,cAAc7sB,GAC/BxO,EAAU,GAAI3L,IAAG4L,OA8BrB,OA3BAsF,GAAOouC,EAAWnlC,EAAI6rB,GACtB90B,EAAKE,YAAY1H,GAEjB4lB,EAAQuX,iBAAiBb,EAAQ,SAASuZ,GACtCp5C,EAAI,gBAEJ,IAAIgsB,GAAWotB,EAAsBA,EAAsBN,EAAqB9kC,EAAI6rB,EAEpF1W,GAAQqX,iBAAiBxsB,GAGpBlC,EAAQ0P,KAAK8I,UACdzwB,GAAGgmC,GAAQ5kC,SAGX+wB,EAASrmB,QACTH,EAAQG,QAAQqmB,GAGhBxmB,EAAQK,QAAQmmB,KAIxBhsB,EAAI,8BAAgCgU,GACpCjJ,EAAKmtC,SACLr+C,GAAGkR,GAAM9P,SAEFuK,GAGX3L,GAAG6B,OAAOxB,KAAM,GAAIL,IAAG0lC,mBACnBztB,SACI4tB,OAAQ5tB,EAAQ0P,KAAK8I,SACrBjG,UAAWvS,EAAQuS,WAGvBsU,OACIrT,SAAUxT,EAAQwT,SAClBxL,QAASA,EACTiD,QAASA,EACT/c,IAAKA,OC5GjBnG,GAAGgkC,YAAchkC,GAAGgkC,gBACpBhkC,GAAGgkC,YAAYoD,iBAAmB,SAAShsB,EAAM0jB,GAC7C,YAEA,IAAIxP,GAAUjvB,KACV4f,EAAU6e,EAAM7e,QAChB0C,EAAUmc,EAAMnc,QAChBO,EAAU4b,EAAM5b,QAChB/c,EAAM24B,EAAM34B,IACZq5C,EAAYpkC,EAAK4b,gBAAkB5b,EAAK8b,aAExCuoB,EAA4B,SAAStlC,EAAI+D,EAAQgO,GAC7C,GAAI3Q,GAAOoH,EAAQxI,GACfpY,EAAOke,EAAQ9F,EAEdiB,GAAK6b,oBACN/Y,EAAO9C,EAAK/F,SAASojB,WAAWpM,WAAaH,EAAUsd,KACvDtrB,EAAO9C,EAAK/F,SAASojB,WAAWC,gBAAkBxM,EAAUphB,MAC5DoT,EAAO9C,EAAK/F,SAASojB,WAAWE,WAAazM,EAAU3Q,KACvD2C,EAAO9C,EAAK/F,SAASojB,WAAWI,YAAc3M,EAAUud,MACxDvrB,EAAO9C,EAAKgc,mBAAqB7b,GAOjCikC,IAAcpkC,EAAK6b,oBACnB/Y,EAAO9C,EAAK2b,eAAiBh1B,IAIrC29C,EAAyB,GAAI1/C,IAAGgkC,YAAY2b,4BACxCh4B,KAAMvM,EAAKuM,KACXxJ,SAAU/C,EAAK/F,SAASvJ,QAAQqS,SAChCyG,QAASxJ,EAAK/F,SAASvJ,QAAQ8Y,QAC/BmU,YAAa3d,EAAK/F,SAASvJ,QAAQitB,YACnC5yB,IAAKA,EACL+gB,OAAQ9L,EAAK/F,SAASvJ,QAAQob,OAC9BhJ,OAAQ9C,EAAK/F,SAASvJ,QAAQoS,SAGlC0hC,EAAiC,SAASzlC,EAAIoR,GAC1C,GAAI5f,GAAU,GAAI3L,IAAG4L,OAerB,OAbA2f,GAAI2Q,mBAAqB,WACrB,GAAuB,IAAnB3Q,EAAIqR,WAAkB,CACtB,GAAIj6B,GAASk9C,EAAwB1lC,EAAIoR,EAErC5oB,GAAOmJ,QACPH,EAAQG,QAAQnJ,EAAOwvB,SAAU5G,GAGjC5f,EAAQK,QAAQrJ,EAAOwvB,SAAU5G,KAKtC5f,GAGXm0C,EAA0B,SAAS3lC,GAC/B,GAAI+D,GAAS9C,EAAKqM,YAAYrF,IAAIjI,GAC9BpY,EAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,EAOnB,OALA+D,GAAO9C,EAAKmM,UAAYrE,EAAQ/I,GAChC+D,EAAO9C,EAAK2b,eAAiBh1B,EAC7Bmc,EAAO9C,EAAKgc,mBAAqB7b,EACjC2C,EAAO9C,EAAK/F,SAASojB,WAAWI,YAAcvJ,EAAQsS,gBAAgBznB,GAE/D+D,GAGX6hC,EAAwB,SAASx0B,EAAK4G,GAClC,MAAOnyB,IAAG2F,SAAS,IAAK,IAAK,IAAK,IAAK,KAAM4lB,EAAI9Q,QAAU,GACtDW,EAAK+b,qBAAuBhF,EAASrmB,SACtCqmB,EAAStY,OAGjBgmC,EAA0B,SAAS1lC,EAAIoR,GACnC,GAAI4G,EAOJ,OALAhsB,GAAI,sCAAwCgU,GAC5ChU,EAAI,kBAAoBolB,EAAI2rB,cAE5B/kB,EAAW6tB,GAAc,EAAMz0B,IAG3Bzf,SAAUi0C,EAAsBx0B,EAAK4G,GACrCA,SAAUA,IAKlB6tB,EAAgB,SAASh2C,EAAQuhB,GAC7B,GAAI4G,KAEJ,KACIhsB,EAAInG,GAAG8H,OAAO,4CAA6CyjB,EAAI9Q,OAAQ8Q,EAAI2rB,eAC3E/kB,EAAWnyB,GAAGqR,UAAUka,EAAI2rB,cAEhC,MAAO/sC,GACHH,GAAUoR,EAAK+b,oBAAsBhxB,EAAI,qDAAuDgE,EAAM/D,QAAU,IAAK,SAGzH,MAAO+rB,IAGX8tB,EAA4B,SAAS9lC,GACjC,GAAIxO,GAAU,GAAI3L,IAAG4L,OAcrB,OAZA8zC,GAAuBQ,SACf/lC,EACAmV,EAAQ2Z,WAAW9uB,GACnB2lC,EAAwB3lC,GACxBiB,EAAKoM,cAAcpF,IAAIjI,IAE1BrD,KAAK,SAASyU,GACX5f,EAAQG,QAAQk0C,GAAc,EAAOz0B,GAAMA,IAC5C,SAASA,GACR5f,EAAQK,QAAQg0C,GAAc,EAAOz0B,GAAMA,KAG5C5f,GAGXw0C,EAA8B,SAASC,GACnC,GAOIliC,GAPArT,EAAau1C,EAAmBv1C,WAChCsP,EAAKimC,EAAmBjmC,GACxBoR,EAAM60B,EAAmB70B,IACzB80B,EAAeD,EAAmBC,iBAClCC,EAAeF,EAAmBE,iBAClCC,EAAgBH,EAAmBliC,WACnCsiC,EAAoBH,EAAaniC,WAGjCnN,EAAWyuC,EAAY,GAAI11C,UAAa,KACxCod,EAASm5B,EAAan5B,QAAU9L,EAAK8L,OACrC/I,EAAWkiC,EAAaliC,UAAY/C,EAAKsM,cAActF,IAAIjI,GAC3DpY,EAAOke,EAAQ9F,GACfoB,EAAOoH,EAAQxI,EAiCnB,OA/BIiB,GAAK6b,mBACL/Y,EAASle,GAAG6B,UAAWy+C,GACvBtgD,GAAG6B,OAAOqc,EAAQsiC,KAGlBtiC,EAASle,GAAG6B,UAAWy+C,GACvBtgD,GAAG6B,OAAOqc,EAAQsiC,GAClBxgD,GAAG6B,OAAOqc,EAAQqiC,GAElBriC,EAAO9C,EAAKmM,UAAYrE,EAAQ/I,GAChC+D,EAAO9C,EAAK2b,eAAiBh1B,EAEzBy9C,EACAthC,EAAO9C,EAAKgc,mBAAqB7b,EAE3BH,EAAK8b,eACXhZ,EAAO9C,EAAKoP,WAAazoB,IAK5BqZ,EAAK8b,eACN/Y,EAAWne,GAAGkQ,QAAQgO,EAAQC,IAGlCoN,EAAI8Q,KAAKnV,EAAQ/I,GAAU,GAEvB/C,EAAKuM,KAAK8I,UAAYrV,EAAKuM,KAAK0R,kBAChC9N,EAAIhY,iBAAkB,GAGtBisC,GACIpkC,EAAK8b,cACLl3B,GAAG8Q,aAAaoN,EAAQnN,GAG5BA,EAASxL,OAAO6V,EAAKoP,UAAW3f,GACzBkG,GAGJlG,GAGX41C,EAAmB,SAASC,GACxB,GAAIC,GAAkBD,EAAeC,gBACjCxmC,EAAKumC,EAAevmC,GACpBoR,EAAMm1B,EAAen1B,GAEzB,IAAIo1B,EACA3gD,GAAG+C,KAAK49C,EAAiB,SAASC,EAAYC,GAC1Ct1B,EAAI2R,iBAAiB0jB,EAAYC,SAGpC,CACD,GAAIC,GAAe1lC,EAAKoM,cAAcpF,IAAIjI,GACtCtP,EAAaykB,EAAQ5N,QAAQvH,EAEjCoR,GAAI2R,iBAAiB,SAAU,oBAC/B3R,EAAI2R,iBAAiB,mBAAoB,kBACzC3R,EAAI2R,iBAAiB,gBAAiB,YAEjCsiB,IACDj0B,EAAI2R,iBAAiB,eAAgB,4BAErC3R,EAAI2R,iBAAiB,cAAeryB,EAAWtK,OAGnDP,GAAG+C,KAAK+9C,EAAc,SAAS/+C,EAAMkB,GACjCsoB,EAAI2R,iBAAiBn7B,EAAMkB,MAK3CjD,IAAG6B,OAAOxB,MACN+hC,YAAa,SAAS2e,GAClB,GAOIp1C,GAASq1C,EAAQV,EAPjBnmC,EAAK4mC,EAAkB5mC,GACvBwlB,EAAWohB,EAAkBphB,SAC7BwC,EAAY4e,EAAkB5e,cAC9BjJ,EAAW6nB,EAAkB7nB,SAE7BhN,EAAYoD,EAAQsQ,cAAczlB,EAAIwlB,GACtCpU,EAAM+D,EAAQ2Z,WAAW9uB,EAAIwlB,GACEzhB,IA4BnC,OA1BAvS,GAAUi0C,EAA+BzlC,EAAIoR,GAC7C+D,EAAQ+a,yBAAyBlwB,EAAIwlB,EAAUzT,EAAU3Q,MACzD+kC,EAAellC,EAAKqM,YAAYrF,IAAIjI,GACpCslC,EAA0BtlC,EAAI+D,EAAQgO,GAElCgN,IACAhb,EAAO9C,EAAKjF,OAAOsiB,WAAWS,WAAY,GAG9C8nB,EAASb,GACLt1C,WAAYqhB,EAAU5gB,KACtB6O,GAAIA,EACJmmC,aAAcA,EACdpiC,OAAQA,EACRqN,IAAKA,EACL80B,aAAcle,IAGlBse,GACIE,gBAAiBxe,EAAUvd,QAC3BzK,GAAIA,EACJoR,IAAKA,IAGTA,EAAIgR,KAAKykB,GAEFr1C,GAGXg4B,WAAY,SAASxpB,GACjB,GACIxO,GAAS4f,EAAK+0B,EAAcU,EAD5Bn2C,EAAaykB,EAAQ5N,QAAQvH,EAsBjC,OAnBAoR,GAAM+D,EAAQ2Z,WAAW9uB,GACzBmV,EAAQ+a,yBAAyBlwB,GACjCxO,EAAUi0C,EAA+BzlC,EAAIoR,GAC7C+0B,EAAellC,EAAKqM,YAAYrF,IAAIjI,GAEpC6mC,EAASb,GACLt1C,WAAYA,EACZsP,GAAIA,EACJmmC,aAAcA,EACd/0B,IAAKA,IAGTk1B,GACItmC,GAAIA,EACJoR,IAAKA,IAGTA,EAAIgR,KAAKykB,GAEFr1C,KAIf3L,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGonC,kBACnBnvB,QAASjY,GAAG6B,QAAQipB,UAAW,eAAgB1P,GAC/C0jB,MAAO9+B,GAAG6B,QAAQqgB,YAAa9G,EAAKsM,cAActF,KAAM0c,MAG5D9+B,GAAGqM,SAAShM,KAAM,SAASmM,GACvB,OACIyzB,eAAgB,SAAS9lB,GAGrB,MAFA2kB,GAAMmF,aAAa9pB,GAEfiB,EAAK/F,SAASvJ,QAAQqS,SACf8hC,EAA0B9lC,GAG1B3N,EAAOyzB,eAAe9lB,EAAIna,GAAG4P,KAAKowC,EAAe3/C,MAAM,SCzSlFL,GAAGgkC,YAAY2b,2BAA6B,SAAS9nC,GACjD,YAEA,IAAIwzB,GACApzB,GACI0P,MACI+I,UAAU,EACVD,UAAU,EACV4I,iBAAiB,GAErBlb,SAAU,KACVhY,IAAK,SAAS4B,EAAK1B,KACnB6gB,OAAQ,QAEZ+5B,KACAC,GACI9+B,IAAK,SAASjI,GACV,MAAIna,IAAG6G,WAAWoR,EAAQkG,UACflG,EAAQkG,SAAShE,GAGrBlC,EAAQkG,UAI3Bne,IAAG6B,OAAOoW,EAASJ,GAEnBwzB,EAAYrrC,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGo6B,eAC/B6C,aAAc,mBACdR,YAAaxkB,EAAQ8gB,YAAc,mBAAqB,oCACxDwE,cAAetlB,EAAQiP,QACvBA,OAAQjP,EAAQiP,OAChBQ,cAAew5B,EACf/jB,oCAAoC,EACpCxV,KAAM1P,EAAQ0P,KACdxhB,IAAK8R,EAAQ9R,IACbmlB,WAAY,SAASnR,EAAIoR,EAAKvD,GAC1B,GAAIrc,GAAUs1C,EAAS9mC,SAEhB8mC,GAAS9mC,GAEZ6N,EACArc,EAAQK,QAAQuf,GAGhB5f,EAAQG,QAAQyf,OAK5BvrB,GAAG6B,OAAOxB,MACN6/C,SAAU,SAAS/lC,EAAIoR,EAAKrN,EAAQ0G,GAChC,GAAIjZ,GAAU,GAAI3L,IAAG4L,OAWrB,OATAqM,GAAQ9R,IAAI,0CAA4CgU,GAExD8mC,EAAS9mC,GAAMxO,EAEf0/B,EAAUxN,cAAc1jB,GACnB+jB,WAAWjmB,EAAQiG,OAAO/D,IAAO+D,GACjCmgB,YAAYpmB,EAAQ2M,QAAQzK,IAAOyK,GACnC2X,KAAKhR,GAEH5f,MCtEnB3L,GAAGmhD,YAAc,SAAStpC,GACtB,YAoBA,SAASupC,GAAmB1hC,EAAO2hC,GAE/B,GAAIC,GAAer5C,MAAMvB,UAAUwB,MAAMtB,KAAK8Y,EAE9CzH,GAAQ6O,UAAUy6B,QAAQ,WAAa7hC,EAAM3Z,OAAS,mBACtDs7C,EAAeG,cAAa,GAC5BvpC,EAAQ6O,UAAU26B,+BAA+BH,EAAcD,EAAeK,cAGlF,QAASC,GAAiBxnB,GACtB,GAAIynB,GAAoB,GAAI5hD,IAAG4L,OAwC/B,OAtCIuuB,GAAM5xB,OACN4xB,EAAM3e,KAAK,SAASA,GAChBA,EAAKqmC,OAASC,EAAqB3nB,GACnC4nB,EAAa7+C,KAAKsY,GAClBomC,EAAkB91C,WAEtB,SAASk2C,GACL/pC,EAAQ6O,UAAUy6B,QAAQ,oBAAsBpnB,EAAM8nB,SAAW,sBAAwBD,EAAUjxB,KAAO,IAAK,SAC/G6wB,EAAkB51C,YAGjBmuB,EAAM+nB,aACXC,EAAoBhoB,GAAOrjB,KACvB,SAAwBoD,GACpB,GAAIkoC,GAAcloC,EAAQnU,MAE1B/F,IAAG+C,KAAKmX,EAAS,SAASlX,EAAKm3B,GAC3BwnB,EAAiBxnB,GAAO5iB,KAAK,WACzB6qC,GAAe,EAEK,IAAhBA,GACAR,EAAkB91C,cAKzBoO,EAAQnU,QACT67C,EAAkB91C,WAI1B,SAAqBk2C,GACjB/pC,EAAQ6O,UAAUy6B,QAAQ,oBAAsBpnB,EAAM8nB,SAAW,sBAAwBD,EAAUjxB,KAAO,IAAK,SAC/G6wB,EAAkB51C,YAKvB41C,EAGX,QAASE,GAAqB3nB,GAC1B,GAAIp4B,GAAOo4B,EAAMp4B,KACbkgD,EAAW9nB,EAAM8nB,SACjBI,EAAwBJ,EAASpwC,YAAY9P,EAUjD,OAPAkgD,GAAWA,EAASnwC,OAAO,EAAGuwC,GAGH,MAAvBJ,EAAStyC,OAAO,KAChBsyC,EAAWA,EAASnwC,OAAO,IAGxBmwC,EAIX,QAASE,GAAoBhoB,EAAO6f,EAAQsI,EAAcC,GACtD,GAAI52C,GAAU42C,GAAmB,GAAIviD,IAAG4L,QACpC42C,EAAYxI,GAAU7f,EAAMsoB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqBxoC,GACjB,GAAIyoC,GAAaL,EAAeA,EAAatyC,OAAOkK,GAAWA,CAE3DA,GAAQnU,OACR4jB,WAAW,WACPw4B,EAAoBhoB,EAAOqoB,EAAWG,EAAYh3C,IACnD,GAGHA,EAAQG,QAAQ62C,IAIxBh3C,EAAQK,SAGLL,EAGX,QAASi3C,GAAmBv4C,EAAcg3C,GACtC,GAAIwB,MACAC,EAA4B,GAAI9iD,IAAG4L,OA4CvC,OA1CAqM,GAAQ6O,UAAUi8B,yBAClB1B,EAAeG,cAAa,GAExBn3C,EAAaqV,MAAM3Z,OAAS,IAAMkS,EAAQ+qC,oBAC1C/qC,EAAQ6O,UAAU26B,mCAClBxpC,EAAQ6O,UAAUm8B,UAAU,oBAAqB,IACjD5B,EAAeG,cAAa,GAC5BsB,EAA0B92C,YAG1B+1C,KAEI/hD,GAAGoK,sBAAsBC,GACzBrK,GAAG+C,KAAKsH,EAAaC,MAAO,SAAStH,EAAKsE,GACtC,GAAI6yB,GAAQ7yB,EAAKiD,kBAEb4vB,KAEIA,EAAM5xB,OACNw5C,EAAa7+C,KAAKoE,EAAKs2C,aAIvBiF,EAAsB3/C,KAAKy+C,EAAiBxnB,GAAO5iB,KAAK,WACpDsrC,EAAsBrf,MACe,IAAjCqf,EAAsB98C,QACtB+8C,EAA0Bh3C,gBAQ9Ci2C,EAAe13C,EAAaqV,MAGK,IAAjCmjC,EAAsB98C,QACtB+8C,EAA0Bh3C,WAI3Bg3C,EAGX,QAASI,GAAcC,GACnB,GAAIC,GAAW,GAAIpjD,IAAGqjD,gBAClBC,sBAlKoB,eAmKpBrjD,QAASkjD,EACTI,QAAS,SAASz0C,GACd9O,GAAGmjD,GAAU9gD,SAAS4V,EAAQmS,QAAQo5B,YACtC10C,EAAE20C,mBAENC,sBAAuB,SAAS50C,GAC5B9O,GAAGmjD,GAAU7gD,YAAY2V,EAAQmS,QAAQo5B,aAE7CG,OAAQ,SAAS70C,GACb8zC,EAAmB9zC,EAAEzE,aAAc+4C,GAAUtsC,KACzC,WACIsqC,EAAmBW,EAAcqB,IAErC,WACInrC,EAAQ6O,UAAUy6B,QAAQ,sEAAuE,aAcjH,OARAvoC,GAAezG,YAAY,WACvB6wC,EAAShxC,YAGbpS,GAAGmjD,GAAUr/C,aA1LY,qBA0L4B9D,GAAGmjD,GAAUjjD,OAElE0jD,EAAgB1gD,KAAKkgD,GAEdA,EAGX,QAASS,GAAWC,GAChB,GAAIC,EASJ,OAPA/jD,IAAG+C,KAAK+gD,EAAUz5C,aAAa25C,MAAO,SAASv0C,EAAKxM,GAChD,GAAY,UAARA,EAEA,MADA8gD,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBn1C,GACxB,MAAI9O,IAAG6N,SACIiB,EAAEgtC,EAAI,GAAKhtC,EAAEo1C,EAAI,EAGb,IAARp1C,EAAEgtC,GAAmB,IAARhtC,EAAEo1C,EAG1B,QAASC,KACL,GAAIC,GAAYnsC,EAAQosC,iBAEpBC,EAAqB,WACjB36B,WAAW,WACP3pB,GAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAC7BpjD,GAAGojD,GAAUt/C,aApOJ,qBAoO4C9D,GAAGojD,GAAUljD,OAClEF,GAAGojD,GAAU9gD,YAAY2V,EAAQmS,QAAQo5B,eAE9C,IAGXxjD,IAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAC7B,GAAI/B,GAAiB6B,EAAcE,EAG/BgB,GAAUr+C,QAAU/F,GAAG8S,kBAAkB6C,UACzCqD,EAAe1Y,OAAOqJ,SAAU,YAAa,SAASmF,IAC7CuyC,EAAeG,gBAAkBqC,EAAW/0C,IAC7C9O,GAAG+C,KAAKqhD,EAAW,SAASphD,EAAKogD,GAGzBA,YAAoBmB,cACpBvkD,GAAGojD,GAAUt/C,aArPZ,qBAuPD9D,GAAGojD,GAAU9hD,KAAKlB,QAAS,gBAQnD4Y,EAAe1Y,OAAOqJ,SAAU,YAAa,SAASmF,GAC9Cm1C,EAAmBn1C,IACnBw1C,MAORtrC,EAAe1Y,OAAON,GAAG2J,UAAUvG,WAAW,GAAI,aAAc,SAAS0L,GACrEw1C,MAGJtrC,EAAe1Y,OAAOqJ,SAAU,OAAQ,SAASmF,GACzC+0C,EAAW/0C,KACXA,EAAED,iBACFy1C,OAIRtrC,EAAe1Y,OAAOqJ,SApRE,eAoR+B26C,GArR3D,GAAIrsC,GAGA2rC,KACA7B,KACA/oC,EAAiB,GAAIhZ,IAAGkS,cAE5B+F,IACIosC,oBACArB,oBAAoB,EACpB54B,SACIo5B,WAAY,MAEhB18B,UAAW,GAAI9mB,IAAGmhD,YAAYr6B,WAGlC9mB,GAAG6B,OAAOoW,EAASJ,GAAG,GAwQtBssC,IAEAnkD,GAAG6B,OAAOxB,MACNmkD,mBAAoB,SAASvkD,GACzBgY,EAAQosC,iBAAiBnhD,KAAKjD,GAC9BijD,EAAcjjD,IAGlBwkD,eAAgB,SAASxkD,GACrB,GAAIyQ,GACAg0C,EAAMzsC,EAAQosC,gBAElB,KAAK3zC,IAAKg0C,GACN,GAAIA,EAAIh0C,KAAOzQ,EACX,MAAOykD,GAAIroC,OAAO3L,EAAG,IAKjC0B,QAAS,WACL4G,EAAe5G,UACfpS,GAAG+C,KAAK6gD,EAAiB,SAAS5gD,EAAKogD,GACnCA,EAAShxC,eAKrB/R,KAAKmyC,YACLnyC,KAAKmyC,SAASsP,qBAAuBA,GAGzC9hD,GAAGmhD,YAAYr6B,UAAY,WACvB,YAEA,QACIi8B,uBAAwB,aACxBtB,+BAAgC,SAAS/hC,EAAOilC,KAChD1B,UAAW,SAASlyB,EAAM6zB,GACtB5kD,GAAGmG,IAAI,2BAA6B4qB,EAAO,2BAA6B6zB,EAAiB,IAAK,UAElGrD,QAAS,SAASn7C,EAASC,GACvBrG,GAAGmG,IAAIC,EAASC,MAK5BrG,GAAGqjD,eAAiB,SAASxrC,GACzB,YAiBA,SAASgtC,KACL,MAAO7kD,IAAG6N,UAAa7N,GAAGiO,WAAajO,GAAGkO,UAG9C,QAAS42C,GAAmBh2C,GAEnBi2C,IAGGF,EACA7rC,EAAe1Y,OAAOqJ,SAAU,WAAY,SAASmF,GACjDA,EAAED,mBAGNmK,EAAe1Y,OAAOqJ,SAAU,WAAY,SAASmF,GAC7CA,EAAEzE,eACFyE,EAAEzE,aAAa26C,WAAa,OAC5Bl2C,EAAED,oBAKdk2C,GAAsB,GAI9B,QAASE,GAAgBn2C,GAGrB,IAAK9O,GAAG8S,kBAAkB6C,SACtB,OAAO,CAGX,IAAIuvC,GAAYC,EAAKr2C,EAAEzE,aAEvB+6C,EAAWplD,GAAG6N,QAOd,OADAq3C,MAAallD,GAAGqN,OAAQrN,GAAG8S,kBAAkB6C,WAAuC,SAArBwvC,EAAGE,cAC3DF,GAAMD,IAEAC,EAAGzlC,OAASylC,EAAGzlC,MAAM3Z,SACpBq/C,GAAYD,EAAGnB,MAAMljD,UAAYqkD,EAAGnB,MAAMljD,SAAS,UACpDqkD,EAAGnB,MAAMsB,UAAYH,EAAGnB,MAAMsB,SAAS,UAIxD,QAASC,GAAoBC,GAIzB,MAHmBrhD,UAAfqhD,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiBj8C,SAASk8C,YAAY,SACtCD,EAAeE,UAAU7tC,EAAQqrC,uBAAuB,GAAM,GAJlE,GAAIsC,EAOJ,IAAI1gD,OAAO6gD,YACP,IACIH,EAAiB,GAAIG,aAAY9tC,EAAQqrC,uBAE7C,MAAO1M,GACH+O,QAIJA,IAGJh8C,UAASq8C,cAAcJ,GAG3B,QAASK,KACLjtC,EAAe1Y,OAAOL,EAAS,WAAY,SAAS6O,GAChD,GAAKm2C,EAAgBn2C,GAArB,CAMA,GAAIo3C,GAASlmD,GAAGqN,MAAQrN,GAAG8S,kBAAkB6C,SAAW,KAAO7G,EAAEzE,aAAag7C,aAE1Ev2C,GAAEzE,aAAa26C,WADJ,SAAXkB,GAAgC,aAAXA,EACO,OAEA,OAGhCp3C,EAAE20C,kBACF30C,EAAED,oBAGNmK,EAAe1Y,OAAOL,EAAS,YAAa,SAAS6O,GACjD,IAAKy2C,IAAuB,CACxB,IAAKN,EAAgBn2C,GACjB,MAEJmJ,GAAQsrC,QAAQz0C,MAIxBkK,EAAe1Y,OAAOL,EAAS,YAAa,SAAS6O,GACjD,GAAKm2C,EAAgBn2C,GAArB,CAIAmJ,EAAQkd,QAAQrmB,EAEhB,IAAIq3C,GAAgBx8C,SAASy8C,iBAAiBt3C,EAAEu3C,QAASv3C,EAAEw3C,QAEvDtmD,IAAGK,MAAMS,SAASqlD,IAItBluC,EAAQyrC,sBAAsB50C,MAGlCkK,EAAe1Y,OAAOL,EAAS,OAAQ,SAAS6O,GAC5C,IAAKy2C,IAAuB,CACxB,IAAKN,EAAgBn2C,GACjB,MAGJA,GAAED,iBACFC,EAAE20C,kBACFxrC,EAAQ0rC,OAAO70C,GAEf42C,OArJZ,GACIztC,GAAShY,EAASwlD,EAAaV,EAD/B/rC,EAAiB,GAAIhZ,IAAGkS,cAG5B+F,IACIhY,QAAS,KACTsjD,QAAS,SAASz0C,KAClBqmB,QAAS,SAASrmB,KAElB40C,sBAAuB,SAAS50C,KAChC60C,OAAQ,SAAS70C,MAGrB9O,GAAG6B,OAAOoW,EAASJ,GACnB5X,EAAUgY,EAAQhY,QA6IlB6kD,IACAmB,IAEAjmD,GAAG6B,OAAOxB,MACNmhD,aAAc,SAASgE,GACnB,MAAOD,GAAoBC,IAG/BpzC,QAAS,WACL4G,EAAe5G,WAGnBsvC,WAAY,WACR,MAAOzhD,MAIfI,KAAKmyC,YACLnyC,KAAKmyC,SAASyS,gBAAkBA,GCrfnC,WACG,YAEAjlD,IAAGumD,aACCloC,gBAAiB,SAASC,GACtBje,KAAKmmD,QAAQ9/C,UAAU2X,gBAAgBpO,MAAM5P,KAAM8H,WACnD9H,KAAKomD,YAAYC,iBAGrBpmC,iBAAkB,WACdjgB,KAAKmmD,QAAQ9/C,UAAU4Z,iBAAiBrQ,MAAM5P,KAAM8H,WACpD9H,KAAKomD,YAAYE,cAGrBC,iBAAkB,SAAS3mD,GACvBI,KAAKwmD,MAAQxmD,KAAKwmD,KAAKrC,mBAAmBvkD,IAG9C6mD,oBAAqB,SAAS7mD,GAC1B,GAAII,KAAKwmD,KACL,MAAOxmD,MAAKwmD,KAAKpC,eAAexkD,IAIxC8mD,gBAAiB,SAAS5sC,GACtB,IAAK9Z,KAAKomD,YAAYO,gBAAgB7sC,GAClC,MAAO9Z,MAAKomD,YAAYQ,iBAAiB9sC,IAIjDN,MAAO,WACHxZ,KAAKmmD,QAAQ9/C,UAAUmT,MAAM5J,MAAM5P,KAAM8H,WACzC9H,KAAKomD,YAAY5sC,SAEZxZ,KAAKye,SAAS8E,QAAUvjB,KAAKomD,YAAY1kC,cAC1C1hB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKomD,YAAY1kC,YAC1B7J,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGHnZ,KAAKwmD,OACLxmD,KAAKwmD,KAAKz0C,UACV/R,KAAKwmD,KAAOxmD,KAAK6mD,qBAGrB7mD,KAAK8mD,mBAAqB,EAC1B9mD,KAAK+mD,uBAAyB,EAE9B/mD,KAAKgnD,mCAGTzhC,QAAS,SAASzL,EAAIuC,GAClB,GAAI4qC,GAAoBjnD,KAAKye,SAAS0S,eAAe9U,EAErDrc,MAAKmmD,QAAQ9/C,UAAUkf,QAAQ3V,MAAM5P,KAAM8H,WAC3C9H,KAAKomD,YAAYc,eAAeptC,EAAImtC,IAGxChkC,YAAa,SAASnJ,GAClB,GAAIyuB,GAASvoC,KAAKmmD,QAAQ9/C,UAAU4c,YAAYrT,MAAM5P,KAAM8H,UAG5D,OADAygC,IAAUvoC,KAAKomD,YAAYe,aAAartC,GACjCyuB,GAGXroB,eAAgB,SAASpG,GACrB,GAAIstC,GAAYpnD,KAAKmmD,QAAQ9/C,UAAU6Z,eAAetQ,MAAM5P,KAAM8H,UAGlE,OADAs/C,IAAapnD,KAAKomD,YAAYiB,gBAAgBvtC,GACvCstC,GAGXE,MAAO,SAASC,GACZ,MAAOvnD,MAAKomD,YAAYoB,UAAUD,IAGtCE,cAAe,SAAS9mC,GAGpB,MAFW3gB,MAAKqhB,QAAQV,GAEZ+mC,eAOpB/nD,GAAGgoD,cACChmC,WAAY,SAAShK,GACjB,GAAI4L,GAASvjB,KAAKmmD,QAAQ9/C,UAAUsb,WAAW/R,MAAM5P,KAAM8H,UAQ3D,OANKyb,IACG5L,IAAa3X,KAAK6tB,mBAClBtK,EAASvjB,KAAKomD,YAAY1kC,aAI3B6B,GAGXqkC,gBAAiB,SAASjnC,GACtB3gB,KAAKomD,YAAYyB,WAAWlnC,IAGhCqmC,gCAAiC,WAC7BhnD,KAAK8nD,yBAA2BnoD,GAAGooD,yBAA2B/nD,KAAKgoD,6BAInEhoD,KAAKioD,wBAA0BtoD,GAAGiO,UAE9B5N,KAAKkoD,2BAELloD,KAAKmoD,sBAAwBnoD,KAAKooD,0BAClCpoD,KAAKqoD,6BAA+BroD,KAAKsoD,iCACzCtoD,KAAKuoD,2BAA6BvoD,KAAKwoD,iCAI/C3B,kBAAmB,WACf,GAAI/uC,GAAO9X,KACPgkD,EAAmBhkD,KAAKye,SAASgqC,YAAYC,eAC7CC,EAAa3oD,KAAKomD,YAClBwC,EAAkBD,EAAWE,aAIjC,OAFAD,IAAmB5E,EAAiBnhD,KAAK+lD,GAElC,GAAIjpD,IAAGmhD,aACVkD,iBAAkBA,EAClBrB,mBAAoB3iD,KAAKye,SAASjV,SAClCugB,SACIo5B,WAAYnjD,KAAKye,SAASsL,QAAQo5B,YAEtC18B,WACIi8B,uBAAwB,WACpBiG,EAAWG,sBAEf1H,+BAAgC,SAAS/hC,EAAOilC,GAC5CqE,EAAWI,qBAEXppD,GAAG+C,KAAK2c,EAAO,SAAS1c,EAAKwY,GACzBA,EAAKusC,aAAepD,IAGpBjlC,EAAM3Z,QACNoS,EAAKiG,SAASsB,EAAO,KAAM,OAGnCujC,UAAW,SAASlyB,EAAMs4B,GACtBlxC,EAAK+N,WAAW6K,EAAMs4B,IAE1B9H,QAAS,SAASn7C,EAASC,GACvB8R,EAAKhS,IAAIC,EAASC,QAMlCgiD,2BAA4B,WACxB,GAAIlwC,GAAO9X,IAEX,OAAO,IAAIL,IAAGooD,yBACVY,WAAY3oD,KAAKomD,YAEjBtgD,IAAK,SAASC,EAASkjD,GACnBnxC,EAAKhS,IAAIC,EAASkjD,IAGtBC,aAAc,SAASvoC,GACnB7I,EAAKuI,WAAWM,IAGpByK,SAAU,SAASzK,GACf7I,EAAK2H,OAAOkB,IAGhBwoC,QAAS,SAASxoC,GACd7I,EAAKmM,MAAMtD,IAGfyoC,QAAS,SAASzoC,GACd7I,EAAKmL,YAAYtC,IAGrB0oC,WAAY,SAAS1oC,GACjB7I,EAAKoI,eAAeS,IAGxB2oC,UAAW,SAAS3oC,GAChB,MAAO7I,GAAK8H,QAAQe,OAKhCunC,uBAAwB,WAEpB,MAAOloD,MAAKomD,YAAYmD,2BAChBvpD,KAAKye,SAASuR,YACfrwB,GAAG6pD,sBACH7pD,GAAG8pD,2BACH9pD,GAAG8pD,2BAGdC,qBAAsB,WAClB,GAAI5xC,GAAO9X,KACP2oD,EAAa3oD,KAAKomD,WAEtB,QACIuC,WAAYA,EACZ7iD,IAAK,SAASC,EAASkjD,GACnBnxC,EAAKhS,IAAIC,EAASkjD,IAEtBU,kBAAmB,SAAShpC,GACxB,MAAO7I,GAAKsK,YAAYtI,GAAI6G,IAASvG,QAEzCkvC,UAAW,SAAS3oC,GAChB,MAAO7I,GAAK8H,QAAQe,IAExBipC,UAAW,SAAS9vC,EAAIuC,GACpBvE,EAAKyN,QAAQzL,EAAIuC,IAErBwtC,sBAAuB,SAAS/vC,EAAIgwC,GAChC,GAAIC,GAAUpqD,GAAGgpD,EAAWqB,aAAalwC,IACrCmwC,EAAkBtqD,GAAGgpD,EAAW/B,iBAAiB9sC,GAEjDgwC,IACAC,EAAQ/nD,SAAS,cACjB2mD,EAAWuB,aAAapwC,GACxB6uC,EAAWwB,aAAarwC,KAGxBiwC,EAAQ9nD,YAAY,cACpB0mD,EAAWyB,aAAatwC,GACxB6uC,EAAW0B,aAAavwC,IAI5BmwC,EAAgBjoD,SAAS,WAAWC,YAAY,cAK5DmnB,sBAAuB,SAAStP,EAAIgC,EAAWD,GAC3C7b,KAAKmmD,QAAQ9/C,UAAU+iB,sBAAsBxZ,MAAM5P,KAAM8H,WAErD9H,KAAKkoD,0BAEDloD,KAAKomD,YAAYQ,iBAAiB9sC,IAAO+B,IAAclc,GAAGya,OAAOyC,YACjE7c,KAAKomD,YAAYkE,qBAAqBxwC,GACtC9Z,KAAKomD,YAAY+D,aAAarwC,IAIlCgC,IAAcnc,GAAGya,OAAOgD,iBAAmBvB,IAAclc,GAAGya,OAAO8C,WACnEld,KAAKomD,YAAYmE,UAAUzwC,GAC3B9Z,KAAKomD,YAAYoE,cAAc1wC,GAC/Bna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK7X,YAAYjC,KAAKyqD,SAASC,WAE/D7uC,IAAclc,GAAGya,OAAOkD,eAC7Btd,KAAKomD,YAAYuE,UAAU7wC,IAInCwuC,+BAAgC,WAC5B,GAAIvtC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAGirD,4BAA4B7vC,IAG9CytC,6BAA8B,WAC1B,GAAIztC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAG8pD,0BAA0B1uC,IAG5CqtC,wBAAyB,WACrB,GAAIrtC,GAAOpb,GAAG6B,UAAWxB,KAAK0pD,uBAE9B,OAAO,IAAI/pD,IAAG6pD,qBAAqBzuC,IAGvC0Y,eAAgB,SAAS3Z,GACrB9Z,KAAKmmD,QAAQ9/C,UAAUotB,eAAe7jB,MAAM5P,KAAM8H,WAClD9H,KAAKomD,YAAYyE,YAAY/wC,IAGjC2X,eAAgB,SAASe,EAAYC,GACjCzyB,KAAKmmD,QAAQ9/C,UAAUorB,eAAe7hB,MAAM5P,KAAM8H,WAClD9H,KAAKomD,YAAY0E,sBAGrBz3B,UAAW,SAASvZ,EAAIpY,GACpB,GAAIyZ,GAAOnb,KAAKqhB,QAAQvH,EAEpBqB,IAAQA,EAAKqmC,QAAUxhD,KAAKye,SAASgqC,YAAYsC,sBACjD/qD,KAAKwjB,aAAa0F,YAAYpP,GAC1BkxC,OAAQ7vC,EAAKqmC,SAIrBxhD,KAAKmmD,QAAQ9/C,UAAUgtB,UAAUzjB,MAAM5P,KAAM8H,WAC7C9H,KAAKirD,WAAWnxC,EAAIpY,IAIxB6xB,aAAc,SAASzZ,GAEf9Z,KAAKkoD,2BACLloD,KAAKomD,YAAYkE,qBAAqBxwC,GACtC9Z,KAAKomD,YAAYiE,aAAavwC,GAGzB9Z,KAAKioD,wBACNjoD,KAAKuoD,2BAA2B2C,WAAWlrD,KAAKomD,YAAY4D,aAAalwC,MAMrFkR,YAAa,SAASlR,EAAIpY,EAAMopB,EAAQC,GACpC/qB,KAAKmmD,QAAQ9/C,UAAU2kB,YAAYpb,MAAM5P,KAAM8H,WAE/C9H,KAAKomD,YAAY+E,eAAerxC,EAAIgR,EAAQC,GAE9B,IAAVA,GAAoD,MAArCzpB,KAAKC,MAAMupB,EAASC,EAAQ,MAC3C/qB,KAAKomD,YAAYgF,WAAWtxC,GAC5B9Z,KAAKomD,YAAYuE,UAAU7wC,GAC3B9Z,KAAKomD,YAAYiF,aAAavxC,GAC9B9Z,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAASpb,KAAKioD,oBAGtDtrD,KAAKurD,iBAAiBzxC,IAItB9Z,KAAKurD,iBAAiBzxC,EAAIgR,EAAQC,IAI1CiJ,iBAAkB,SAASlJ,EAAQC,GAC/B/qB,KAAKmmD,QAAQ9/C,UAAU2tB,iBAAiBpkB,MAAM5P,KAAM8H,WACpD9H,KAAKomD,YAAYvJ,oBAAoB/xB,EAAQC,IAGjDI,YAAa,SAASrR,EAAIpY,EAAMY,EAAQ4oB,GAMpC,QAASsgC,GAAelpD,GAGfid,IAILopC,EAAW6B,cAAc1wC,GAEzBna,GAAG4f,GAAetd,YAAY6V,EAAK2yC,SAASC,UAC5C/B,EAAW0C,aAAavxC,GAEpBhC,EAAKsK,YAAYtI,GAAIA,IAAKM,SAAWza,GAAGya,OAAOkD,eAC/CqrC,EAAWyC,WAAWtxC,GAE1B6uC,EAAWkC,YAAY/wC,GAEnBxX,EAAOmJ,QACPqM,EAAK2zC,sBAAsB3xC,IAG3Bna,GAAG4f,GAAevd,SAAS8V,EAAK2yC,SAASiB,MACzC/C,EAAWgD,WAAW7xC,GAElB6uC,EAAWiD,oBAAsB9zC,EAAKuL,gBAAgBvJ,KACtDna,GAAG4f,GAAevd,SAAS8V,EAAK2yC,SAAS/N,WACzCiM,EAAWkD,UAAU/xC,IAEzBhC,EAAKg0C,2BAA2BhyC,EAAIxX,KAjC5C,GAAIypD,GAAe/rD,KAAKmmD,QAAQ9/C,UAAU8kB,YAAYvb,MAAM5P,KAAM8H,WAC9D6gD,EAAa3oD,KAAKomD,YAClB7mC,EAAgBopC,EAAW/B,iBAAiB9sC,GAC5ChC,EAAO9X,IA6CX,OAVI+rD,aAAwBpsD,IAAG4L,QAC3BwgD,EAAa70C,KAAK,SAAS80C,GACvBR,EAAeQ,KAKnBR,EAAelpD,GAGZypD,GAGXN,sBAAuB,SAAS3xC,GAC5B,GAAI6uC,GAAa3oD,KAAKomD,WAElBpmD,MAAKmwB,qBACLw4B,EAAWsD,iBAAiBnyC,GAGhCna,GAAGgpD,EAAW/B,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAASh/C,SAE3DzL,KAAKksD,sBAAsBpyC,IAG/B0R,cAAe,SAAS1R,GACpB9Z,KAAKmmD,QAAQ9/C,UAAUmlB,cAAc5b,MAAM5P,KAAM8H,WACjD9H,KAAKomD,YAAY+F,YAAYryC,IAGjC4R,UAAW,SAAS5R,EAAIpY,GACpB,GAAIqqD,GAAe/rD,KAAKmmD,QAAQ9/C,UAAUqlB,UAAU9b,MAAM5P,KAAM8H,UAIhE,OAFA9H,MAAKomD,YAAY+F,YAAYryC,GAEtBiyC,GAGXjgC,eAAgB,SAAShS,EAAI+R,GACzB7rB,KAAKmmD,QAAQ9/C,UAAUylB,eAAelc,MAAM5P,KAAM8H,WAI9C+jB,EAAUG,UAAY,GAAKhsB,KAAK6f,SAASiD,YAAYhJ,IACrD9Z,KAAKomD,YAAYgG,WAAWtyC,IAIpCwR,UAAW,SAASxR,EAAIpY,GACpB1B,KAAKmmD,QAAQ9/C,UAAUilB,UAAU1b,MAAM5P,KAAM8H,WAC7C9H,KAAK4nD,gBAAgB9tC,GAEU,IAA3B9Z,KAAKkuB,mBACLluB,KAAKomD,YAAY0E,sBAIzBh4B,mBAAoB,SAAShZ,GACzB,GAAIuyC,GAAoBC,EAASC,CAEjCvsD,MAAKmmD,QAAQ9/C,UAAUysB,mBAAmBljB,MAAM5P,KAAM8H,WAEtD9H,KAAKwsD,gBAAgB1yC,GAEjB9Z,KAAKye,SAASwF,MAAMwoC,oBACpBJ,EAAqBrsD,KAAKmjB,aAAarJ,GACvCwyC,EAAUtsD,KAAKye,SAASwF,MAAMqR,gBAE9Bi3B,EAAYvsD,KAAKye,SAASwF,MAAMyoC,cAAcxqD,QAAQ,gBAAiBmqD,GACvEE,EAAYA,EAAUrqD,QAAQ,eAAgBoqD,GAE9CtsD,KAAKomD,YAAYoE,cAAc1wC,EAAIyyC,GACnC5sD,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAASC,YAKzEn5B,qBAAsB,SAASzX,GAC3B,MAAI9Z,MAAKmmD,QAAQ9/C,UAAUkrB,qBAAqB3hB,MAAM5P,KAAM8H,YACxD9H,KAAKomD,YAAYuG,cAAc7yC,GAC/Bna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK7X,YAAYjC,KAAKyqD,SAASiB,MACpE1rD,KAAKomD,YAAYoE,cAAc1wC,GAC/B9Z,KAAKomD,YAAY+F,YAAYryC,GAC7B9Z,KAAKwsD,gBAAgB1yC,IACd,IAGPna,GAAGK,KAAKomD,YAAYQ,iBAAiB9sC,IAAK9X,SAAShC,KAAKyqD,SAAS/N,WACjE18C,KAAKomD,YAAYyF,UAAU/xC,IACpB,IAIfwG,gBAAiB,SAASxG,GACtB,GAAI4Z,GAAoB/zB,GAAG4P,KAAKvP,KAAK4sD,uBAAwB5sD,KAE7DA,MAAKmmD,QAAQ9/C,UAAUia,gBAAgB/Z,KAAKvG,KAAM8Z,EAAI4Z,IAG1Dk5B,uBAAwB,SAAS9yC,EAAIG,EAAM0Z,GACnC3zB,KAAKye,SAAS4B,WAAWwsC,aACzB7sD,KAAK8sD,mBAAmBl9C,MAAM5P,KAAM8H,WAGpC9H,KAAK+sD,mBAAmBn9C,MAAM5P,KAAM8H,YAI5C4d,kBAAmB,SAAS5L,EAAIoR,EAAKvD,GACjC3nB,KAAKmmD,QAAQ9/C,UAAUqf,kBAAkB9V,MAAM5P,KAAM8H,WAErD9H,KAAKomD,YAAYyE,YAAY/wC,GAEzB6N,GACA3nB,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAAS4B,WAAW2sC,oBAC5DhtD,KAAKomD,YAAY6F,iBAAiBnyC,IAGlC9Z,KAAK4nD,gBAAgB9tC,IAI7BizC,mBAAoB,SAASjzC,EAAIG,EAAM0Z,GACnC3zB,KAAKomD,YAAY6G,iBAAiBnzC,GAClC9Z,KAAKomD,YAAY+F,YAAYryC,GAC7B9Z,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAAS4B,WAAW6sC,oBAC5DltD,KAAK8zB,eAAeC,WAAWnkB,MAAM5P,KAAM8H,YAG/CglD,mBAAoB,SAAShzC,EAAIG,EAAMmhB,GAEnC,GAKIlsB,GALA0C,EAAW5R,KAAK4f,QAAQ9F,GACxBqzC,EAAiBntD,KAAKye,SAAS4B,WAAW8sC,eAAejrD,QAAQ,gBAAiB0P,GAElFw7C,GADOptD,KAAK6iB,QAAQ/I,GACAhS,WACpBgQ,EAAO9X,IAGXkP,GAASlP,KAAKye,SAAS4uC,YAAYF,GAE/BxtD,GAAG4W,iBAAiBrH,GACpBA,EAAOuH,KAAK,WACRqB,EAAKi1C,mBAAmBn9C,MAAMkI,EAAMs1C,KAGnCl+C,KAAW,GAChB4I,EAAKi1C,mBAAmBn9C,MAAMkI,EAAMs1C,IAI5CnC,WAAY,SAASnxC,EAAIpY,EAAM4rD,GAC3B,GAAIC,GAGA5xC,EAFA6xC,EAAe,EACfC,EAAcztD,KAAK6f,SAAS+kB,UAAU9qB,IAAO9Z,KAAKye,SAAS1I,QAAQ23C,UAGnE1tD,MAAKye,SAAS1e,QAAQ4tD,eAClB3tD,KAAK8mD,mBAAqB,GAAK9mD,KAAK+mD,uBAAyB,IAC7DyG,EAAextD,KAAK+mD,uBAAyB,GAGjDwG,GACIhzC,MAAOizC,IAIVF,IACGttD,KAAKye,SAAS+X,8BAAgC72B,GAAG8S,kBAAkBoC,eACnE7U,KAAKomD,YAAYwH,gBAMhB5tD,KAAKye,SAASjV,WACfmS,EAAS3b,KAAKoiB,YAAYtI,GAAIA,IAE9B9Z,KAAK6tD,mBAAqB7tD,KAAK6tD,oBAAsBlyC,EAAON,aAExDM,EAAON,eAAiBrb,KAAK6tD,oBAAuBlyC,EAAON,eAC3Drb,KAAK6f,SAASC,YACd9f,KAAK8tD,aACL9tD,KAAK6tD,mBAAqB,QAKlCP,GACAttD,KAAKomD,YAAY2H,eAAej0C,EAAI9Z,KAAKye,SAAS0S,eAAezvB,GAAO6rD,EAAaE,GACrFztD,KAAKomD,YAAY4H,gBAAgBl0C,EAAI9Z,KAAKmhB,eAAerH,IAAK,EAAM9Z,KAAKye,SAASwvC,WAAW/0B,iBAG7Fl5B,KAAKomD,YAAYtrC,QAAQhB,EAAI9Z,KAAKye,SAAS0S,eAAezvB,GAAO6rD,EAAaE,GAC9EztD,KAAKomD,YAAY8H,gBAAgBp0C,EAAI9Z,KAAKqhB,QAAQvH,GAAK9Z,KAAKye,SAASwvC,WAAW/0B,gBAGpFl5B,KAAK+mD,wBAA0B,GAE3BuG,GACCttD,KAAKye,SAAS1e,QAAQouD,kBAAoBxuD,GAAG8S,kBAAkBoC,gBAEhE7U,KAAKurD,iBAAiBzxC,IAI9Bg0C,WAAY,WACR9tD,KAAKomD,YAAYE,aACjBtmD,KAAKigB,oBAGTsrC,iBAAkB,SAASzxC,EAAIs0C,EAAY/R,GACvC,GAAInhC,GAAOlb,KAAKsiB,QAAQxI,GACpBu0C,EAAiBruD,KAAKktB,YAAYhS,EAElCA,IAAQ,IACWpX,SAAfsqD,GAA0CtqD,SAAdu4C,IAC5BgS,EAAiBruD,KAAKsuD,gBAAgBF,EAAY/R,IAGtDr8C,KAAKomD,YAAY9pC,WAAWxC,EAAIu0C,KAIxCC,gBAAiB,SAASC,EAAclS,GAEpC,QAASvvC,GAAEpL,EAAMkvB,GAAe7qB,EAAUA,EAAQ7D,QAAQR,EAAMkvB,GADhE,GAAI7qB,GAAU/F,KAAKye,SAASpb,KAAKmrD,cAKjC,OAFA1hD,GAAE,YAAaxL,KAAKC,MAAMgtD,EAAelS,EAAY,MACrDvvC,EAAE,eAAgB9M,KAAKktB,YAAYmvB,IAC5Bt2C,GAGX+lD,2BAA4B,SAAShyC,EAAIgY,GACrC,GAAI28B,GAAMC,EAAkBC,CAE5BF,GAAOzuD,KAAKye,SAASmwC,wBAAwBH,KAC7CC,EAAmB1uD,KAAKye,SAASmwC,wBAAwBF,iBAE5C,WAATD,GACAE,EAAgB78B,EAAS48B,GACpBC,IACDA,EAAgB3uD,KAAKye,SAASpb,KAAKwrD,YAGvC7uD,KAAKomD,YAAYoE,cAAc1wC,EAAI60C,GAE/B3uD,KAAKye,SAASmwC,wBAAwBE,eACtC9uD,KAAK+uD,aAAaj1C,EAAI60C,IAGZ,YAATF,EACLzuD,KAAKomD,YAAYoE,cAAc1wC,EAAI9Z,KAAKye,SAASpb,KAAKwrD,YAExC,SAATJ,GACLzuD,KAAK8F,IAAI,0CAA4C2oD,EAAO,iBAAkB,SAItFM,aAAc,SAASj1C,EAAIzW,GACvBrD,KAAKomD,YAAYQ,iBAAiB9sC,GAAIjC,MAAQxU,GAGlDmpD,gBAAiB,SAAS1yC,GACjB9Z,KAAKye,SAAS+X,8BAA+B72B,GAAG8S,kBAAkBoC,eACnE7U,KAAKomD,YAAYuF,WAAW7xC,IAIpC+L,WAAY,SAAS6K,EAAMhvB,EAAMuF,GAC7B,GAAIlB,GAAU/F,KAAKmmD,QAAQ9/C,UAAUwf,WAAWjW,MAAM5P,KAAM8H,UAC5D9H,MAAKye,SAASuwC,YAAYjpD,IAG9BygB,YAAa,SAASzgB,GAClB/F,KAAKmmD,QAAQ9/C,UAAUmgB,YAAY5W,MAAM5P,KAAM8H,WAC/C9H,KAAKye,SAASuwC,YAAYjpD,IAG9BkpD,kBAAmB,WACf,GAAIn3C,GAAO9X,IAEXA,MAAKye,SAASgI,UAAUyB,gBAAkB,WACtC,GAAIniB,GAAU+R,EAAK2G,SAASsJ,MAAMmnC,kBAC9BC,EAAar3C,EAAK2G,SAASsJ,MAAMpJ,WAErC,OAAO7G,GAAK2G,SAAS2wC,WAAWrpD,EAASopD,KAIjDliC,oBAAqB,SAASnT,EAAIpY,GAC9B1B,KAAK8mD,oBAAsB,EAC3B9mD,KAAKmmD,QAAQ9/C,UAAU4mB,oBAAoBrd,MAAM5P,KAAM8H,YAG3D0X,uBAAwB,SAASvV,EAAO4T,EAAQC,GAC5C9d,KAAK8mD,mBAAqB78C,EAAMvE,OAChC1F,KAAK+mD,uBAAyB,EAC9B/mD,KAAKmmD,QAAQ9/C,UAAUmZ,uBAAuB5P,MAAM5P,KAAM8H,YAG9DokD,sBAAuB,SAASvrC,GAC5B,GAAIwF,GAAenmB,KAAKmhB,eAAeR,EACtB3gB,MAAKoiB,YAAYtI,GAAI6G,IAASvG,SAE5Bza,GAAGya,OAAOqD,UACxB0I,IACDnmB,KAAKye,SAASwvC,WAAWoB,aAAaC,mBACrC3vD,GAAG8S,kBAAkBgD,eAItBzV,KAAKomD,YAAY4H,gBAAgBrtC,EAAQwF,EAAcnmB,KAAKye,SAASwvC,WAAW/0B,gBAIxF/a,eAAgB,SAAS6H,GACrB,GAAIlM,GAAK9Z,KAAKmmD,QAAQ9/C,UAAU8X,eAAevO,MAAM5P,KAAM8H,UAO3D,OALA9H,MAAKirD,WAAWnxC,EAAI9Z,KAAK4f,QAAQ9F,IAAK,GACtC9Z,KAAKomD,YAAYyE,YAAY/wC,GAC7B9Z,KAAKomD,YAAYgF,WAAWtxC,GAC5B9Z,KAAKyrD,sBAAsB3xC,GAEpBA,GAGX4S,SAAU,SAAS5S,EAAIyC,GACnBvc,KAAKmmD,QAAQ9/C,UAAUqmB,SAAS9c,MAAM5P,KAAM8H,WAE5C9H,KAAKomD,YAAY9pC,WAAWxC,EAAI9Z,KAAKktB,YAAY3Q,KAGrD4Y,wBAAyB,WACrBn1B,KAAKomD,YAAYC,gBACjBrmD,KAAKmmD,QAAQ9/C,UAAU8uB,wBAAwBvlB,MAAM5P,KAAM8H,gBC7sBvEnI,GAAG4vD,aAAe,SAAS/3C,EAAGiT,GAC1B,YAEA,IAAI3S,GAAO9X,IAKXA,MAAKmmD,QAAU17B,EAAY9qB,GAAG8qB,GAAW8L,kBAAoB52B,GAAG42B,kBAChEv2B,KAAKmmD,QAAQv2C,MAAM5P,KAAM8H,WAGzBnI,GAAG6B,OAAOxB,KAAKye,UACX7e,QAAS,KAET2jB,OAAQ,KAERisC,YAAa,KAEb/G,aACIC,kBACAqC,sBAAsB,GAG1B1nD,MACImrD,eAAgB,6BAChBK,WAAY,gBACZvD,mBAAoB,gBACpB/iB,OAAQ,UAGZknB,SAAU,cAEV1lC,SACI2gC,SAAU,qBACVhO,UAAW,sBACXjxC,QAAS,oBACTigD,KAAM,iBACNgE,SAAU,cACV7vD,KAAM,UACNsjD,WAAY,8BAGhByL,yBACIH,KAAM,UACNC,iBAAkB,QAClBI,eAAe,GAGnB/9B,UACI4+B,kBAAmB,6BACnBC,mBAAoB,kFAGxB3rC,OACIwoC,mBAAmB,EACnBC,cAAe,oCAGnBrsC,YACIwsC,cAAc,EACdM,eAAgB,8CAChBD,mBAAoB,cACpBF,mBAAoB,iBAIxBjtD,SACIouD,kBAAkB,EAClBR,cAAc,GAGlB5lC,OACI8nC,eAAe,EACfX,kBAAmB,0BAGvBjB,YACI/0B,cAAe,KACf42B,SAAU,EACVT,cACIC,mBAAmB,EACnBS,iBAAkB,KAClBC,YAAa,MAEjBC,kBAAmB,KAGvBl6C,SACI23C,YAAY,GAGhBsB,YAAa,SAASjpD,GAClB,GAAI+R,EAAKsuC,YAAY8J,UAAU,SAC3B,MAAOp4C,GAAKsuC,YAAY+J,WAAW,QAASpqD,EAG5CujB,YAAW,WACPzkB,OAAO8sB,MAAM5rB,IACd,IAIXsnD,YAAa,SAAStnD,GAClB,MAAI+R,GAAKsuC,YAAY8J,UAAU,WACpBp4C,EAAKsuC,YAAY+J,WAAW,UAAWpqD,GAGvClB,OAAOurD,QAAQrqD,IAI9BqpD,WAAY,SAASrpD,EAASsqD,GAC1B,MAAIv4C,GAAKsuC,YAAY8J,UAAU,UACpBp4C,EAAKsuC,YAAY+J,WAAW,SAAUpqD,EAASsqD,GAG/CxrD,OAAOyrD,OAAOvqD,EAASsqD,MAGvC,GAGH1wD,GAAG6B,OAAOxB,KAAKye,SAAUjH,GAAG,GAE5BxX,KAAKomD,YAAc,GAAIzmD,IAAG4wD,YACtBzqD,IAAKnG,GAAG4P,KAAKvP,KAAK8F,IAAK9F,MACvBwwD,eAAgBxwD,KAAKye,SAASgxC,SAC9BgB,YAAazwD,KAAKye,SAAS7e,QAC3B8wD,gBAAiB1wD,KAAKye,SAAS+wC,YAC/BjsC,OAAQvjB,KAAKye,SAAS8E,OACtB81B,eAAgBr5C,KAAKkhB,gBACrB6I,SACIlqB,KAAMG,KAAKye,SAASsL,QAAQlqB,KAC5B6vD,SAAU1vD,KAAKye,SAASsL,QAAQ2lC,UAEpCra,QACIsb,UAAW3wD,KAAKye,SAASwvC,WAAW6B,SACpCG,kBAAmBjwD,KAAKye,SAASwvC,WAAWgC,mBAEhDZ,cACIuB,gBAAiB5wD,KAAKye,SAASwvC,WAAWoB,aAAaC,kBACvDuB,sBAAuB7wD,KAAKye,SAASwvC,WAAWoB,aAAaU;6EAC7De,oBAAqB9wD,KAAKye,SAASwvC,WAAWoB,aAAaW,aAE/D3sD,KAAMrD,KAAKye,SAASpb,OAGpBrD,KAAKye,SAASgL,YAAYiI,mBAAqB/xB,GAAGyO,UAAYzO,GAAG2O,YACjEtO,KAAKomD,YAAY2K,cAAc/wD,KAAKye,SAASsS,SAASa,+BAEhDjyB,GAAG8S,kBAAkByD,WAAclW,KAAKye,SAAS6I,KAAK8I,WAAazwB,GAAG8S,kBAAkB0D,WAC9FnW,KAAKomD,YAAY2K,cAAc/wD,KAAKye,SAASsS,SAAS6+B,qBAGtD5vD,KAAKi2B,iBAELj2B,KAAKomD,YAAYlX,SAEjBlvC,KAAKyqD,SAAWzqD,KAAKye,SAASsL,SAEzB/pB,KAAKye,SAAS8E,QAAUvjB,KAAKomD,YAAY1kC,cAC1C1hB,KAAK6tB,iBAAmB7tB,KAAKupB,qBACzB3pB,QAASI,KAAKomD,YAAY1kC,YAC1B7J,MAAO7X,KAAKye,SAASpb,KAAKgnB,iBAC3BlR,eAGPnZ,KAAKgnD,kCAEDrnD,GAAGmhD,aAAenhD,GAAG8S,kBAAkB6C,WACvCtV,KAAKwmD,KAAOxmD,KAAK6mD,qBAGjB7mD,KAAKye,SAASsJ,MAAMD,eAAiB9nB,KAAKye,SAASsJ,MAAM8nC,gBACrDlwD,GAAGkoB,aACH7nB,KAAKivD,oBAGLjvD,KAAK8F,IAAI,kCAAmC,UAIpD9F,KAAK8mD,mBAAqB,EAC1B9mD,KAAK+mD,uBAAyB,IAKtCpnD,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAG+d,eACxC/d,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGomB,gBAGxCpmB,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGumD,aACxCvmD,GAAG6B,OAAO7B,GAAG4vD,aAAalpD,UAAW1G,GAAGgoD,cC5LxChoD,GAAG4wD,WAAa,SAASx1C,GACrB,YAEA,IA4EIjV,GACAkrD,EACAC,EACAC,EACA5vC,EACAgO,EACA6hC,EACAC,EA1EAC,GACIC,QAAShoD,SAASioD,yBAClBC,QAEJC,GAAmB,EACnBC,EAAsB,EACtBC,GAA+B,EAC/BC,KACAC,GAAmB,EACnBj6C,GACI9R,IAAK,KACLuvC,QACIsb,UAAW,EACXV,kBAAmB,KAEvBO,eAAgB,cAChBC,YAAa,KACbC,gBAAiB,KACjBntC,OAAQ,KACR81B,eAAgB,KAChBtvB,SACIlqB,KAAM,UACN6vD,SAAU,eAEdL,cACIuB,iBAAiB,EACjBC,sBAAuB,KACvBC,oBAAqB,MAEzBztD,MACIklC,OAAQ,WAGhBupB,GACIvuC,OAAQ,4BACRwuC,YAAa,2BACbC,mBAAoB,4BACpBC,cAAe,6BACfC,cAAe,6BACfC,eAAgB,wBAChBC,aAAc,4BACdC,SAAU,uBACVC,KAAM,+BACNC,KAAM,0BACNC,qBAAsB,qCACtB38C,YAAa,2BACb48C,0BAA2B,2CAC3BC,iBAAkB,iCAClBv3C,KAAM,0BACNw3C,QAAS,6BACTz3C,KAAM,0BACNuE,OAAQ,4BACR7J,MAAO,2BACPg9C,eAAgB,8BAChBC,aAAc,4BACd5uC,MAAO,2BACP6uC,WAAY,iCACZC,kBAAmB,4BACnBC,aAAc,iCACdC,SAAU,oCACVC,eAAgB,8BAChBC,sBAAuB,sCACvBC,UAAW,yBAEfC,KACAC,EAAiC,GAAI3zD,IAAG4L,QACxCgoD,EAA+B,GAAI5zD,IAAG4L,QAatCioD,EAA6B,WACzB,GAAIC,GAAmB77C,EAAQy3C,aAAawB,sBACxC6C,EAAa97C,EAAQy3C,aAAayB,oBAClC/1C,GACI8F,QAASgxC,EACTzwC,MAAOgwC,EAGXD,KACIsC,EACA77C,EAAQyhC,eAAe93B,SAASkyC,EAAiB,GAAI9kB,OAAS5zB,GAAMtE,KAChE,SAASk9C,GACLL,EAA+B7nD,QAAQkoD,IAE3C,WACIL,EAA+B3nD,UAC/B7F,EAAI,wDAA0D2tD,EAAiB,WAKvFH,EAA+B3nD,UAG/B+nD,EACA97C,EAAQyhC,eAAe93B,SAASmyC,EAAY,GAAI/kB,OAAS5zB,GAAMtE,KAC3D,SAASk9C,GACLJ,EAA6B9nD,QAAQkoD,IAEzC,WACIJ,EAA6B5nD,UAC7B7F,EAAI,gEAAkE4tD,EAAY,WAK1FH,EAA6B5nD,YAOzCioD,EAAoB,SAASR,GACzB,GAAIS,GAAsB,GAAIl0D,IAAG4L,OAwBjC,OAtBAgoD,GAA6B98C,KAAK,SAASy0B,GACvC4oB,EAA4B5oB,EAAKkoB,GAE5BA,EAAUrkB,IASX8kB,EAAoBpoD,WARpB2nD,EAAUrkB,IAAM7D,EAAI6D,IACpBqkB,EAAU5nD,OAAS,WACf4nD,EAAU5nD,OAAS,KACnBuoD,EAAKX,GACLS,EAAoBpoD,aAM7B,WAIC5L,EAAKuzD,GACLS,EAAoBpoD,YAGjBooD,GAGXG,EAAqB,SAASl6C,EAAI7O,EAAM8P,GACpC,GAAIq4C,GAAYa,EAAan6C,EAK7B,OAHAhU,GAAI,gCAAkCgU,GACtC7O,EAAKipD,cAAgBp6C,EAEdlC,EAAQyhC,eAAe93B,SAAStW,EAAMmoD,EAAWr4C,GAAMtE,KAC1D,WACIi7C,IACAqC,EAAKX,GACLC,EAAkBv5C,GAAIrO,WAE1B,WACI4nD,EAAkBv5C,GAAInO,UAIjBiM,EAAQy3C,aAAauB,iBACtBuD,EAA+Br6C,EAAIs5C,MAKnDgB,EAA4B,WACxB,GAAIxC,EAAqBlsD,OAAQ,CAC7BisD,GAA+B,CAE/B,IAAI0C,GAAqBzC,EAAqB3/C,OAE1CoiD,GAAmBC,OACnBC,EAAkCF,GAGlCG,EAA+BH,OAInC1C,IAA+B,GAIvC8C,EAAY,SAAS36C,GACjB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBryC,SAGtDk1C,EAAc,SAAS76C,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBc,iBAGtDgC,EAAY,SAAS10D,GACjB,MAAOw0D,GAAcpzC,EAAWwwC,EAAgB5xD,EAAO,YAG3D20D,EAAY,SAAS/6C,GACjB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBe,eAGtDiC,EAAoB,WAChB,MAAOJ,GAAcpzC,EAAWwwC,EAAgBoB,iBAGpD6B,EAAc,SAASj7C,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBkB,eAGtD3xC,EAAU,SAASvH,GACf,MAAOu3C,GAAUG,IAAI13C,IAAOna,GAAG2vB,GAAUxsB,gBAhOzB,cAgO6DgX,IAGjFpI,EAAc,SAASoI,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB32C,OAGtD65C,EAAW,SAASl7C,GAChB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBl8C,QAGtDq/C,EAAc,SAASn7C,GAGnB,MAAU,OAANA,EACO46C,EAAcpzC,EAAWwwC,EAAgBW,4BAC5CiC,EAAcpzC,EAAWwwC,EAAgBY,kBAI1CgC,EAAcrzC,EAAQvH,GAAKg4C,EAAgBU,uBAC9CkC,EAAcrzC,EAAQvH,GAAKg4C,EAAgBj8C,cAGnDq/C,EAAW,SAASp7C,GAChB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB7tC,QAGtD3B,EAAU,SAASxI,GACf,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgB52C,OAGtDi6C,EAAa,SAASr7C,GAClB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBa,UAGtD+B,EAAgB,SAASjlD,EAAS2lD,GAC9B,MAAO3lD,IAAW9P,GAAG8P,GAAS3M,gBAAgBsyD,IAGlDnB,EAAe,SAASn6C,GACpB,MAAOq3C,IAAkBuD,EAAcrzC,EAAQvH,GAAKg4C,EAAgBsB,YAGxEvzD,EAAO,SAAS8vC,GACZA,GAAMhwC,GAAGgwC,GAAI3tC,SAAS4V,EAAQmS,QAAQlqB,OAM1Ci0D,EAA8B,SAASxiC,EAAa8hC,GAChD,GAAIn8B,GAAW3F,EAAYxxB,MAAMm3B,SAC7BD,EAAY1F,EAAYxxB,MAAMk3B,SAE9BA,IAAaC,IAAam8B,EAAUtzD,MAAMm3B,WAAam8B,EAAUtzD,MAAMk3B,WACvEr3B,GAAGyzD,GAAWnyD,KACVg2B,SAAUA,EACVD,UAAWA,KAQvBm9B,EAAiC,SAASr6C,EAAIs5C,GAC1C,GAAIiC,GAAahC,EAAkBv5C,KAAO,GAAIna,IAAG4L,SAAUI,UACvD2pD,EAA2B,GAAI31D,IAAG4L,OAqBtC,OAnBA+nD,GAA+B78C,KAAK,SAASy0B,GACzCmqB,EAAW5+C,KACP,WACI6+C,EAAyB7pD,WAE7B,WACIqoD,EAA4B5oB,EAAKkoB,GAEjCA,EAAU5nD,OAAS,WACf4nD,EAAU5nD,OAAS,KACnB8pD,EAAyB7pD,WAG7B2nD,EAAUrkB,IAAM7D,EAAI6D,IACpBglB,EAAKX,OAKVkC,GAWXC,EAAsB,WAClB,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACA/S,EACAsQ,EACAF,EACA4C,EACAC,CAKJ,IAHAjwD,EAAI,oBAG0B,MAA1B8R,EAAQ44C,eACR,KAAM,IAAIrvD,OAAM,oDAIpB,IAAIxB,GAAGwH,SAASyQ,EAAQ44C,gBAAiB,CAGrC,GAFAgF,EAAWlsD,SAASs8B,eAAehuB,EAAQ44C,gBAE1B,OAAbgF,EACA,KAAM,IAAIr0D,OAAMxB,GAAG8H,OAAO,0CAA2CmQ,EAAQ44C,gBAGjFiF,GAAaD,EAAS1mD,cAErB,CACD,GAAyChL,SAArC8T,EAAQ44C,eAAe1hD,UACvB,KAAM,IAAI3N,OAAM,gGAIpBs0D,GAAa79C,EAAQ44C,eAAe1hD,UA4ExC,GAzEA2mD,EAAa91D,GAAG0H,QAAQouD,GACxBE,EAAiBrsD,SAASC,cAAc,OACxCosD,EAAe5kD,YAAYpR,GAAGgP,UAAU8mD,IACxCM,EAAap2D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBO,UAI5Dz6C,EAAQ2L,SACRsyC,EAAgBl2D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBvuC,QAC/DsyC,GACAl2D,GAAGk2D,GAAe90D,UASrBpB,GAAGmhD,aAAgBnhD,GAAG8S,kBAAkB6C,WACzC49C,EAAiBvzD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBoB,gBAChEA,GACAvzD,GAAGuzD,GAAgBnyD,UAI3B+hD,EAAWnjD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBQ,MAI1DxP,IAAanjD,GAAGmhD,cAChBh7C,EAAI,0BAA2B,QAC/BnG,GAAGmjD,GAAU/hD,UAGZpB,GAAG8S,kBAAkB6C,SAajB3V,GAAGo2D,GAAYtyD,aAtZN,sBAsZ2Cq/C,IACzDgT,EAAan2D,GAAGmjD,GAAUhgD,gBAAgBgvD,EAAgBmB,UAC1D6C,GAAcn2D,GAAGm2D,GAAY/0D,WAb7Bg1D,EAAWz8C,gBA3YG,qBA6YVwpC,GAAYnjD,GAAGmjD,GAAUr/C,aA9YhB,qBAkZT9D,GAAGmjD,GAAU7hD,KACTlB,QAAS,UAWrBqzD,EAAYzzD,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBsB,WAC1DjC,EAGIiC,IACLvB,EAAmB5uB,SAASmwB,EAAUvvD,aAtapB,gBAwalBguD,EAAmBA,EAAmB,EAAIA,EAAmB,KAE7DT,EAAczxD,GAAGyzD,GAAW3vD,aAzaN,oBAkatB2vD,GAAazzD,GAAGyzD,GAAWryD,SAS/BowD,EAAiBA,GAAkBiC,EAEnCpC,EAAsBrxD,GAAGg2D,GAAgBxzD,WAAW2vD,EAAgBiB,mBAAmBrtD,OAAS,EAChGurD,EAAsBtxD,GAAGg2D,GAAgBxzD,WAAW2vD,EAAgB7tC,OAAOve,OAAS,EAEpFgwD,EAAe/1D,GAAGg2D,GAAgB7yD,gBAAgBgvD,EAAgBS,MAE9C,MAAhBmD,EACA,KAAM,IAAIv0D,OAAM,0DAapB,OAVAy0D,GAAaF,EAAa3yD,SAAS,GAAGizD,WAAU,GAChDN,EAAa5mD,UAAY,GAGrB6mD,EAAelzD,qBAAqB,UAAUiD,QAC9C4D,SAASC,cAAc,UAG3BzD,EAAI,8BAGA2pD,SAAUkG,EACVM,aAAcL,IAItBM,EAAc,SAASvmB,EAAIp1B,EAAO+U,GAC9B,GAAI6mC,GAAW7mC,EACX8mC,EAAWD,EAASlzD,UAEpBsX,GAAQ,IACR67C,EAAWz2D,GAAGw2D,GAAUpzD,WAAWwX,GAAOpX,aAI9CgzD,EAASv1D,aAAa+uC,EAAIymB,IAG9B5B,EAAiC,SAASH,GACtC,GAAIv6C,GAAKu6C,EAAmBv6C,GACxBu8C,EAAgBhC,EAAmBgC,cACnCC,EAAqBD,GAAiBA,EAAcnC,cACpDd,EAAYa,EAAan6C,GACzBiB,GACIgG,qBAAsBszC,EAAmBtzC,qBACzCF,QAASgxC,EACTz4B,QAAQ,EACRhY,OAAO,EAGXzhB,IAAG8S,kBAAkBgD,cACjB29C,EACIx7C,EAAQy9B,OAAOsb,WAAa/4C,EAAQy9B,OAAOsb,WAAae,GACxDyC,EAA+Br6C,EAAIs5C,GACnCgB,KAGAR,EAAkBR,GAAWl8C,KAAK,WAC9Bm8C,EAAkBv5C,GAAM,GAAIna,IAAG4L,QAE/B8nD,EAAkBv5C,GAAI5C,KAAK,WACvBoS,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,qBAM/B,MAAtBqG,EACAC,EAAiBz8C,EAAIw8C,GAGrBtC,EAAmBl6C,EAAIu8C,EAAet7C,KAOlDq5C,IAGChB,IACLQ,EAAkBR,GAClBgB,MAIRG,EAAoC,SAASF,GACzC,GAAIv6C,GAAKu6C,EAAmBv6C,GACxBqM,EAAekuC,EAAmBluC,aAClCqwC,EAAiBnC,EAAmBmC,eACpCpD,EAAYa,EAAan6C,GACzBiB,GACIgG,qBAAsBszC,EAAmBtzC,qBACzCK,MAAOgwC,EACPvwC,QAASgxC,EAGjB,IAAIuB,EACA,GAAIjtC,EAAc,CACd,KAAIvO,EAAQy9B,OAAOsb,WAAa/4C,EAAQy9B,OAAOsb,WAAae,GASxD,MAJI8E,IACA5C,EAAkBR,GAGfx7C,EAAQyhC,eAAe93B,SAAS4E,EAAcitC,EAAWr4C,GAAMtE,KAClE,WACIs9C,EAAKX,GACL1B,IACApoC,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,oBAGzD,WACIkE,EAA+Br6C,EAAIs5C,GACnC9pC,WAAW8qC,EAA2Bx8C,EAAQy9B,OAAO4a,oBAjB7DkE,GAA+Br6C,EAAIs5C,GACnCgB,QAsBJD,GAA+Br6C,EAAIs5C,GACnCgB,KAKZqC,EAAsB,SAAS38C,EAAI48C,GAC/B,GAAIC,GAAM1B,EAAYn7C,GAElB88C,EAA4B,MAAN98C,EAAag4C,EAAgBY,iBAAmBZ,EAAgBj8C,WAEtF8gD,KAAQh3D,GAAGg3D,GAAKl1D,SAASm1D,KACzBD,EAAMh3D,GAAGg3D,GAAK7zD,gBAAgB8zD,IAG9BD,IACAh3D,GAAGg3D,GAAK11D,KAAKuqC,MAAOkrB,EAAU,MAC9BC,EAAI7lD,aAAa,gBAAiB4lD,KAI1C3C,EAAO,SAASpkB,GACZA,GAAMhwC,GAAGgwC,GAAI1tC,YAAY2V,EAAQmS,QAAQlqB,OAG7C02D,EAAmB,SAASM,EAAmBC,GAC3C,GAAIC,GAAkB9C,EAAa4C,GAC/BG,EAAkB/C,EAAa6C,EAEnChxD,GAAInG,GAAG8H,OAAO,qFAAsFovD,EAAmBC,EAAmBA,IAG1IzD,EAAkByD,GAAmBrgD,KAAK,WACtCi7C,IACA2B,EAAkBwD,GAAmBprD,UACrC3F,EAAInG,GAAG8H,OAAO,uEAAwEqvD,EAAmBD,IACzGE,EAAgBhoB,IAAMioB,EAAgBjoB,IACtCglB,EAAKgD,IAET,WACI1D,EAAkBwD,GAAmBlrD,UAChCiM,EAAQy3C,aAAauB,iBACtBuD,EAA+B0C,EAAmBE,KAKlEp3D,IAAG6B,OAAOoW,EAASmD,GACnBjV,EAAM8R,EAAQ9R,IAITnG,GAAG8S,kBAAkBgD,gBACtBmC,EAAQy9B,OAAO4a,kBAAoB,EACnCr4C,EAAQy9B,OAAOsb,UAAY,GAG/BrvC,EAAY1J,EAAQ64C,YACpBU,EAA4CrtD,SAA3B8T,EAAQyhC,eACzB6X,EAAcqE,IAEd/B,IAEA7zD,GAAG6B,OAAOxB,MACNkvC,OAAQ,WACJppC,EAAI,8BAEJ4rD,EAAsB,EAEtBpwC,EAAUvQ,YAAYmgD,EAAYzB,SAASuG,WAAU,IACrDn2D,EAAKi1D,KACL90D,KAAKi3D,oBACL3nC,EAAW1X,EAAQ84C,iBAAmBgE,EAAcpzC,EAAWwwC,EAAgBS,MAE/EzsD,EAAI,gCAGRirD,cAAe,SAAShrD,GACpB,GAAImxD,GAAev3D,GAAGgP,UAAU5I,EAChCub,GAAUxS,UAAY,GACtBwS,EAAUvQ,YAAYmmD,IAG1B19C,MAAO,WACH8H,EAAUxS,UAAY,GACtB9O,KAAKkvC,UAGToX,WAAY,WACRh3B,EAASxgB,UAAY,IAGzB8+C,cAAe,WACX6D,GAAmB,GAGvB32C,QAAS,SAAShB,EAAIpY,EAAMy1D,EAAaC,EAAaC,GAClD,GAIIC,GAJAC,EAASrG,EAAY+E,aAAaD,WAAU,GAC5CwB,EAAa9C,EAAc6C,EAAQzF,EAAgB32C,MACnD46C,EAAarB,EAAcpzC,EAAWwwC,EAAgBO,UACtD9yC,EAAgB83C,EAAQhG,EAAUC,QAAUhiC,CAG5C+nC,KACAhG,EAAUG,IAAI13C,GAAMy9C,GAGxB53D,GAAG43D,GAAQv1D,SArpBK,cAqpBwB8X,GACxCi8C,EAAWz8C,gBAjpBO,qBAmpBdk+C,IACA73D,GAAG63D,GAAYp0D,QAAQ1B,GACvB81D,EAAW1mD,aAAa,QAASpP,IAGrC61D,EAAOzmD,aA9pBI,aA8pBuBgJ,GAE9Bq9C,EACAjB,EAAYqB,EAAQJ,EAAY58C,MAAOgF,GAGvCA,EAAcxO,YAAYwmD,GAG1BH,GACAG,EAAOz3D,MAAMC,QAAU,OACvBJ,GAAG43D,GAAQv1D,SAjqBI,uBAoqBfnC,EAAKo1D,EAAYn7C,IACjBja,EAAKyiB,EAAQxI,IACbja,EAAKg1D,EAAU/6C,IACfja,EAAKq1D,EAASp7C,IACdja,EAAKm1D,EAASl7C,IACdja,EAAK80D,EAAY76C,IAEb23C,GACAzxD,KAAKorD,WAAWtxC,GAGpBw9C,EAAQrD,EAAan6C,GACjBw9C,IAAUA,EAAMvoB,KAChBwkB,EAA6B98C,KAAK,SAASghD,GACvCH,EAAMvoB,IAAM0oB,EAAW1oB,IACnB0oB,EAAW33D,MAAMk3B,WAAaygC,EAAW33D,MAAMm3B,UAC/Ct3B,GAAG23D,GAAOr2D,KACN+1B,UAAWygC,EAAW33D,MAAMk3B,UAC5BC,SAAUwgC,EAAW33D,MAAMm3B,WAInC88B,EAAKuD,OAMrBvJ,eAAgB,SAASj0C,EAAIpY,EAAMy1D,EAAaC,GAC5Cp3D,KAAK8a,QAAQhB,EAAIpY,EAAMy1D,EAAaC,GAAa,IAGrD/Q,cAAe,WACX/2B,EAASve,YAAYsgD,EAAUC,SAC/BD,EAAUC,QAAUhoD,SAASioD,yBAC7BF,EAAUG,QAGd3J,WAAY,SAAS/tC,GACjBna,GAAG0hB,EAAQvH,IAAK/Y,UAGpBymD,UAAW,SAAS7X,GAChB,GAAI+nB,GAAc/nB,CAElB,IAAI+nB,EAAa,CAEb,KAAiD,MAA1CA,EAAY7zD,aA3tBZ,eA4tBH6zD,EAAcA,EAAY52D,UAG9B,OAAOmiC,UAASy0B,EAAY7zD,aA/tBrB,iBAmuBf8zD,YAAa,WACT,MAAOroC,IAGXg7B,qBAAsB,SAASxwC,GAC3B,GAAIxI,GAAWI,EAAYoI,EAE3BxI,IAAY3R,GAAG2R,GAAUtP,SAAS4V,EAAQmS,QAAQ2lC,WAGtDxI,eAAgB,SAASptC,EAAIpY,GACzB,GAAIk2D,GAAalmD,EAAYoI,EAEzB89C,KACAj4D,GAAGi4D,GAAYx0D,QAAQ1B,GACvBk2D,EAAW9mD,aAAa,QAASpP,KAIzCwoD,aAAc,SAASpwC,GACnBja,EAAK6R,EAAYoI,KAGrBswC,aAAc,SAAStwC,GACnBi6C,EAAKriD,EAAYoI,KAGrB+9C,WAAY,SAASloB,GACjB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgB32C,OAG3CuG,UAAW,WACP,MAAO9J,GAAQ2L,QAAUmxC,EAAcpzC,EAAWwwC,EAAgBvuC,SAGtEwlC,mBAAoB,WAChBlpD,EAAKi1D,MAGThM,mBAAoB,WAChBiL,EAAKe,MAGTjM,YAAa,WACT,MAAO6L,GAAcpzC,EAAWwwC,EAAgBQ,OAGpD/I,uBAAwB,WACpB,MAAOyH,IAGXzG,UAAW,SAASzwC,GAChBja,EAAKq1D,EAASp7C,KAGlB8xC,gBAAiB,WACb,MAAOqF,IAGXpF,UAAW,SAAS/xC,GAChBi6C,EAAKmB,EAASp7C,KAGlB8sC,iBAAkB,SAAS9sC,GACvB,MAAOuH,GAAQvH,IAGnBuwC,aAAc,SAASvwC,GACnB,GAAIg+C,GAAO/C,EAAYj7C,EAEvBg+C,IAAQn4D,GAAGm4D,GAAM91D,SAAS4V,EAAQmS,QAAQ2lC,WAG9C/I,gBAAiB,SAAS7sC,GACtB,MAAOna,IAAG0hB,EAAQvH,IAAKrY,SAryBJ,sBAwyBvB0oD,aAAc,SAASrwC,GACnB,GAAIg+C,GAAO/C,EAAYj7C,EAEvBg+C,IAAQn4D,GAAGm4D,GAAM71D,YAAY2V,EAAQmS,QAAQ2lC,WAGjDqI,WAAY,SAASpoB,GACjB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBkB,cAAc,IAGzDhJ,aAAc,SAASlwC,GACnB,MAAO46C,GAAcrzC,EAAQvH,GAAKg4C,EAAgBiB,oBAGtDiF,YAAa,SAASroB,GAClB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBiB,mBAAmB,IAG9D5H,eAAgB,SAASrxC,EAAIgR,EAAQC,GACjC,GACI2rC,GADAC,EAAM1B,EAAYn7C,EAGlB68C,IAAO5rC,EAAQ,IACf2rC,EAAUp1D,KAAKC,MAAMupB,EAASC,EAAQ,KAEtB,MAAZ2rC,EACA72D,EAAK82D,GAGL5C,EAAK4C,GAGTF,EAAoB38C,EAAI48C,KAIhC7Z,oBAAqB,SAAS/xB,EAAQC,GAClC/qB,KAAKmrD,eAAe,KAAMrgC,EAAQC,IAGtCsgC,aAAc,SAASvxC,GACnB,GAAI68C,GAAM1B,EAAYn7C,EAEtB68C,IAAO92D,EAAK82D,IAGhBM,kBAAmB,WACfj3D,KAAKqrD,gBAGTsB,cAAe,SAAS7yC,GACpB28C,EAAoB38C,EAAI,GACxB9Z,KAAKi3D,kBAAkBn9C,IAG3BgxC,mBAAoB,WAChB9qD,KAAK2sD,iBAGThB,WAAY,SAAS7xC,GACjB,IAAK23C,EAAkB,CACnB,GAAIhyC,GAASg1C,EAAU36C,EAEvB2F,IAAU9f,GAAG8f,GAAQxd,YAAY2V,EAAQmS,QAAQlqB,QAIzDurD,WAAY,SAAStxC,GACjBja,EAAK40D,EAAU36C,KAGnBm+C,SAAU,SAAStoB,GACf,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBryC,QAAQ,IAGnD2sC,WAAY,SAAStyC,GACjBi6C,EAAKiB,EAASl7C,IACdja,EAAK80D,EAAY76C,KAGrBqtC,aAAc,SAASrtC,GACnB9Z,KAAKwqD,cAAc1wC,EAAIlC,EAAQvU,KAAKklC,QACpCvoC,KAAKk4D,oBAAoBp+C,GACzBja,EAAKs1D,EAAWr7C,KAGpB6wC,UAAW,SAAS7wC,GAChBja,EAAKm1D,EAASl7C,KAGlBq+C,QAAS,SAASxoB,GACd,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBl8C,OAAO,IAGlDwiD,iBAAkB,SAASzoB,GACvB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBc,gBAAgB,IAG3DsF,oBAAqB,SAASp+C,GAC1Bi6C,EAAKY,EAAY76C,IACjBja,EAAKm1D,EAASl7C,KAGlButC,gBAAiB,SAASvtC,GACtB9Z,KAAKwqD,cAAc1wC,EAAI,IACvB9Z,KAAKosD,WAAWtyC,GAChBi6C,EAAKoB,EAAWr7C,KAGpBmyC,iBAAkB,SAASnyC,GACvBi6C,EAAKc,EAAU/6C,KAGnBmzC,iBAAkB,SAASnzC,GACvBja,EAAKg1D,EAAU/6C,KAGnBu+C,eAAgB,SAAS1oB,GACrB,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgBe,cAAc,IAGzDyF,QAAS,SAAS3oB,GACd,MAAOhwC,IAAGgwC,GAAIluC,SAASqwD,EAAgB7tC,OAAO,IAGlD3H,WAAY,SAASxC,EAAIzW,GACrB,GAAI6X,GAAOoH,EAAQxI,EAEfoB,KACA64C,EAAK74C,GACLvb,GAAGub,GAAM9X,QAAQC,KAIzBmnD,cAAe,SAAS1wC,EAAIzW,GACxB,GAAIk1D,GAAS7D,EAAcrzC,EAAQvH,GAAKg4C,EAAgBgB,WAEpDyF,KAEY,MAARl1D,EACA1D,GAAG44D,GAAQ/0D,YAGX7D,GAAG44D,GAAQn1D,QAAQC,KAK/BwnD,YAAa,SAAS/wC,GAClBna,GAAG0hB,EAAQvH,IAAK7X,YA97BA,kBA+7BhBpC,EAAKs1D,EAAWr7C,KAGpBqyC,YAAa,SAASryC,GAClBna,GAAG0hB,EAAQvH,IAAK9X,SAn8BA,kBAo8BhB+xD,EAAKoB,EAAWr7C,KAGpBo0C,gBAAiB,SAASp0C,EAAIu8C,EAAet1C,GACpC/gB,KAAK2mD,gBAAgB7sC,KACtB83C,EAAqB/uD,MAAMiX,GAAIA,EAAIiH,qBAAsBA,EAAsBs1C,cAAeA,KAC7F1E,GAAgCyC,MAIzCpG,gBAAiB,SAASl0C,EAAIqM,EAAcqwC,EAAgBz1C,GACnD/gB,KAAK2mD,gBAAgB7sC,KACtB83C,EAAqB/uD,MAAMke,qBAAsBA,EAAsBuzC,QAAQ,EAAMx6C,GAAIA,EAAIqM,aAAcA,EAAcqwC,eAAgBA,KACxI7E,GAAgCyC,MAIzClE,UAAW,SAAShwD,GAChB,MAAOP,IAAG8S,kBAAkB2C,iBAAmBw/C,EAAU10D,IAG7DiwD,WAAY,SAASjwD,EAAM6F,EAASsqD,GAChC,GAAImI,GAAS5D,EAAU10D,GACnBu4D,EAAY/D,EAAc8D,EAAQ1G,EAAgBI,eAClDwG,EAAUF,EAAO/1D,qBAAqB,SAAS,GAC/Ck2D,EAAYjE,EAAc8D,EAAQ1G,EAAgBE,oBAClD4G,EAAQlE,EAAc8D,EAAQ1G,EAAgBK,gBAC9C7mD,EAAU,GAAI3L,IAAG4L,QAEjBstD,EAAe,WACXF,EAAUp4D,oBAAoB,QAASu4D,GACvCF,GAASA,EAAMr4D,oBAAoB,QAASw4D,GAC5CztD,EAAQK,WAGZmtD,EAAqB,WACjBH,EAAUp4D,oBAAoB,QAASu4D,GACvCN,EAAOQ,SAGXD,EAAiB,WACbP,EAAOj4D,oBAAoB,QAASs4D,GACpCD,EAAMr4D,oBAAoB,QAASw4D,GACnCP,EAAOQ,QAEP1tD,EAAQG,QAAQitD,GAAWA,EAAQhyD,OAc3C,OAXA8xD,GAAOp4D,iBAAiB,QAASy4D,GACjCF,EAAUv4D,iBAAiB,QAAS04D,GACpCF,GAASA,EAAMx4D,iBAAiB,QAAS24D,GAErCL,IACAA,EAAQhyD,MAAQ2pD,GAEpBoI,EAAUl1D,YAAcwC,EAExByyD,EAAOS,YAEA3tD,MChhCnB3L,GAAGu5D,eAAiB,SAASC,EAAGC,GAC5B,YAqBA,SAASlO,GAAWtrD,GAChBoS,EAAS/R,OAAOL,EAASmb,EAAKs+C,UAAW,SAASxkC,GAE9CA,EAAQA,GAAShwB,OAAOgwB,KAGxB,IAAI5oB,GAAS4oB,EAAM5oB,QAAU4oB,EAAMykC,UAEnCv+C,GAAKw+C,UAAUttD,EAAQ4oB,KA3B/B,GAAI7iB,GAAW,GAAIrS,IAAGkS,eAClBkJ,GACIs+C,UAAW,QACXG,SAAU,KACVD,UAAW,SAASttD,EAAQ4oB,KAKpCl1B,IAAG6B,OAAOxB,MACNkrD,WAAY,SAAStrD,GACjBsrD,EAAWtrD,IAGfmS,QAAS,WACLC,EAASD,aAiBjBpS,GAAG6B,OAAO43D,GACNK,kBAAmB,SAASxyD,GACxB,MAAOA,GAAKyyD,UAGhBC,kBAAmB,WACf,MAAO3nD,MAIfrS,GAAG6B,OAAOuZ,EAAMo+C,GAEZp+C,EAAKy+C,UACLtO,EAAWnwC,EAAKy+C,WClDxB75D,GAAGooD,wBAA0B,SAASoR,GAClC,YAqBA,SAASS,GAAa3tD,EAAQ4oB,GAC1Bl1B,GAAG+C,KAAKm3D,EAAgB,SAASC,EAAY7qC,GACzC,GACItO,GADAo5C,EAA2BD,EAAWxqD,OAAO,GAAGwX,cAAgBgzC,EAAWjyD,MAAM,EAGrF,IAAIkT,EAAK4tC,WAAW,KAAOoR,GAA0B9tD,GAKjD,MAJA0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,GACnCtM,GAAG6O,eAAeqmB,GAClB9Z,EAAKjV,IAAInG,GAAG8H,OAAO,+DAAgEsT,EAAKuuC,UAAU3oC,GAASA,IAC3GsO,EAAQtO,IACD,IA7BnB,GAAIq5C,MACAj/C,GACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBC,aAAc,SAASvoC,KACvByK,SAAU,SAASzK,KACnBwoC,QAAS,SAASxoC,KAClByoC,QAAS,SAASzoC,KAClB0oC,WAAY,SAAS1oC,KACrB2oC,UAAW,SAAS3oC,MAExBk5C,GACIp6C,OAAQ,SAAS3F,GAAMiB,EAAKqQ,SAAStR,IACrCmK,MAAQ,SAASnK,GAAMiB,EAAKouC,QAAQrvC,IACpC+4C,aAAc,SAAS/4C,GAAMiB,EAAKmuC,aAAapvC,IAC/ClE,MAAO,SAASkE,GAAMiB,EAAKquC,QAAQtvC,IACnC84C,eAAgB,SAAS94C,GAAMiB,EAAKsuC,WAAWvvC,IAkBvDna,IAAG6B,OAAOuZ,EAAMo+C,GAEhBp+C,EAAKs+C,UAAY,QACjBt+C,EAAKw+C,UAAYK,EACjB7+C,EAAKy+C,SAAWz+C,EAAK4tC,WAAWgP,cAEhCh4D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu5D,eAAen+C,EAAMi/C,KC1ChDr6D,GAAG6pD,qBAAuB,SAAS2P,GAC/B,YAiBA,SAASS,GAAa3tD,EAAQ4oB,GAC1B,GAAI9Z,EAAK4tC,WAAWkP,WAAW5rD,IAAW8O,EAAK4tC,WAAWoP,WAAW9rD,GAAS,CAC1E,GAAI0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,EAC1B8O,GAAK4uC,kBAAkBhpC,KAGrBhhB,GAAGya,OAAOyC,YACrB9B,EAAKjV,IAAInG,GAAG8H,OAAO,4DAA6DsT,EAAKuuC,UAAU3oC,GAASA,IACxGhhB,GAAG6O,eAAeqmB,GAElBmlC,EAAqBC,mBAAmBt5C,EAAQ1U,GAAQ,KAzBpE,GAAI+tD,MACAj/C,GACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBl/B,SACI5O,KAAM,iBACN63C,aAAc,yBAElBrJ,kBAAmB,SAAShpC,KAC5B2oC,UAAW,SAAS3oC,KAG5BhhB,IAAG6B,OAAOuZ,EAAMo+C,GAkBhBp+C,EAAKs+C,UAAY,QACjBt+C,EAAKw+C,UAAYK,EAEjBj6D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu6D,oBAAoBn/C,EAAMi/C,KCpCrDr6D,GAAGirD,4BAA8B,SAASuO,EAAGa,GACzC,YAaA,SAASG,GAAiBluD,EAAQ4oB,GAC9B,GAAI9Z,EAAK4tC,WAAWqP,YAAY/rD,GAAS,CACrC,GAAI0U,GAAS5F,EAAK4tC,WAAWnB,UAAUv7C,EAC1B8O,GAAK4uC,kBAAkBhpC,KAErBhhB,GAAGya,OAAOyC,YACrB9B,EAAKjV,IAAInG,GAAG8H,OAAO,kEAAmEsT,EAAKuuC,UAAU3oC,GAASA,IAC9Gq5C,EAAqBC,mBAAmBt5C,EAAQ1U,KAlB5D,GAAI8O,IACI4tC,WAAY,KACZgB,kBAAmB,SAAShpC,KAC5B7a,IAAK,SAASC,EAASkjD,KAG1B+Q,KACDA,MAgBJj/C,EAAKs+C,UAAY,UACjBt+C,EAAKw+C,UAAYY,EAEjBx6D,GAAG6B,OAAOuZ,EAAMo+C,GAChBx5D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu6D,oBAAoBn/C,EAAMi/C,KCzBrDr6D,GAAG8pD,0BAA4B,SAAS1uC,GACpC,YAEAA,GAAKs+C,UAAY,QACjBt+C,EAAKy+C,SAAW,KAEhB75D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGirD,4BAA4B7vC,QCVvDpb,GAAGu6D,oBAAsB,SAASf,EAAGa,GACjC,YAWA,SAASI,GAAyBz5C,GAC9B,GAAI05C,GAAkBt/C,EAAKuuC,UAAU3oC,GACjCpP,EAAS8oD,EAAgB7oD,YAAY,IAMzC,OAJID,GAAS,IACT8oD,EAAkBA,EAAgB5oD,OAAO,EAAGF,IAGzC8oD,EAGX,QAASC,GAAqB35C,GAC1B,GAAI45C,GAAWx/C,EAAKuuC,UAAU3oC,EAC9B,OAAOhhB,IAAG0R,aAAakpD,GAI3B,QAASC,GAAiBC,EAAoB95C,GAC1C,GACI+5C,GADAr+C,EAAUo+C,EAAmB/zD,KAGjB5C,UAAZuY,GAAyB1c,GAAG0H,QAAQgV,GAAS3W,OAAS,IACtDg1D,EAAgBJ,EAAqB35C,GAEf7c,SAAlB42D,IACAr+C,EAAUA,EAAU,IAAMq+C,GAG9B3/C,EAAK6uC,UAAUjpC,EAAQtE,IAG3BtB,EAAK8uC,sBAAsBlpC,GAAQ,GAIvC,QAASg6C,GAAyBjC,EAAS/3C,GACvCq5C,EAAqBL,oBAAoB15D,OAAOy4D,EAAS,OAAQ,WAC7D8B,EAAiB9B,EAAS/3C,KAKlC,QAASi6C,GAA6BlC,EAAS/3C,GAC3Cq5C,EAAqBL,oBAAoB15D,OAAOy4D,EAAS,QAAS,SAAS7jC,GAI1D,MAFFA,EAAMgmC,SAAWhmC,EAAMimC,QAG9BN,EAAiB9B,EAAS/3C,KAzDtC,GAAI5F,IACI4tC,WAAY,KACZ7iD,IAAK,SAASC,EAASkjD,KACvBU,kBAAmB,SAAShpC,KAC5B2oC,UAAW,SAAS3oC,KACpBipC,UAAW,SAASjpC,EAAQtE,KAC5BwtC,sBAAuB,SAASlpC,EAAQmpC,KAwDhDnqD,IAAG6B,OAAOuZ,EAAMo+C,GAEhBp+C,EAAKy+C,SAAWz+C,EAAK4tC,WAAWgP,cAEhCh4D,GAAG6B,OAAOxB,KAAM,GAAIL,IAAGu5D,eAAen+C,EAAMi/C,IAE5Cr6D,GAAG6B,OAAOw4D,GACNC,mBAAoB,SAASngD,EAAI7N,EAAQ8uD,GACrC,GAAIN,GAAqB1/C,EAAK4tC,WAAWqB,aAAalwC,EAEtDiB,GAAK8uC,sBAAsB/vC,GAAI,GAE/B2gD,EAAmB/zD,MAAQ0zD,EAAyBtgD,GAEhDihD,GACAN,EAAmBO,QAGvBL,EAAyBF,EAAoB3gD,GAC7C8gD,EAA6BH,EAAoB3gD,Q3CvF9BjV","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","substring","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","match","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","options","title","self","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","index","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","params","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","_options","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","callbacks","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","toUpperCase","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","namespace","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","el","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","DragAndDrop","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","FineUploader","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","uploader","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","cloneNode","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"fine-uploader.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js index f635b4d0e..00152c02b 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js @@ -1,4 +1,4 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { (function($) { "use strict"; @@ -842,7 +842,7 @@ }; qq.Error.prototype = new Error(); })(); - qq.version = "5.12.0"; + qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; @@ -860,9 +860,6 @@ } return supported; } - function isChrome21OrHigher() { - return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; - } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } @@ -900,7 +897,11 @@ supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); - supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsFolderDrop = supportsFileDrop && function() { + var input = document.createElement("input"); + input.type = "file"; + return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); + }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); @@ -1160,7 +1161,8 @@ originalName: spec.name, uuid: spec.uuid, size: spec.size == null ? -1 : spec.size, - status: status + status: status, + file: spec.file }) - 1; if (spec.batchId) { data[id].batchId = spec.batchId; @@ -1182,6 +1184,7 @@ byStatus[status] = []; } byStatus[status].push(id); + spec.onBeforeStatusChange && spec.onBeforeStatusChange(id); uploaderProxy.onStatusChange(id, null, status); return id; }, @@ -1198,6 +1201,12 @@ return qq.extend([], data, true); } }, + removeFileRef: function(id) { + var record = getDataByIds(id); + if (record) { + delete record.file; + } + }, reset: function() { data = []; byUuid = {}; @@ -1250,6 +1259,7 @@ CANCELED: "canceled", PAUSED: "paused", UPLOADING: "uploading", + UPLOAD_FINALIZING: "upload finalizing", UPLOAD_RETRYING: "retrying upload", UPLOAD_SUCCESSFUL: "upload successful", UPLOAD_FAILED: "upload failed", @@ -1330,7 +1340,14 @@ } }, cancel: function(id) { - this._handler.cancel(id); + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) { + this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.", id, this.getName(id)), "error"); + } else { + this._handler.cancel(id); + } }, cancelAll: function() { var storedIdsCopy = [], self = this; @@ -1407,7 +1424,17 @@ return this._endpointStore.get(fileId); }, getFile: function(fileOrBlobId) { - return this._handler.getFile(fileOrBlobId) || null; + var file = this._handler.getFile(fileOrBlobId); + var uploadDataRecord; + if (!file) { + uploadDataRecord = this._uploadData.retrieve({ + id: fileOrBlobId + }); + if (uploadDataRecord) { + file = uploadDataRecord.file; + } + } + return file || null; }, getInProgress: function() { return this._uploadData.retrieve({ @@ -1456,6 +1483,9 @@ id: id }).uuid; }, + isResumable: function(id) { + return this._handler.hasResumeRecord(id); + }, log: function(str, level) { if (this._options.debug && (!level || level === "info")) { qq.log("[Fine Uploader " + qq.version + "] " + str); @@ -1482,6 +1512,10 @@ } return false; }, + removeFileRef: function(id) { + this._handler.expunge(id); + this._uploadData.removeFileRef(id); + }, reset: function() { this.log("Resetting uploader..."); this._handler.reset(); @@ -1504,6 +1538,7 @@ this._succeededSinceLastAllComplete = []; this._failedSinceLastAllComplete = []; this._totalProgress && this._totalProgress.reset(); + this._customResumeDataStore.reset(); }, retry: function(id) { return this._manualRetry(id); @@ -1519,6 +1554,9 @@ setCustomHeaders: function(headers, id) { this._customHeadersStore.set(headers, id); }, + setCustomResumeData: function(id, data) { + this._customResumeDataStore.set(data, id); + }, setDeleteFileCustomHeaders: function(headers, id) { this._deleteFileCustomHeadersStore.set(headers, id); }, @@ -1546,6 +1584,28 @@ setUuid: function(id, newUuid) { return this._uploadData.uuidChanged(id, newUuid); }, + setStatus: function(id, newStatus) { + var fileRecord = this.getUploads({ + id: id + }); + if (!fileRecord) { + throw new qq.Error(id + " is not a valid file ID."); + } + switch (newStatus) { + case qq.status.DELETED: + this._onDeleteComplete(id, null, false); + break; + + case qq.status.DELETE_FAILED: + this._onDeleteComplete(id, null, true); + break; + + default: + var errorMessage = "Method setStatus called on '" + name + "' not implemented yet for " + newStatus; + this.log(errorMessage); + throw new qq.Error(errorMessage); + } + }, uploadStoredFiles: function() { if (this._storedIds.length === 0) { this._itemError("noFilesError"); @@ -1556,20 +1616,22 @@ }; qq.basePrivateApi = { _addCannedFile: function(sessionData) { - var id = this._uploadData.addFile({ + var self = this; + return this._uploadData.addFile({ uuid: sessionData.uuid, name: sessionData.name, size: sessionData.size, - status: qq.status.UPLOAD_SUCCESSFUL + status: qq.status.UPLOAD_SUCCESSFUL, + onBeforeStatusChange: function(id) { + sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + self._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + self._netUploaded++; + self._netUploadedOrQueued++; + } }); - sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); - sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); - if (sessionData.thumbnailUrl) { - this._thumbnailUrls[id] = sessionData.thumbnailUrl; - } - this._netUploaded++; - this._netUploadedOrQueued++; - return id; }, _annotateWithButtonId: function(file, associatedInput) { if (qq.isFile(file)) { @@ -1804,17 +1866,28 @@ onUploadPrep: qq.bind(this._onUploadPrep, this), onUpload: function(id, name) { self._onUpload(id, name); - self._options.callbacks.onUpload(id, name); + var onUploadResult = self._options.callbacks.onUpload(id, name); + if (qq.isGenericPromise(onUploadResult)) { + self.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.", id)); + return onUploadResult; + } + return new qq.Promise().success(); }, onUploadChunk: function(id, name, chunkData) { self._onUploadChunk(id, chunkData); - self._options.callbacks.onUploadChunk(id, name, chunkData); + var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData); + if (qq.isGenericPromise(onUploadChunkResult)) { + self.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.", id, chunkData.partIndex)); + return onUploadChunkResult; + } + return new qq.Promise().success(); }, onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._onUploadChunkSuccess(id, chunkData); self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); }, - onResume: function(id, name, chunkData) { - return self._options.callbacks.onResume(id, name, chunkData); + onResume: function(id, name, chunkData, customResumeData) { + return self._options.callbacks.onResume(id, name, chunkData, customResumeData); }, onAutoRetry: function(id, name, responseJSON, xhr) { return self._onAutoRetry.apply(self, arguments); @@ -1839,7 +1912,16 @@ return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; }, getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, - getIdsInBatch: self._uploadData.getIdsInBatch + getIdsInBatch: self._uploadData.getIdsInBatch, + isInProgress: function(id) { + return self.getUploads({ + id: id + }).status === qq.status.UPLOADING; + }, + getCustomResumeData: qq.bind(self._getCustomResumeData, self), + setStatus: function(id, status) { + self._uploadData.setStatus(id, status); + } }; qq.each(this._options.request, function(prop, val) { options[prop] = val; @@ -1916,6 +1998,9 @@ } } }, + _getCustomResumeData: function(fileId) { + return this._customResumeDataStore.get(fileId); + }, _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 ] @@ -2017,7 +2102,8 @@ uuid: uuid, name: name, size: size, - batchId: batchId + batchId: batchId, + file: file }); this._handler.add(id, file); this._trackButton(id); @@ -2038,6 +2124,28 @@ blob: blob }); }, + _handleDeleteSuccess: function(id) { + if (this.getUploads({ + id: id + }).status !== qq.status.DELETED) { + var name = this.getName(id); + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _handleDeleteFailed: function(id, xhrOrXdr) { + var name = this.getName(id); + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + }, _initExtraButton: function(spec) { var button = this._createUploadButton({ accept: spec.validation.acceptFiles, @@ -2190,7 +2298,7 @@ _onAutoRetry: function(id, name, responseJSON, xhr, callback) { var self = this; self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - if (self._shouldAutoRetry(id, name, responseJSON)) { + if (self._shouldAutoRetry(id)) { var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; self._maybeParseAndSendUploadError.apply(self, arguments); self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); @@ -2263,19 +2371,9 @@ _onDeleteComplete: function(id, xhrOrXdr, isError) { var name = this.getName(id); if (isError) { - this._uploadData.setStatus(id, qq.status.DELETE_FAILED); - this.log("Delete request for '" + name + "' has failed.", "error"); - if (xhrOrXdr.withCredentials === undefined) { - this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); - } else { - this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); - } + this._handleDeleteFailed(id, xhrOrXdr); } else { - this._netUploadedOrQueued--; - this._netUploaded--; - this._handler.expunge(id); - this._uploadData.setStatus(id, qq.status.DELETED); - this.log("Delete request for '" + name + "' has succeeded."); + this._handleDeleteSuccess(id); } }, _onInputChange: function(input) { @@ -2335,6 +2433,11 @@ this._uploadData.setStatus(id, qq.status.UPLOADING); }, _onUploadChunk: function(id, chunkData) {}, + _onUploadChunkSuccess: function(id, chunkData) { + if (!this._preventRetries[id] && this._options.retry.enableAuto) { + this._autoRetries[id] = 0; + } + }, _onUploadStatusChange: function(id, oldStatus, newStatus) { if (newStatus === qq.status.PAUSED) { clearTimeout(this._retryTimeouts[id]); @@ -2430,7 +2533,7 @@ this._uploadData.updateSize(id, newSize); this._totalProgress && this._totalProgress.onNewSize(id); }, - _shouldAutoRetry: function(id, name, responseJSON) { + _shouldAutoRetry: function(id) { var uploadData = this._uploadData.retrieve({ id: id }); @@ -2579,6 +2682,7 @@ maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, + warnBeforeUnload: true, request: { customHeaders: {}, endpoint: "/server/upload", @@ -2586,8 +2690,10 @@ forceMultipart: true, inputName: "qqfile", method: "POST", + omitDefaultParams: false, params: {}, paramsInBody: true, + requireSuccessJson: true, totalFileSizeName: "qqtotalfilesize", uuidName: "qquuid" }, @@ -2615,7 +2721,7 @@ onUpload: function(id, name) {}, onUploadChunk: function(id, name, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onProgress: function(id, name, loaded, total) {}, onTotalProgress: function(loaded, total) {}, onError: function(id, name, reason, maybeXhrOrXdr) {}, @@ -2668,9 +2774,20 @@ totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts" }, - partSize: 2e6, + partSize: function(id) { + return 2e6; + }, success: { - endpoint: null + endpoint: null, + headers: function(id) { + return null; + }, + jsonPayload: false, + method: "POST", + params: function(id) { + return null; + }, + resetOnStatus: [] } }, resume: { @@ -2678,6 +2795,9 @@ recordsExpireIn: 7, paramNames: { resuming: "qqresume" + }, + customKeys: function(fileId) { + return []; } }, formatFileName: function(fileOrBlobName) { @@ -2776,7 +2896,7 @@ this.log("Paste support module not found", "error"); } } - this._preventLeaveInProgress(); + this._options.warnBeforeUnload && this._preventLeaveInProgress(); this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); this._refreshSessionData(); this._succeededSinceLastAllComplete = []; @@ -2794,6 +2914,7 @@ }); } this._currentItemLimit = this._options.validation.itemLimit; + this._customResumeDataStore = this._createStore(); }; qq.FineUploaderBasic.prototype = qq.basePublicApi; qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); @@ -2863,7 +2984,7 @@ return xhrOrXdr; } function getXhrOrXdr(id, suppliedXhr) { - var xhrOrXdr = requestData[id].xhr; + var xhrOrXdr = requestData[id] && requestData[id].xhr; if (!xhrOrXdr) { if (suppliedXhr) { xhrOrXdr = suppliedXhr; @@ -3126,13 +3247,14 @@ onUploadChunk: function(id, fileName, chunkData) {}, onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, onAutoRetry: function(id, fileName, response, xhr) {}, - onResume: function(id, fileName, chunkData) {}, + onResume: function(id, fileName, chunkData, customResumeData) {}, onUuidChanged: function(id, newUuid) {}, getName: function(id) {}, setSize: function(id, newSize) {}, isQueued: function(id) {}, getIdsInProxyGroup: function(id) {}, - getIdsInBatch: function(id) {} + getIdsInBatch: function(id) {}, + isInProgress: function(id) {} }, chunked = { done: function(id, chunkIdx, response, xhr) { var chunkData = handler._getChunkData(id, chunkIdx); @@ -3151,13 +3273,13 @@ handler._maybeDeletePersistedChunkData(id); upload.cleanup(id, normaizedResponse, xhr); }, function(response, xhr) { - var normaizedResponse = upload.normalizeResponse(response, false); - log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); - if (normaizedResponse.reset) { + var normalizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normalizedResponse.error, "error"); + if (normalizedResponse.reset || xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0) { chunked.reset(id); } - if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { - upload.cleanup(id, normaizedResponse, xhr); + if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) { + upload.cleanup(id, normalizedResponse, xhr); } }); }, @@ -3169,7 +3291,8 @@ if (responseToReport.reset) { chunked.reset(id); } else { - inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + var inProgressChunksArray = handler._getFileState(id).chunking.inProgress; + inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1; if (inProgressIdx >= 0) { handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); handler._getFileState(id).chunking.remaining.unshift(chunkIdx); @@ -3207,13 +3330,14 @@ handler._maybeDeletePersistedChunkData(id); handler.reevaluateChunking(id); handler._getFileState(id).loaded = 0; + handler._getFileState(id).attemptingResume = false; }, sendNext: function(id) { - var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; - if (handler._getFileState(id).loaded == null) { - handler._getFileState(id).loaded = 0; + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), fileState = handler._getFileState(id), resuming = fileState.attemptingResume, inProgressChunks = fileState.chunking.inProgress || []; + if (fileState.loaded == null) { + fileState.loaded = 0; } - if (resuming && options.onResume(id, name, chunkData) === false) { + if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) { chunked.reset(id); chunkIdx = chunked.nextPart(id); chunkData = handler._getChunkData(id, chunkIdx); @@ -3222,8 +3346,6 @@ if (chunkIdx == null && inProgressChunks.length === 0) { chunked.finalize(id); } else { - log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); - options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); inProgressChunks.push(chunkIdx); handler._getFileState(id).chunking.inProgress = inProgressChunks; if (concurrentChunkingPossible) { @@ -3235,30 +3357,45 @@ if (chunkData.blob.size === 0) { log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); chunked.handleFailure(chunkIdx, id, "File is no longer available", null); - } else { - handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { - log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); - handler.clearCachedChunk(id, chunkIdx); - var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); - log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); - chunked.done(id, chunkIdx, responseToReport, xhr); - if (inProgressChunkIdx >= 0) { - inProgressChunks.splice(inProgressChunkIdx, 1); - } - handler._maybePersistChunkedState(id); - if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { - chunked.finalize(id); - } else if (chunked.hasMoreParts(id)) { - chunked.sendNext(id); - } else { - log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); - } - }, function failure(response, xhr) { - chunked.handleFailure(chunkIdx, id, response, xhr); - }).done(function() { - handler.clearXhr(id, chunkIdx); - }); } + var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + onUploadChunkPromise.then(function(requestOverrides) { + if (!options.isInProgress(id)) { + log(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.", id, chunkIdx)); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + var uploadChunkData = { + chunkIdx: chunkIdx, + id: id, + overrides: requestOverrides, + resuming: resuming + }; + handler.uploadChunk(uploadChunkData).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + }, function(error) { + chunked.handleFailure(chunkIdx, id, error, null); + }); } } }, connectionManager = { @@ -3334,7 +3471,12 @@ } }, simple = { send: function(id, name) { - handler._getFileState(id).loaded = 0; + var fileState = handler._getFileState(id); + if (!fileState) { + log("Ignoring send request as this upload may have been cancelled, File ID " + id, "warn"); + return; + } + fileState.loaded = 0; log("Sending simple upload request for " + id); handler.uploadFile(id).then(function(response, optXhr) { log("Simple upload request succeeded for " + id); @@ -3370,6 +3512,7 @@ initHandler: function() { var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getCustomResumeData: options.getCustomResumeData, getDataByUuid: options.getDataByUuid, getName: options.getName, getSize: options.getSize, @@ -3377,7 +3520,10 @@ log: log, onCancel: options.onCancel, onProgress: options.onProgress, - onUuidChanged: options.onUuidChanged + onUuidChanged: options.onUuidChanged, + onFinalizing: function(id) { + options.setStatus(id, qq.status.UPLOAD_FINALIZING); + } }); if (handler._removeExpiredChunkingRecords) { handler._removeExpiredChunkingRecords(); @@ -3450,12 +3596,26 @@ if (!controller.isValid(id)) { throw new qq.Error(id + " is not a valid file ID to upload!"); } - options.onUpload(id, name); - if (chunkingPossible && handler._shouldChunkThisFile(id)) { - chunked.sendNext(id); - } else { - simple.send(id, name); - } + options.onUpload(id, name).then(function(response) { + if (response && response.pause) { + options.setStatus(id, qq.status.PAUSED); + handler.pause(id); + connectionManager.free(id); + } else { + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + } + }, function(error) { + error = error || {}; + log(id + " upload start aborted due to rejected onUpload Promise - details: " + error, "error"); + if (!options.onAutoRetry(id, name, error.responseJSON || {})) { + var response = upload.normalizeResponse(error.responseJSON, false); + upload.cleanup(id, response); + } + }); }, start: function(id) { var blobToUpload = upload.getProxyOrBlob(id); @@ -3534,6 +3694,13 @@ isValid: function(id) { return handler.isValid(id); }, + hasResumeRecord: function(id) { + var key = handler.isValid(id) && handler._getLocalStorageId && handler._getLocalStorageId(id); + if (key) { + return !!localStorage.getItem(key); + } + return false; + }, getResumableFilesData: function() { if (handler.getResumableFilesData) { return handler.getResumableFilesData(); @@ -3553,6 +3720,9 @@ } return false; }, + isAttemptingResume: function(id) { + return !!handler.isAttemptingResume && handler.isAttemptingResume(id); + }, isResumable: function(id) { return !!handler.isResumable && handler.isResumable(id); } @@ -3743,7 +3913,19 @@ }; qq.XhrUploadHandler = function(spec) { "use strict"; - var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log; + var handler = this, namespace = spec.options.namespace, proxy = spec.proxy, chunking = spec.options.chunking, getChunkSize = function(id) { + var fileState = handler._getFileState(id); + if (fileState.chunkSize) { + return fileState.chunkSize; + } else { + var chunkSize = chunking.partSize; + if (qq.isFunction(chunkSize)) { + chunkSize = chunkSize(id, getSize(id)); + } + fileState.chunkSize = chunkSize; + return chunkSize; + } + }, resume = spec.options.resume, chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking, resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, getEndpoint = proxy.getEndpoint, getDataByUuid = proxy.getDataByUuid, onUuidChanged = proxy.onUuidChanged, onProgress = proxy.onProgress, log = proxy.log, getCustomResumeData = proxy.getCustomResumeData; function abort(id) { qq.each(handler._getXhrs(id), function(xhrId, xhr) { var ajaxRequester = handler._getAjaxRequester(id, xhrId); @@ -3781,7 +3963,10 @@ }); qq.extend(this, { clearCachedChunk: function(id, chunkIdx) { - delete handler._getFileState(id).temp.cachedChunks[chunkIdx]; + var fileState = handler._getFileState(id); + if (fileState) { + delete fileState.temp.cachedChunks[chunkIdx]; + } }, clearXhr: function(id, chunkIdx) { var tempState = handler._getFileState(id).temp; @@ -3818,15 +4003,21 @@ if (uploadData.key) { data.key = uploadData.key; } + if (uploadData.customResumeData) { + data.customResumeData = uploadData.customResumeData; + } resumableFilesData.push(data); }); return resumableFilesData; }, + isAttemptingResume: function(id) { + return handler._getFileState(id).attemptingResume; + }, isResumable: function(id) { return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable; }, moveInProgressToRemaining: function(id, optInProgress, optRemaining) { - var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress, remaining = optRemaining || handler._getFileState(id).chunking.remaining; + var fileState = handler._getFileState(id) || {}, chunkingState = fileState.chunking || {}, inProgress = optInProgress || chunkingState.inProgress, remaining = optRemaining || chunkingState.remaining; if (inProgress) { log(qq.format("Moving these chunks from in-progress {}, to remaining.", JSON.stringify(inProgress))); inProgress.reverse(); @@ -3885,7 +4076,7 @@ return handler._getFileState(id).temp.ajaxRequesters[chunkIdx]; }, _getChunkData: function(id, chunkIndex) { - var chunkSize = chunking.partSize, fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); + var chunkSize = getChunkSize(id), fileSize = getSize(id), fileOrBlob = handler.getFile(id), startBytes = chunkSize * chunkIndex, endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, totalChunks = handler._getTotalChunks(id), cachedChunks = this._getFileState(id).temp.cachedChunks, blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes); cachedChunks[chunkIndex] = blob; return { part: chunkIndex, @@ -3905,8 +4096,11 @@ }; }, _getLocalStorageId: function(id) { - var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = chunking.partSize, endpoint = getEndpoint(id); - return qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + var formatVersion = "5.0", name = getName(id), size = getSize(id), chunkSize = getChunkSize(id), endpoint = getEndpoint(id), customKeys = resume.customKeys(id), localStorageId = qq.format("qq{}resume{}-{}-{}-{}-{}", namespace, formatVersion, name, size, chunkSize, endpoint); + customKeys.forEach(function(key) { + localStorageId += "-" + key; + }); + return localStorageId; }, _getMimeType: function(id) { return handler.getFile(id).type; @@ -3916,7 +4110,7 @@ }, _getTotalChunks: function(id) { if (chunking) { - var fileSize = getSize(id), chunkSize = chunking.partSize; + var fileSize = getSize(id), chunkSize = getChunkSize(id); return Math.ceil(fileSize / chunkSize); } }, @@ -3974,6 +4168,7 @@ state.key = persistedData.key; state.chunking = persistedData.chunking; state.loaded = persistedData.loaded; + state.customResumeData = persistedData.customResumeData; state.attemptingResume = true; handler.moveInProgressToRemaining(id); } @@ -3983,6 +4178,7 @@ _maybePersistChunkedState: function(id) { var state = handler._getFileState(id), localStorageId, persistedData; if (resumeEnabled && handler.isResumable(id)) { + var customResumeData = getCustomResumeData(id); localStorageId = handler._getLocalStorageId(id); persistedData = { name: getName(id), @@ -3993,6 +4189,9 @@ loaded: state.loaded, lastUpdated: Date.now() }; + if (customResumeData) { + persistedData.customResumeData = customResumeData; + } try { localStorage.setItem(localStorageId, JSON.stringify(persistedData)); } catch (error) { @@ -4049,10 +4248,12 @@ }, _shouldChunkThisFile: function(id) { var state = handler._getFileState(id); - if (!state.chunking) { - handler.reevaluateChunking(id); + if (state) { + if (!state.chunking) { + handler.reevaluateChunking(id); + } + return state.chunking.enabled; } - return state.chunking.enabled; } }); }; @@ -5579,18 +5780,24 @@ "use strict"; var handler = this, getName = proxy.getName, getSize = proxy.getSize, getUuid = proxy.getUuid, log = proxy.log, multipart = spec.forceMultipart || spec.paramsInBody, addChunkingSpecificParams = function(id, params, chunkData) { var size = getSize(id), name = getName(id); - params[spec.chunking.paramNames.partIndex] = chunkData.part; - params[spec.chunking.paramNames.partByteOffset] = chunkData.start; - params[spec.chunking.paramNames.chunkSize] = chunkData.size; - params[spec.chunking.paramNames.totalParts] = chunkData.count; - params[spec.totalFileSizeName] = size; - if (multipart) { + if (!spec.omitDefaultParams) { + params[spec.chunking.paramNames.partIndex] = chunkData.part; + params[spec.chunking.paramNames.partByteOffset] = chunkData.start; + params[spec.chunking.paramNames.chunkSize] = chunkData.size; + params[spec.chunking.paramNames.totalParts] = chunkData.count; + params[spec.totalFileSizeName] = size; + } + if (multipart && !spec.omitDefaultParams) { params[spec.filenameParam] = name; } }, allChunksDoneRequester = new qq.traditional.AllChunksDoneAjaxRequester({ cors: spec.cors, endpoint: spec.chunking.success.endpoint, - log: log + headers: spec.chunking.success.headers, + jsonPayload: spec.chunking.success.jsonPayload, + log: log, + method: spec.chunking.success.method, + params: spec.chunking.success.params }), createReadyStateChangedHandler = function(id, xhr) { var promise = new qq.Promise(); xhr.onreadystatechange = function() { @@ -5612,7 +5819,7 @@ params[spec.chunking.paramNames.totalParts] = handler._getTotalChunks(id); return params; }, isErrorUploadResponse = function(xhr, response) { - return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || !response.success || response.reset; + return qq.indexOf([ 200, 201, 202, 203, 204 ], xhr.status) < 0 || spec.requireSuccessJson && !response.success || response.reset; }, onUploadOrChunkComplete = function(id, xhr) { var response; log("xhr - server response received for " + id); @@ -5628,7 +5835,7 @@ log(qq.format("Received response status {} with body: {}", xhr.status, xhr.responseText)); response = qq.parseJson(xhr.responseText); } catch (error) { - upload && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); + upload && spec.requireSuccessJson && log("Error when attempting to parse xhr response text (" + error.message + ")", "error"); } return response; }, sendChunksCompleteRequest = function(id) { @@ -5639,17 +5846,32 @@ promise.failure(parseResponse(false, xhr), xhr); }); return promise; - }, setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { - var formData = new FormData(), method = spec.method, endpoint = spec.endpointStore.get(id), name = getName(id), size = getSize(id); - params[spec.uuidName] = getUuid(id); - params[spec.filenameParam] = name; - if (multipart) { - params[spec.totalFileSizeName] = size; - } - if (!spec.paramsInBody) { - if (!multipart) { + }, setParamsAndGetEntityToSend = function(entityToSendParams) { + var fileOrBlob = entityToSendParams.fileOrBlob; + var id = entityToSendParams.id; + var xhr = entityToSendParams.xhr; + var xhrOverrides = entityToSendParams.xhrOverrides || {}; + var customParams = entityToSendParams.customParams || {}; + var defaultParams = entityToSendParams.params || {}; + var xhrOverrideParams = xhrOverrides.params || {}; + var params; + var formData = multipart ? new FormData() : null, method = xhrOverrides.method || spec.method, endpoint = xhrOverrides.endpoint || spec.endpointStore.get(id), name = getName(id), size = getSize(id); + if (spec.omitDefaultParams) { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + } else { + params = qq.extend({}, customParams); + qq.extend(params, xhrOverrideParams); + qq.extend(params, defaultParams); + params[spec.uuidName] = getUuid(id); + params[spec.filenameParam] = name; + if (multipart) { + params[spec.totalFileSizeName] = size; + } else if (!spec.paramsInBody) { params[spec.inputName] = name; } + } + if (!spec.paramsInBody) { endpoint = qq.obj2url(params, endpoint); } xhr.open(method, endpoint, true); @@ -5664,42 +5886,74 @@ return formData; } return fileOrBlob; - }, setUploadHeaders = function(id, xhr) { - var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + }, setUploadHeaders = function(headersOptions) { + var headerOverrides = headersOptions.headerOverrides; + var id = headersOptions.id; + var xhr = headersOptions.xhr; + if (headerOverrides) { + qq.each(headerOverrides, function(headerName, headerValue) { + xhr.setRequestHeader(headerName, headerValue); + }); + } else { + var extraHeaders = spec.customHeaders.get(id), fileOrBlob = handler.getFile(id); + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + if (!multipart) { + xhr.setRequestHeader("Content-Type", "application/octet-stream"); + xhr.setRequestHeader("X-Mime-Type", fileOrBlob.type); + } + qq.each(extraHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); } - qq.each(extraHeaders, function(name, val) { - xhr.setRequestHeader(name, val); - }); }; qq.extend(this, { - uploadChunk: function(id, chunkIdx, resuming) { - var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), size = getSize(id), promise, toSend, params; + uploadChunk: function(uploadChunkParams) { + var id = uploadChunkParams.id; + var chunkIdx = uploadChunkParams.chunkIdx; + var overrides = uploadChunkParams.overrides || {}; + var resuming = uploadChunkParams.resuming; + var chunkData = handler._getChunkData(id, chunkIdx), xhr = handler._createXhr(id, chunkIdx), promise, toSend, customParams, params = {}; promise = createReadyStateChangedHandler(id, xhr); handler._registerProgressHandler(id, chunkIdx, chunkData.size); - params = spec.paramsStore.get(id); + customParams = spec.paramsStore.get(id); addChunkingSpecificParams(id, params, chunkData); if (resuming) { params[spec.resume.paramNames.resuming] = true; } - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setUploadHeaders(id, xhr); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: chunkData.blob, + id: id, + customParams: customParams, + params: params, + xhr: xhr, + xhrOverrides: overrides + }); + setUploadHeaders({ + headerOverrides: overrides.headers, + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; }, uploadFile: function(id) { - var fileOrBlob = handler.getFile(id), promise, xhr, params, toSend; + var fileOrBlob = handler.getFile(id), promise, xhr, customParams, toSend; xhr = handler._createXhr(id); handler._registerProgressHandler(id); promise = createReadyStateChangedHandler(id, xhr); - params = spec.paramsStore.get(id); - toSend = setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id); - setUploadHeaders(id, xhr); + customParams = spec.paramsStore.get(id); + toSend = setParamsAndGetEntityToSend({ + fileOrBlob: fileOrBlob, + id: id, + customParams: customParams, + xhr: xhr + }); + setUploadHeaders({ + id: id, + xhr: xhr + }); xhr.send(toSend); return promise; } @@ -5715,6 +5969,7 @@ qq.override(this, function(super_) { return { finalizeChunks: function(id) { + proxy.onFinalizing(id); if (spec.chunking.success.endpoint) { return sendChunksCompleteRequest(id); } else { @@ -5726,24 +5981,29 @@ }; qq.traditional.AllChunksDoneAjaxRequester = function(o) { "use strict"; - var requester, method = "POST", options = { + var requester, options = { cors: { allowXdr: false, expected: false, sendCredentials: false }, endpoint: null, - log: function(str, level) {} + log: function(str, level) {}, + method: "POST" }, promises = {}, endpointHandler = { get: function(id) { + if (qq.isFunction(options.endpoint)) { + return options.endpoint(id); + } return options.endpoint; } }; qq.extend(options, o); requester = qq.extend(this, new qq.AjaxRequester({ acceptHeader: "application/json", - validMethods: [ method ], - method: method, + contentType: options.jsonPayload ? "application/json" : "application/x-www-form-urlencoded", + validMethods: [ options.method ], + method: options.method, endpointStore: endpointHandler, allowXRequestedWithAndCacheControl: false, cors: options.cors, @@ -5763,7 +6023,7 @@ var promise = new qq.Promise(); options.log("Submitting All Chunks Done request for " + id); promises[id] = promise; - requester.initTransport(id).withParams(params).withHeaders(headers).send(xhr); + requester.initTransport(id).withParams(options.params(id) || params).withHeaders(options.headers(id) || headers).send(xhr); return promise; } }); @@ -5790,12 +6050,7 @@ var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { - var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); - fullPath = fullPath.substr(0, indexOfNameInFullPath); - if (fullPath.charAt(0) === "/") { - fullPath = fullPath.substr(1); - } - file.qqPath = fullPath; + file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { @@ -5823,6 +6078,14 @@ } return parseEntryPromise; } + function extractDirectoryPath(entry) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + return fullPath; + } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { @@ -5910,9 +6173,6 @@ return fileDrag; } function leavingDocumentOut(e) { - if (qq.firefox()) { - return !e.relatedTarget; - } if (qq.safari()) { return e.x < 0 || e.y < 0; } @@ -5952,8 +6212,10 @@ maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { - e.preventDefault(); - maybeHideDropZones(); + if (isFileDrag(e)) { + e.preventDefault(); + maybeHideDropZones(); + } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } @@ -5978,6 +6240,8 @@ }); } }); + this._testing = {}; + this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; @@ -6030,7 +6294,7 @@ } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; - return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { @@ -6113,6 +6377,8 @@ return element; } }); + this._testing = {}; + this._testing.isValidFileDrag = isValidFileDrag; }; (function() { "use strict"; @@ -6841,7 +7107,7 @@ dropProcessing: "qq-drop-processing-selector", dropProcessingSpinner: "qq-drop-processing-spinner-selector", thumbnail: "qq-thumbnail-selector" - }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateHtml, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { + }, previewGeneration = {}, cachedThumbnailNotAvailableImg = new qq.Promise(), cachedWaitingForThumbnailImg = new qq.Promise(), log, isEditElementsExist, isRetryElementExist, templateDom, container, fileList, showThumbnails, serverScale, cacheThumbnailPlaceholders = function() { var notAvailableUrl = options.placeholders.thumbnailNotAvailable, waitingUrl = options.placeholders.waitingForThumbnail, spec = { maxSize: thumbnailMaxSize, scale: serverScale @@ -6973,7 +7239,7 @@ }); return notAvailableImgPlacement; }, parseAndGetTemplate = function() { - var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListHtml, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; + var scriptEl, scriptHtml, fileListNode, tempTemplateEl, fileListEl, defaultButton, dropArea, thumbnail, dropProcessing, dropTextEl, uploaderEl; log("Parsing template"); if (options.templateIdOrEl == null) { throw new Error("You MUST specify either a template element or ID!"); @@ -7037,15 +7303,15 @@ if (fileListNode == null) { throw new Error("Could not find the file list container in the template!"); } - fileListHtml = fileListNode.innerHTML; + fileListEl = fileListNode.children[0].cloneNode(true); fileListNode.innerHTML = ""; if (tempTemplateEl.getElementsByTagName("DIALOG").length) { document.createElement("dialog"); } log("Template parsing complete"); return { - template: qq.trimStr(tempTemplateEl.innerHTML), - fileTemplate: qq.trimStr(fileListHtml) + template: tempTemplateEl, + fileTemplate: fileListEl }; }, prependFile = function(el, index, fileList) { var parentEl = fileList, beforeEl = parentEl.firstChild; @@ -7151,13 +7417,13 @@ } container = options.containerEl; showThumbnails = options.imageGenerator !== undefined; - templateHtml = parseAndGetTemplate(); + templateDom = parseAndGetTemplate(); cacheThumbnailPlaceholders(); qq.extend(this, { render: function() { log("Rendering template in DOM."); generatedThumbnails = 0; - container.innerHTML = templateHtml.template; + container.appendChild(templateDom.template.cloneNode(true)); hide(getDropProcessing()); this.hideTotalProgress(); fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list); @@ -7169,6 +7435,7 @@ container.appendChild(cantRenderEl); }, reset: function() { + container.innerHTML = ""; this.render(); }, clearFiles: function() { @@ -7178,7 +7445,7 @@ isCancelDisabled = true; }, addFile: function(id, name, prependInfo, hideForever, batch) { - var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; + var fileEl = templateDom.fileTemplate.cloneNode(true), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), fileContainer = batch ? fileBatch.content : fileList, thumb; if (batch) { fileBatch.map[id] = fileEl; } diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map index d573d8f94..4ab51c04f 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","fileError","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA,SCCT,SAASC,GACN,YAIA,SAASC,GAAKC,GACV,GAAIC,GAAcC,EAAmBF,OACjCG,EAAsBC,EAAuBH,EAKjD,OAHAI,GAASF,GACTG,EAAaL,EAAaE,GAEnBI,EAGX,QAASH,GAAuBI,GAC5B,GAAIC,GAAeC,EAAa,gBAC5BC,EAAYD,EAAa,eAG7B,OAAID,IAGAA,EAAeA,EAAaG,OAAO,GAAGC,cAAgBJ,EAAaK,MAAM,GAAGC,cAExEJ,EACO,GAAIK,IAAGL,GAAW,eAAiBF,GAAcD,GAGrD,GAAIQ,IAAG,eAAiBP,GAAcD,IAGzCG,EACO,GAAIK,IAAGL,GAAWM,aAAaT,GAGnC,GAAIQ,IAAGC,aAAaT,GAInC,QAASU,GAAUC,EAAKC,GACpB,GAAIC,GAAOd,EAAIc,KAAK,eAEpB,OAAID,IACaE,SAATD,IACAA,MAEJA,EAAKF,GAAOC,EACZb,EAAIc,KAAK,eAAgBA,GAJzB,QAOaC,SAATD,EACO,KAEJA,EAAKF,GAMpB,QAASd,GAASkB,GACd,MAAOL,GAAU,WAAYK,GAGjC,QAASb,GAAac,EAAQC,GAC1B,MAAOP,GAAUM,EAAQC,GAK7B,QAASnB,GAAaoB,EAAiBvB,GACnC,GAAIwB,GAAYD,EAAgBC,YAEhC7B,GAAE8B,KAAKzB,EAAoB0B,SAASF,UAAW,SAASG,EAAMC,GAC1D,GAAIC,GAAMC,CAEVD,GAAO,WAAWE,KAAKJ,GAAM,GAC7BE,EAAOA,EAAKG,UAAU,EAAG,GAAGpB,cAAgBiB,EAAKG,UAAU,GAC3DF,EAAsB1B,EAEtBoB,EAAUG,GAAQ,WACd,GAEIM,GAAyBC,EAFzBC,EAAeC,MAAMC,UAAU1B,MAAM2B,KAAKC,WAC1CC,IAGJ7C,GAAE8B,KAAKU,EAAc,SAASM,EAAKC,GAC/BF,EAAgBG,KAAKC,EAAkBF,MAG3CT,EAA0BL,EAAkBiB,MAAMC,KAAMX,EAExD,KACID,EAA4BJ,EAAoBiB,eAAelB,EAAMW,GAEzE,MAAOQ,GACHnC,GAAGoC,IAAI,uDAAyDD,EAAME,QAAS,SAInF,MAA+B,OAA3BjB,EACOA,EAEJC,KAIflC,EAAoB0B,SAASF,UAAYA,EAI7C,QAASzB,GAAmBoD,EAAQC,GAChC,GAAIC,GAASC,CAgDb,IA5CQD,EAFKlC,SAATiC,EAC4B,UAAxBD,EAAO7C,cACKiD,QAASnD,EAAI,OAOnBgD,EAGdzD,EAAE8B,KAAK0B,EAAQ,SAASxB,EAAMV,GACtBtB,EAAE6D,QAAQ7B,EAAM8B,IAAkB,EAClClD,EAAaoB,EAAMV,GAEdA,YAAetB,GACpB0D,EAAQ1B,GAAQV,EAAI,GAEftB,EAAE+D,cAAczC,IACrBoC,EAAQ1B,MACR5B,EAAmBkB,EAAKoC,EAAQ1B,KAE3BhC,EAAEgE,QAAQ1C,IACfqC,KACA3D,EAAE8B,KAAKR,EAAK,SAASwB,EAAKmB,GACtB,GAAIC,KAEAD,aAAoBjE,GACpBA,EAAEmE,MAAMR,EAAWM,GAEdjE,EAAE+D,cAAcE,IACrB7D,EAAmB6D,EAAUC,GAC7BP,EAAUX,KAAKkB,IAGfP,EAAUX,KAAKiB,KAGvBP,EAAQ1B,GAAQ2B,GAGhBD,EAAQ1B,GAAQV,IAIXE,SAATiC,EACA,MAAOC,GAIf,QAASU,GAAeC,GACpB,MAA2B,WAApBrE,EAAEsE,KAAKD,KACTA,EAAQE,MAAM,OACS/C,SAAxBjB,IAAW8D,GAKnB,QAASG,GAAgBH,GACrB,GAEII,GAFAC,KACAC,EAAWlC,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAOrD,OAJAxC,GAAmBuE,EAAUD,GAE7BD,EAASlE,IAAW8D,GAASnB,MAAM3C,IAAYmE,GAExCzB,EAAkBwB,GAI7B,QAASxB,GAAkB3B,GACvB,GAAIsD,GAAiBtD,CAUrB,OANW,OAAPA,GAA8B,gBAARA,IACL,IAAjBA,EAAIuD,UAAmC,IAAjBvD,EAAIuD,WAAmBvD,EAAIwD,YAEjDF,EAAiB5E,EAAEsB,IAGhBsD,EAlMX,GAAInE,GACAqD,GAAiB,eAAgB,eAoMrC9D,GAAE+E,GAAGC,aAAe,SAASC,GACzB,GAAIC,GAAO/B,KAAMgC,EAAWvC,UAAWwC,IAoBvC,OAlBAjC,MAAKrB,KAAK,SAASuD,EAAOC,GAGtB,GAFA7E,EAAMT,EAAEsF,GAEJ/E,KAAc6D,EAAea,IAG7B,GAFAG,EAAQpC,KAAKwB,EAAgBtB,MAAMgC,EAAMC,IAErB,IAAhBD,EAAKK,OACL,OAAO,MAGsB,gBAArBN,IAAkCA,EAI9CjF,EAAEqD,MAAM,UAAa4B,EAAmB,0CAHxChF,EAAKiD,MAAMgC,EAAMC,KAOF,IAAnBC,EAAQG,OACDH,EAAQ,GAEVA,EAAQG,OAAS,EACfH,EAGJjC,OAGbqC,QCtOD,SAASxF,GACN,YAIA,SAASC,GAAKC,GACLA,IACDA,MAGJA,EAAQuF,kBAAoBhF,EAC5B,IAAIN,GAAcC,EAAmBF,EAIrC,OAHAM,GAAaL,GACbuF,EAAI,GAAIxE,IAAGyE,YAAYxF,IAEhBM,EAGX,QAASW,GAAUC,EAAKC,GACpB,GAAIC,GAAOd,EAAIc,KAAKqE,EAEpB,OAAItE,IACaE,SAATD,IACAA,MAEJA,EAAKF,GAAOC,EACZb,EAAIc,KAAKqE,EAAarE,GAJtB,QAOaC,SAATD,EACO,KAEJA,EAAKF,GAIpB,QAASqE,GAAIjE,GACT,MAAOL,GAAU,cAAeK,GAGpC,QAASjB,GAAaoB,GAClB,GAAIC,GAAYD,EAAgBC,YAEhC7B,GAAE8B,KAAK,GAAIZ,IAAGyE,YAAY9D,UAAa,SAASG,EAAM6D,GAClD,GACIC,GADA5D,EAAOF,CAGX8D,GAAcrF,EAEdoB,EAAUG,GAAQ,WACd,GAAI+D,GAAOtD,MAAMC,UAAU1B,MAAM2B,KAAKC,WAClCoD,EAAsBF,EAAY1C,eAAelB,EAAM6D,EAE3D,OAAOC,MAMnB,QAAS5F,GAAmBoD,EAAQC,GAChC,GAAIC,GAASC,CAkCb,IA/BID,EADSlC,SAATiC,KAIUA,EAGdzD,EAAE8B,KAAK0B,EAAQ,SAASxB,EAAMV,GACtBA,YAAetB,GACf0D,EAAQ1B,GAAQV,EAAI,GAEftB,EAAE+D,cAAczC,IACrBoC,EAAQ1B,MACR5B,EAAmBkB,EAAKoC,EAAQ1B,KAE3BhC,EAAEgE,QAAQ1C,IACfqC,KACA3D,EAAE8B,KAAKR,EAAK,SAASwB,EAAKmB,GAClBA,YAAoBjE,GACpBA,EAAEmE,MAAMR,EAAWM,GAGnBN,EAAUX,KAAKiB,KAGvBP,EAAQ1B,GAAQ2B,GAGhBD,EAAQ1B,GAAQV,IAIXE,SAATiC,EACA,MAAOC,GAIf,QAASU,GAAeC,GACpB,MAA2B,WAApBrE,EAAEsE,KAAKD,IACE,YAAZA,GACmB7C,SAAnBkE,IAAMrB,GAGd,QAASG,GAAgBH,GACrB,GAAIK,MAAkBC,EAAWlC,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAEvE,OADAxC,GAAmBuE,EAAUD,GACtBgB,IAAMrB,GAASnB,MAAMwC,IAAOhB,GA1GvC,GACIjE,GADAmF,EAAc,iBA6GlB5F,GAAE+E,GAAGkB,gBAAkB,SAAShB,GAC5B,GAAIC,GAAO/B,KAAMgC,EAAWvC,UAAWwC,IAoBvC,OAlBAjC,MAAKrB,KAAK,SAASuD,EAAOC,GAGtB,GAFA7E,EAAMT,EAAEsF,GAEJI,KAAStB,EAAea,IAGxB,GAFAG,EAAQpC,KAAKwB,EAAgBtB,MAAMgC,EAAMC,IAErB,IAAhBD,EAAKK,OACL,OAAO,MAGsB,gBAArBN,IAAkCA,EAI9CjF,EAAEqD,MAAM,UAAa4B,EAAmB,kDAHxChF,EAAKiD,MAAMgC,EAAMC,KAOF,IAAnBC,EAAQG,OACDH,EAAQ,GAEVA,EAAQG,OAAS,EACfH,EAGJjC,OAGbqC,OC7IF,IAAItE,IAAK,SAAS0C,GACd,YAEA,QACIsC,KAAM,WAEF,MADAtC,GAAQuC,MAAMC,QAAU,OACjBjD,MAIXkD,OAAQ,SAAS/B,EAAMS,GAMnB,MALInB,GAAQ0C,iBACR1C,EAAQ0C,iBAAiBhC,EAAMS,GAAI,GAC5BnB,EAAQ2C,aACf3C,EAAQ2C,YAAY,KAAOjC,EAAMS,GAE9B,WACH7D,GAAG0C,GAAS4C,OAAOlC,EAAMS,KAIjCyB,OAAQ,SAASlC,EAAMS,GAMnB,MALInB,GAAQ6C,oBACR7C,EAAQ6C,oBAAoBnC,EAAMS,GAAI,GAC/BnB,EAAQ2C,aACf3C,EAAQ8C,YAAY,KAAOpC,EAAMS,GAE9B5B,MAGXwD,SAAU,SAASC,GAKf,QAAKA,IAKDhD,IAAYgD,IAIZhD,EAAQ+C,SACD/C,EAAQ+C,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwBjD,OAOrDkD,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAalD,EAASmD,GACnC5D,MAGX8D,OAAQ,WAEJ,MADArD,GAAQoD,WAAWE,YAAYtD,GACxBT,MAOXgE,IAAK,SAASC,GAEV,GAAqB,MAAjBxD,EAAQuC,MACR,KAAM,IAAIjF,IAAGmG,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1B1D,GAAQuC,MAAMmB,SAAqD,mBAArB1D,GAAe,UACpEwD,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9EpG,GAAGwG,OAAO9D,EAAQuC,MAAOiB,GAElBjE,MAGXwE,SAAU,SAASzF,EAAM0F,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAU5F,EAAO,QACrC,OAAO2F,GAAGE,KAAKnE,EAAQoE,eAAiBJ,IAAkBC,EAAGE,KAAKnE,EAAQoD,WAAWgB,aAGzFC,SAAU,SAAS/F,GAIf,MAHKhB,IAAG0C,GAAS+D,SAASzF,KACtB0B,EAAQoE,WAAa,IAAM9F,GAExBiB,MAGX+E,YAAa,SAAShG,GAClB,GAAI2F,GAAK,GAAIC,QAAO,QAAU5F,EAAO,QAErC,OADA0B,GAAQoE,UAAYpE,EAAQoE,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtEhF,MAGXiF,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASzE,EAAQ4E,cACV5E,EAAQ4E,cAAc,IAAMR,GAE9BpE,EAAQ6E,iBACN7E,EAAQ6E,iBAAiB,IAAMT,IAG1CM,EAAa1E,EAAQ8E,qBAAqB,KAE1CxH,GAAGY,KAAKwG,EAAY,SAASxF,EAAKxB,GAC1BJ,GAAGI,GAAKqG,SAASK,IACjBO,EAAOvF,KAAK1B,KAGb+G,EAAQE,EAAO,GAAKA,IAG/BI,gBAAiB,SAASX,GACtB,MAAO9G,IAAG0C,GAASwE,WAAWJ,GAAW,IAG7CY,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQjF,EAAQkF,WAEbD,GACoB,IAAnBA,EAAMhE,UACN+D,EAAS5F,KAAK6F,GAElBA,EAAQA,EAAME,WAGlB,OAAOH,IAGXI,QAAS,SAASC,GAGd,MAFArF,GAAQsF,UAAYD,EACpBrF,EAAQuF,YAAcF,EACf9F,MAGXiG,UAAW,WACP,MAAOlI,IAAG0C,GAASoF,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAI3F,GAAQyF,eAEHzF,EAAQyF,aAAaC,IAKkC,MAArD,WAAalH,KAAKwB,EAAQ4F,aAAaF,KAG9CC,EAAU3F,EAAQ0F,GAEF9H,SAAZ+H,GAKiC,MAA9B,WAAanH,KAAKmH,QAMxC,WACG,YAEArI,IAAGuI,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAO1I,IAAG2I,cAAcH,EAAOI,UAAUH,EAAMC,KAGnD1I,GAAG2I,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAAS7I,EAAMoI,GACxB,GAAIU,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOpJ,GACZmJ,EAAYE,QAAQjB,IAGpB,GAAIkB,OAAMtJ,IAAQ+C,KAAMqF,IAyB3C,OAlBIM,GADAF,EAAQe,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKjB,EAAQe,MAAM,KAAK,IAGxBG,UAAUlB,EAAQe,MAAM,KAAK,IAI9CX,EAAaJ,EAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBd,EAAc,GAAIkB,aAAYjB,EAAW1E,QACzC2E,EAAW,GAAIiB,YAAWnB,GAC1B9I,GAAGY,KAAKmI,EAAY,SAASnH,EAAKsI,GAC9BlB,EAASpH,GAAOsI,EAAUC,WAAW,KAGlCjB,EAAWJ,EAAaG,IAGnCjJ,GAAGoC,IAAM,SAASC,EAAS+H,GACnBhB,OAAOiB,UACFD,GAAmB,SAAVA,EAKNhB,OAAOiB,QAAQD,GACfhB,OAAOiB,QAAQD,GAAO/H,GAGtB+G,OAAOiB,QAAQjI,IAAI,IAAMgI,EAAQ,KAAO/H,GAR5C+G,OAAOiB,QAAQjI,IAAIC,KAc/BrC,GAAGsK,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAAS5G,UAAyD,oBAA7C6G,OAAOhJ,UAAUiJ,SAAShJ,KAAK8I,IAG5EvK,GAAG0K,WAAa,SAASH,GACrB,MAA6B,kBAAf,IASlBvK,GAAG8C,QAAU,SAAS6H,GAClB,MAAiD,mBAA1CH,OAAOhJ,UAAUiJ,SAAShJ,KAAKkJ,IACjCA,GAASvB,OAAOY,aAAeW,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBb,aAIrFhK,GAAG8K,WAAa,SAASC,GACrB,MAAyD,kCAAlDP,OAAOhJ,UAAUiJ,SAAShJ,KAAKsJ,IAK1C/K,GAAGgL,WAAa,SAASC,GACrB,MAAyD,sBAAlDT,OAAOhJ,UAAUiJ,SAAShJ,KAAKwJ,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CnL,GAAGoL,SAAW,SAASC,GACnB,MAAuD,oBAAhDb,OAAOhJ,UAAUiJ,SAAShJ,KAAK4J,IAG1CrL,GAAGsL,QAAU,SAASC,GAClB,MAAIC,QAAOhK,UAAUiK,KACVF,EAAOE,OAGXF,EAAOtE,QAAQ,aAAc,KAOxCjH,GAAG0L,OAAS,SAASC,GAEjB,GAAI9G,GAAQtD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,GAC9CkK,EAASD,EACTE,EAAmBD,EAAO/B,QAAQ,KAetC,OAbA7J,IAAGY,KAAKiE,EAAM,SAASjD,EAAKxB,GACxB,GAAI0L,GAAYF,EAAOzK,UAAU,EAAG0K,GAChCE,EAAWH,EAAOzK,UAAU0K,EAAmB,EAMnD,IAJAD,EAASE,EAAY1L,EAAM2L,EAC3BF,EAAmBD,EAAO/B,QAAQ,KAAMgC,EAAmBzL,EAAIiE,QAG3DwH,EAAmB,EACnB,OAAO,IAIRD,GAGX5L,GAAGgM,OAAS,SAASC,GACjB,MAAO7C,QAAO8C,MAAsD,kBAA9C1B,OAAOhJ,UAAUiJ,SAAShJ,KAAKwK,IAGzDjM,GAAGmM,WAAa,SAASC,GACrB,MAAOhD,QAAOiD,UAA8D,sBAAlD7B,OAAOhJ,UAAUiJ,SAAShJ,KAAK2K,IAG7DpM,GAAGsM,cAAgB,SAASC,GACxB,MAAOvM,IAAGgM,OAAOO,IAAqBvM,GAAGwM,QAAQD,IAGrDvM,GAAGwM,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAASvJ,GACxB,GAAIwJ,GAAiBxJ,EAAKrD,aAE1B,OAAI2M,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAIxD,OAAOyD,kBAC4C,8BAA/CrC,OAAOhJ,UAAUiJ,SAAShJ,KAAKgL,IAC3BA,EAAWrJ,MAAQuJ,EAAaF,EAAWrJ,WAKnDqJ,EAAWK,SAC8B,UAArCL,EAAWK,QAAQ/M,eACf0M,EAAWrJ,MAAQuJ,EAAaF,EAAWrJ,QAS3DpD,GAAG+M,OAAS,SAASC,GACjB,GAAI5D,OAAOO,MAAsD,kBAA9Ca,OAAOhJ,UAAUiJ,SAAShJ,KAAKuL,GAC9C,OAAO,GAIfhN,GAAGiN,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAM9J,KAAO,OAGU9C,SAAnB4M,EAAMG,UACc,mBAATnB,OACa,mBAAboB,WACoC,mBAAnCtN,IAAGuN,oBAAqBC,QAI5CxN,GAAGuN,kBAAoB,WACnB,GAAInE,OAAOqE,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOvL,GAEH,MADAnC,IAAGoC,IAAI,wCAAyC,SACzC,OAIfpC,GAAG2N,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMxJ,OAAS,GAC5BuJ,EAAaC,MAAM,GAAGC,kBAG9B9N,GAAG+N,wBAA0B,WACzB,OAAQ/N,GAAGgO,gBACPhO,GAAGiN,yBACuB3M,SAAzB4L,KAAK1K,UAAU1B,OAAsDQ,SAA/B4L,KAAK1K,UAAUyM,aAAyD3N,SAA5B4L,KAAK1K,UAAU0M,WAG1GlO,GAAGmO,UAAY,SAASC,EAAYC,EAAOC,GACvC,GAAIC,GAASH,EAAWtO,OAASsO,EAAWF,UAAYE,EAAWH,WAEnE,OAAOM,GAAO9M,KAAK2M,EAAYC,EAAOC,IAG1CtO,GAAGwO,iBAAmB,SAAS5D,GAC3B,GAAI6D,GAAa,GACbC,EAAQ,GAAIzE,YAAWW,EAY3B,OAVA5K,IAAGY,KAAK8N,EAAO,SAAS9M,EAAK+M,GACzB,GAAIC,GAAeD,EAAIlE,SAAS,GAE5BmE,GAAavK,OAAS,IACtBuK,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXzO,GAAG6O,cAAgB,SAASC,EAAMC,EAAa1K,GAC3C,GAAI2K,GAAchP,GAAGmO,UAAUW,EAAMC,EAAaA,EAAc1K,GAC5D4K,EAAa,GAAIC,YACjBC,EAAU,GAAInP,IAAGoP,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQtP,GAAGwO,iBAAiBS,EAAW5H,UAGnD4H,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGXnP,GAAGwG,OAAS,SAASW,EAAOuI,EAAQC,GAahC,MAZA3P,IAAGY,KAAK8O,EAAQ,SAAS5O,EAAMV,GACvBuP,GAAgB3P,GAAGsK,SAASlK,IACRE,SAAhB6G,EAAMrG,KACNqG,EAAMrG,OAEVd,GAAGwG,OAAOW,EAAMrG,GAAOV,GAAK,IAG5B+G,EAAMrG,GAAQV,IAIf+G,GAaXnH,GAAG4P,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACAzN,EAASwN,EAASC,EAUtB,OARA/P,IAAGY,KAAK0B,EAAQ,SAAS0N,EAAaC,GACN3P,SAAxBuP,EAAOG,KACPD,EAAOC,GAAeH,EAAOG,IAGjCH,EAAOG,GAAeC,IAGnBJ,GAMX7P,GAAG6J,QAAU,SAASqG,EAAKC,EAAKC,GAC5B,GAAIF,EAAIrG,QACJ,MAAOqG,GAAIrG,QAAQsG,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAI7L,MAMd,KAJI+L,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIXpQ,GAAGuQ,YAAc,WACb,MAAO,uCAAuCtJ,QAAQ,QAAS,SAASuJ,GAEpE,GAAIC,GAAoB,GAAhBnK,KAAKoK,SAAgB,EAAGC,EAAS,KAALH,EAAWC,EAAS,EAAJA,EAAU,CAC9D,OAAOE,GAAElG,SAAS,OAM1BzK,GAAG4Q,GAAK,WACJ,MAAOC,WAAUC,UAAUjH,QAAQ,WAAY,GAC3CgH,UAAUC,UAAUjH,QAAQ,cAAe,GAGnD7J,GAAG+Q,IAAM,WACL,MAAOF,WAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGgR,IAAM,WACL,MAAOH,WAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGiR,KAAO,WACN,MAAOJ,WAAUC,UAAUjH,QAAQ,cAAe,GAGtD7J,GAAGkR,KAAO,WACN,MAAOlR,IAAG4Q,MAAQC,UAAUC,UAAUjH,QAAQ,YAAa,GAG/D7J,GAAGmR,KAAO,WACN,MAAON,WAAUC,UAAUjH,QAAQ,SAAW,GAGlD7J,GAAGoR,OAAS,WACR,MAA4B9Q,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,YAAa,GAGnF7J,GAAGsR,OAAS,WACR,MAA4BhR,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,aAAc,GAGpF7J,GAAGuR,MAAQ,WACP,MAA4BjR,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,YAAa,GAGnF7J,GAAGwR,QAAU,WACT,OAASxR,GAAGmR,SAAWnR,GAAGkR,QAAUL,UAAUC,UAAUjH,QAAQ,cAAe,GAA2BvJ,SAArBuQ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrIrR,GAAGyR,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrB1R,GAAG2R,QAAU,WACT,MAAOd,WAAUC,UAAU/Q,cAAc8J,QAAQ,cAAe,GAKpE7J,GAAGgO,aAAe,WACd,MAAOhO,IAAG2R,WAAad,UAAUC,UAAU/Q,cAAc8J,QAAQ,UAAY,GAGjF7J,GAAG4R,KAAO,WACN,MAAO5R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAGjE7J,GAAG8R,KAAO,WACN,MAAO9R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAGjE7J,GAAG+R,KAAO,WACN,MAAO/R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAIjE7J,GAAGgS,OAAS,WACR,MAAOhS,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,eAAgB,GAGnE7J,GAAG6R,IAAM,WAEL,MAAOhB,WAAUC,UAAUjH,QAAQ,WAAY,GACxCgH,UAAUC,UAAUjH,QAAQ,WAAY,GACxCgH,UAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGiS,UAAY,WACX,MAAOjS,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,YAAa,GAGhE7J,GAAGkS,UAAY,WACX,MAAOlS,IAAG6R,QAAU7R,GAAGiS,aAAepB,UAAUC,UAAUjH,QAAQ,aAAc,GAGpF7J,GAAGmS,iBAAmB,WAClB,MAAOnS,IAAG6R,QAAU7R,GAAGiS,cAAgBjS,GAAGkS,aAM9ClS,GAAGoS,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxBtS,GAAGuS,UAAa,WACZ,GAAIC,GAAMrF,SAASC,cAAc,MACjC,OAAO,UAASqF,GACZD,EAAIE,UAAYD,CAChB,IAAI/P,GAAU8P,EAAI5K,UAElB,OADA4K,GAAIxM,YAAYtD,GACTA,MAKf1C,GAAGY,KAAO,SAAS+R,EAAcC,GAC7B,GAAIC,GAAYtP,CAEhB,IAAIoP,EAEA,GAAIvJ,OAAO0J,SAAWH,EAAa9H,cAAgBzB,OAAO0J,QACtD,IAAKD,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASD,EAAaxS,IAAI0S,GAAaF,EAAaI,QAAQJ,EAAaxS,IAAI0S,KAClFtP,KAAW,GAFoCsP,SAStD,IAAI7S,GAAG8C,QAAQ6P,IAAiB3S,GAAG8K,WAAW6H,IAAiB3S,GAAGgL,WAAW2H,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASC,EAAYF,EAAaE,IACvCtP,KAAW,GAFoCsP,SAOtD,IAAI7S,GAAGoL,SAASuH,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASC,EAAYF,EAAa/S,OAAOiT,IAC9CtP,KAAW,GAFoCsP,SAQvD,KAAKA,IAAcF,GACf,GAAInI,OAAOhJ,UAAU8O,eAAe7O,KAAKkR,EAAcE,KACnDtP,EAASqP,EAASC,EAAYF,EAAaE,IACvCtP,KAAW,GACX,OASxBvD,GAAGgT,KAAO,SAASC,EAASC,GACxB,GAAIlT,GAAG0K,WAAWuI,GAAU,CACxB,GAAIpO,GAAQtD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAElD,OAAO,YACH,GAAIyR,GAAUnT,GAAGwG,UAAW3B,EAI5B,OAHInD,WAAU2C,SACV8O,EAAUA,EAAQC,OAAO7R,MAAMC,UAAU1B,MAAM2B,KAAKC,aAEjDuR,EAAQjR,MAAMkR,EAASC,IAItC,KAAM,IAAIhN,OAAM,wCAmBpBnG,GAAGqT,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQ1M,KAAK0M,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAW3R,KACa,gBAAZ8R,GACF5T,GAAGqT,QAAQO,EAASE,GAAU,GACe,sBAA5CtJ,OAAOhJ,UAAUiJ,SAAShJ,KAAKmS,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAK7M,KAAK0M,GAAU,MAAM1M,KAAK0M,GAAS,GAAK,IAAM,IAC7DE,EAAW3R,KAAKyR,GAChBE,EAAW3R,KAAK9B,GAAGqT,QAAQC,KACqB,mBAAxC9I,OAAOhJ,UAAUiJ,SAAShJ,KAAK6R,IAA8C,mBAARA,GAC7EtT,GAAGY,KAAK0S,EAAK,SAAS1R,EAAKxB,GACvBuT,EAAIvT,EAAKwB,KAEU,mBAAR0R,IAAiC,OAARA,GAAiC,gBAARA,GACjEtT,GAAGY,KAAK0S,EAAK,SAASxS,EAAMV,GACxBuT,EAAIvT,EAAKU,KAGb2S,EAAW3R,KAAKiS,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBzM,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7BjH,GAAGiU,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAI5G,WAGnBtN,GAAGY,KAAK0S,EAAK,SAASnT,EAAKC,GACvBD,EAAMgU,EAAeA,EAAe,IAAMhU,EAAM,IAAMA,EAElDH,GAAGsK,SAASlK,GACZJ,GAAGiU,aAAa7T,EAAK8T,EAAU/T,GAE1BH,GAAG0K,WAAWtK,GACnB8T,EAASzK,OAAOtJ,EAAKC,KAGrB8T,EAASzK,OAAOtJ,EAAKC,KAItB8T,GAGXlU,GAAGoU,WAAa,SAASd,EAAKe,GAC1B,GAAInH,EAeJ,OAbKmH,KACDA,EAAOlH,SAASC,cAAc,SAGlCpN,GAAGiU,aAAaX,GACZ7J,OAAQ,SAAStJ,EAAKC,GAClB8M,EAAQC,SAASC,cAAc,SAC/BF,EAAMoH,aAAa,OAAQnU,GAC3B+M,EAAMoH,aAAa,QAASlU,GAC5BiU,EAAKE,YAAYrH,MAIlBmH,GAOXrU,GAAGwU,UAAY,SAASC,MAEpB,MAAIrL,QAAOsL,MAAQ1U,GAAG0K,WAAWgK,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjCzU,GAAG6U,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAASzQ,OAAS0Q,IAIzD/U,GAAGkV,YAAc,SAASC,GAGtB,MAAInV,IAAGwM,QAAQ2I,GAEJA,EAAgBxK,MAAM1D,QAAQ,YAAa,IAE7CjH,GAAGgM,OAAOmJ,IACkB,OAA7BA,EAAgBC,UAAkD9U,SAA7B6U,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgBnU,MAM3BhB,GAAGqV,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIXrQ,OAAQ,WACJ,GAAIN,GAAOnD,SAEXO,MAAKyT,YAAY1V,GAAG6E,EAAK,IAAIM,OAAOnD,MAAMC,KAAMV,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,MAI1FgU,YAAa,SAASC,GAClBL,EAAUxT,KAAK6T,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAO5V,MAGY,mBAAX8V,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAU/V,GAGjBnB,OAAOmB,GAAKA,MCRnB,WACG,YAEAA,IAAGmG,MAAQ,SAAS9D,GAChBJ,KAAKI,QAAU,kBAAoBrC,GAAGgW,QAAU,KAAO3T,GAG3DrC,GAAGmG,MAAM3E,UAAY,GAAI2E,UCV7BnG,GAAGgW,QAAU,SCAbhW,GAAGiW,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAYhJ,SAASC,cAAc,SACnC+I,EAAU/S,KAAO,OACjBpD,GAAGmW,GAAWnR,OAEVmR,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQvW,GAAGsR,UAAYtR,GAAGuR,UAC+CjR,SAArEuQ,UAAUC,UAAUzN,MAAM,uCAIlC,QAASmT,KACL,OAAQxW,GAAGsR,UAAYtR,GAAGuR,UAC+CjR,SAArEuQ,UAAUC,UAAUzN,MAAM,uCAIlC,QAASoT,KACL,GAAIrN,OAAOqE,eAAgB,CACvB,GAAIiJ,GAAM1W,GAAGuN,mBAGb,OAA+BjN,UAAxBoW,EAAIC,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiCtW,UAA1B8I,OAAOyN,eAKlB,QAASC,KACL,QAAIL,KAIGG,IAGX,QAASG,KAEL,MAA2DzW,UAApD6M,SAASC,cAAc,SAAS4J,gBAG3C,QAASC,KACL,IACI,QAAS7N,OAAO8N,cAEZlX,GAAG0K,WAAWtB,OAAO8N,aAAaC,SAE1C,MAAOhV,GAEH,OAAO,GAIf,QAASiV,KACL,GAAIC,GAAOlK,SAASC,cAAc,OAElC,QAAQ,aAAeiK,IAAS,eAAiBA,IAAQ,UAAYA,MAChErX,GAAG2R,YAAc3R,GAAG6R,MAhG7B,GAAIyF,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAnCAd,GAAoBpB,IAEpBuB,EAA4BH,GAAqBtX,GAAGiN,uBAEpDsK,EAAyBE,IAA8BzX,GAAGgO,eAE1DwJ,EAAmBC,GAA6BL,IAEhDM,EAAqBF,GAAoBjB,IAEzCoB,EAAmBF,GAA6BzX,GAAG+N,0BAEnD6J,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BjB,IAEtDsB,EAAqBR,IAA6ChX,SAAvB8I,OAAOiP,aAA6BZ,GAE/EO,EAA4BvB,IAE5BsB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmDnX,SAAtB8I,OAAO8F,WAE5DkJ,EAA0B,WACtB,QAAIX,KACQzX,GAAGgO,iBAAmBhO,GAAGiS,iBAMrCqG,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiBzP,OAAO0P,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAczZ,GAAGoR,SACjBsI,0BAA2B1Z,GAAG6R,MAC9B8H,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxB7X,GAAGga,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQla,GAAG0K,WAAWuP,EAAaC,QAG9Ela,GAAGoP,QAAU,WACT,YAEA,IAAI+K,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZxa,IAAGwG,OAAOvE,MACNiY,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiBvY,KAAK2Y,GAEtBC,GACAJ,EAAiBxY,KAAK4Y,IAGrBF,KAAU,EACfE,GAAaA,EAAU1Y,MAAM,KAAMoY,GAE9BK,GACLA,EAAUzY,MAAM,KAAMmY,GAGnBlY,MAGX0Y,KAAM,SAAS/H,GAQX,MAPc,KAAV4H,EACAD,EAAczY,KAAK8Q,GAGnBA,EAAS5Q,MAAM,KAAsB1B,SAAhB8Z,EAA4BD,EAAcC,GAG5DnY,MAGXqN,QAAS,WAgBL,MAfAkL,GAAQ,EACRL,EAAczY,UAEV2Y,EAAiBhW,QACjBrE,GAAGY,KAAKyZ,EAAkB,SAASzY,EAAKgR,GACpCA,EAAS5Q,MAAM,KAAMmY,KAIzBI,EAAclW,QACdrE,GAAGY,KAAK2Z,EAAe,SAAS3Y,EAAKgR,GACjCA,EAAS5Q,MAAM,KAAMmY,KAItBlY,MAGXuN,QAAS,WAgBL,MAfAgL,IAAQ,EACRJ,EAAc1Y,UAEV4Y,EAAiBjW,QACjBrE,GAAGY,KAAK0Z,EAAkB,SAAS1Y,EAAKgR,GACpCA,EAAS5Q,MAAM,KAAMoY,KAIzBG,EAAclW,QACdrE,GAAGY,KAAK2Z,EAAe,SAAS3Y,EAAKgR,GACjCA,EAAS5Q,MAAM,KAAMoY,KAItBnY,SC3EnBjC,GAAG4a,UAAY,SAASC,EAAeC,GACnC,YAEA9a,IAAGwG,OAAOvE,MACN4Y,cAAeA,EAEfE,OAAQ,WACJ,MAAOD,GAASD,OCF5B7a,GAAGgb,aAAe,SAASC,GACvB,YA0CA,SAASC,KACL,GAAIhO,GAAQC,SAASC,cAAc,QAmEnC,OAjEAF,GAAMoH,aAAatU,GAAGgb,aAAaG,oBAAqBC,GACxDlO,EAAMoH,aAAa,QAAStV,EAAQqc,OAEpCrX,EAAKsX,YAAYtc,EAAQqO,SAAUH,GAE/BlO,EAAQuc,SAAWvb,GAAGiW,kBAAkBgD,iBAExC/L,EAAMoH,aAAa,kBAAmB,IAGtCtV,EAAQwc,aACRtO,EAAMoH,aAAa,SAAUtV,EAAQwc,aAGzCtO,EAAMoH,aAAa,OAAQ,QAC3BpH,EAAMoH,aAAa,OAAQtV,EAAQgC,MAEnChB,GAAGkN,GAAOjH,KACNwV,SAAU,WAIVC,MAAO,EACPC,IAAK,EACLC,WAAY,QASZC,SAAU7b,GAAG4Q,OAAS5Q,GAAGgR,MAAQ,SAAW,QAC5C8K,OAAQ,EACRC,QAAS,EACTC,OAAQ,UACR5V,QAAS,KAKZpG,GAAG+Q,OAAS/Q,GAAGkN,GAAOjH,KAAKgW,OAAQ,SAEpCjd,EAAQ0D,QAAQ6R,YAAYrH,GAE5BgP,EAAe/W,OAAO+H,EAAO,SAAU,WACnClO,EAAQmd,SAASjP,KAIrBgP,EAAe/W,OAAO+H,EAAO,YAAa,WACtClN,GAAGhB,EAAQ0D,SAASqE,SAAS/H,EAAQod,cAEzCF,EAAe/W,OAAO+H,EAAO,WAAY,WACrClN,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQod,cAG5CF,EAAe/W,OAAO+H,EAAO,QAAS,WAClClN,GAAGhB,EAAQ0D,SAASqE,SAAS/H,EAAQqd,cAEzCH,EAAe/W,OAAO+H,EAAO,OAAQ,WACjClN,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQqd,cAGrCnP,EA5GX,GAgCIA,GAAOkO,EAhCPpX,EAAO/B,KAEPia,EAAiB,GAAIlc,IAAGqV,eAExBrW,GAEIwc,YAAa,KAGb9Y,QAAS,KAET2Z,WAAY,yBAGZd,SAAS,EAGTa,WAAY,yBAEZE,4BAA4B,EAG5BjP,UAAU,EAGVrM,KAAM,SAGNmb,SAAU,SAASjP,KAEnBmO,MAAO,KAKfrb,IAAGwG,OAAOxH,EAASic,GAEnBG,EAAWpb,GAAGuQ,cA2EdvQ,GAAGhB,EAAQ0D,SAASuD,KAChBwV,SAAU,WACVc,SAAU,SAEVC,UAAW,QAIfxc,GAAGwG,OAAOvE,MACNwa,SAAU,WACN,MAAOvP,IAGXwP,YAAa,WACT,MAAOtB,IAGXE,YAAa,SAASqB,EAAYC,GAC9B,GAAI1P,GAAQ0P,GAAY3a,KAAKwa,UAKzBzd,GAAQsd,4BAA8Btc,GAAG+R,SAAW/R,GAAGiS,aAAejS,GAAGmS,oBACzEjF,EAAMoH,aAAa,WAAY,IAI3BqI,EACAzP,EAAMoH,aAAa,WAAY,IAG/BpH,EAAM2P,gBAAgB,aAKlCC,eAAgB,SAAStB,GACjBA,IAAgBxc,EAAQwc,aACxBtO,EAAMoH,aAAa,SAAUkH,IAIrCuB,MAAO,WACC7P,EAAMpH,YACN9F,GAAGkN,GAAOnH,SAGd/F,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQqd,YACxCnP,EAAQ,KACRA,EAAQgO,OAIhBhO,EAAQgO,KAGZlb,GAAGgb,aAAaG,oBAAsB,eCxLtCnb,GAAGgd,WAAa,SAASC,GACrB,YAQA,SAASC,GAAaC,GAClB,GAAInd,GAAG8C,QAAQqa,GAAU,CACrB,GAAIC,KAMJ,OAJApd,IAAGY,KAAKuc,EAAS,SAASvb,EAAKyb,GAC3BD,EAAQtb,KAAKzB,EAAKgd,MAGfD,EAGX,MAAO/c,GAAK8c,GAGhB,QAASG,GAAeC,GACpB,GAAIvd,GAAG8C,QAAQya,GAAQ,CACnB,GAAIH,KAMJ,OAJApd,IAAGY,KAAK2c,EAAO,SAAS3b,EAAK4b,GACzBJ,EAAQtb,KAAKzB,EAAKod,EAAOD,OAGtBJ,EAGX,MAAO/c,GAAKod,EAAOF,IAGvB,QAASG,GAAgBC,GACrB,GAAIC,MACAC,KAAczK,OAAOuK,EAYzB,OAVA3d,IAAGY,KAAKid,EAAU,SAAS1Z,EAAO2Z,GAC9B,GAAIC,GAAsBC,EAASF,EAEPxd,UAAxByd,GACA/d,GAAGY,KAAKmd,EAAqB,SAASlK,EAAGoK,GACrCL,EAAc9b,KAAKzB,EAAK4d,QAK7BL,EAhDX,GAAIvd,MACAod,KACAO,KACAE,KACAC,IA+CJne,IAAGwG,OAAOvE,MAeNmc,QAAS,SAASC,GACd,GAAIV,GAASU,EAAKV,QAAU3d,GAAG2d,OAAOW,WAClCjB,EAAKhd,EAAKyB,MACNd,KAAMqd,EAAKrd,KACXud,aAAcF,EAAKrd,KACnBwc,KAAMa,EAAKb,KACXgB,KAAmB,MAAbH,EAAKG,MAAe,EAAKH,EAAKG,KACpCb,OAAQA,IACP,CA8BT,OA5BIU,GAAKI,UACLpe,EAAKgd,GAAIoB,QAAUJ,EAAKI,QAEQne,SAA5B6d,EAAUE,EAAKI,WACfN,EAAUE,EAAKI,aAEnBN,EAAUE,EAAKI,SAAS3c,KAAKub,IAG7BgB,EAAKK,eACLre,EAAKgd,GAAIqB,aAAeL,EAAKK,aAEape,SAAtC4d,EAAeG,EAAKK,gBACpBR,EAAeG,EAAKK,kBAExBR,EAAeG,EAAKK,cAAc5c,KAAKub,IAG3Chd,EAAKgd,GAAIA,GAAKA,EACdI,EAAOY,EAAKb,MAAQH,EAEK/c,SAArB0d,EAASL,KACTK,EAASL,OAEbK,EAASL,GAAQ7b,KAAKub,GAEtBJ,EAAc0B,eAAetB,EAAI,KAAMM,GAEhCN,GAGXuB,SAAU,SAASC,GACf,MAAI7e,IAAGsK,SAASuU,IAAmBxe,EAAKgE,OACV/D,SAAtBue,EAAexB,GACRH,EAAa2B,EAAexB,IAGN/c,SAAxBue,EAAerB,KACbF,EAAeuB,EAAerB,MAGhCqB,EAAelB,OACbD,EAAgBmB,EAAelB,QADrC,OAKE3d,GAAGwG,UAAWnG,GAAM,IAInC0c,MAAO,WACH1c,KACAod,KACAO,KACAG,MAGJW,UAAW,SAASzB,EAAI0B,GACpB,GAAIC,GAAY3e,EAAKgd,GAAIM,OACrBsB,EAAyBjf,GAAG6J,QAAQmU,EAASgB,GAAY3B,EAE7DW,GAASgB,GAAWE,OAAOD,EAAwB,GAEnD5e,EAAKgd,GAAIM,OAASoB,EAEUze,SAAxB0d,EAASe,KACTf,EAASe,OAEbf,EAASe,GAAWjd,KAAKub,GAEzBJ,EAAc0B,eAAetB,EAAI2B,EAAWD,IAGhDI,YAAa,SAAS9B,EAAI+B,GACtB,GAAIC,GAAUhf,EAAKgd,GAAIG,IAEvBnd,GAAKgd,GAAIG,KAAO4B,EAChB3B,EAAO2B,GAAW/B,QACXI,GAAO4B,IAGlBC,WAAY,SAASjC,EAAIkC,GACrBlf,EAAKgd,GAAIrc,KAAOue,GAGpBC,WAAY,SAASnC,EAAIoC,GACrBpf,EAAKgd,GAAImB,KAAOiB,GAIpBC,YAAa,SAASC,EAAUC,GAC5Bvf,EAAKsf,GAAUC,SAAWA,GAG9BC,mBAAoB,SAASxC,GACzB,GAAIqB,GAAere,EAAKgd,GAAIqB,YAE5B,OAAIA,GACOR,EAAeQ,OAK9BoB,cAAe,SAASzC,GACpB,GAAIoB,GAAUpe,EAAKgd,GAAIoB,OAEvB,OAAON,GAAUM,OAK7Bze,GAAG2d,QACCW,WAAY,aACZyB,UAAW,YACXC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,UAAW,YACXC,gBAAiB,kBACjBC,kBAAmB,oBACnBC,cAAe,gBACfC,cAAe,gBACfC,SAAU,WACVC,QAAS,WCxMZ,WACG,YAEA1gB,IAAG2gB,eAECC,SAAU,SAASC,EAAiBrhB,EAAQshB,GACxC7e,KAAK8e,SAASF,EAAiBrhB,EAAQshB,IAG3CE,gBAAiB,SAASC,GACtB,GAAIjd,GAAO/B,IAEXjC,IAAGY,KAAKqgB,EAAgB,SAAS9c,EAAO+c,GACpCld,EAAKmd,eAAeD,MAI5BH,SAAU,SAAS1gB,EAAMb,EAAQshB,GAC7B7e,KAAKmf,kCAEL,IAAI3C,GAAqC,IAA3Bxc,KAAKof,WAAWhd,OAAerE,GAAGuQ,cAAgBtO,KAAKqf,gBAEjEC,EAAcvhB,GAAGgT,KAAK,SAASlE,GAC3B7M,KAAKuf,gBACD1S,KAAMA,EACN9N,KAAMiB,KAAKpB,SAAS4gB,MAAMC,aAC3BjD,EAASkD,IACb1f,MAEH2f,EAAkB5hB,GAAGgT,KAAK,SAAS6O,GAC/B5f,KAAKuf,eAAeK,EAAUpD,EAASkD,IACxC1f,MAEH6f,EAAgB9hB,GAAGgT,KAAK,SAASxK,GAC7B,GAAIsG,GAAO9O,GAAGuI,aAAaC,EAE3BvG,MAAKuf,gBACD1S,KAAMA,EACN9N,KAAMiB,KAAKpB,SAAS4gB,MAAMC,YAAc,QACzCjD,EAASkD,IACb1f,MAEH8f,EAAoB/hB,GAAGgT,KAAK,SAASgP,GACjC,GAAIC,GAAoBD,EAAWtZ,SAAWsZ,EAAWtZ,QAAU,IAC/DoG,EAAO9O,GAAGuI,aAAayZ,EAAWxZ,OAAQwZ,EAAW5e,KAAM6e,EAE/DhgB,MAAKuf,gBACD1S,KAAMA,EACN9N,KAAMghB,EAAWhhB,MAClByd,EAASkD,IACb1f,MAEHigB,EAAqBliB,GAAGgT,KAAK,SAASmP,GAClC,GAAIniB,GAAGwM,QAAQ2V,IAAgBniB,GAAGiW,kBAAkBqC,cAAe,CAC/D,GAAI8J,GAAQ7gB,MAAMC,UAAU1B,MAAM2B,KAAK0gB,EAAYC,OAC/Cpe,EAAO/B,IAEXjC,IAAGY,KAAKwhB,EAAO,SAASxgB,EAAKygB,GACzBre,EAAKwd,eAAea,EAAM5D,EAASkD,SAIvC1f,MAAKuf,eAAeW,EAAa1D,EAASkD,IAE/C1f,MAEHqgB,EAAgB,WACRtiB,GAAGmM,WAAW9L,KACdA,EAAOkB,MAAMC,UAAU1B,MAAM2B,KAAKpB,IAEtCA,KAAU+S,OAAO/S,IAGrB2D,EAAO/B,KACP0f,IAEJ1f,MAAKqf,gBAAkB7C,EAEnBpe,IACAiiB,IAEAtiB,GAAGY,KAAKP,EAAM,SAASuB,EAAK2gB,GACpBviB,GAAGsM,cAAciW,GACjBL,EAAmBK,GAEdviB,GAAG+M,OAAOwV,GACfhB,EAAYgB,GAEPviB,GAAGsK,SAASiY,GACbA,EAAczT,MAAQyT,EAAcvhB,KACpC4gB,EAAgBW,GAEXA,EAAc/Z,QAAU+Z,EAAcvhB,MAC3C+gB,EAAkBQ,GAGjBA,EAAczV,SAAmD,WAAxCyV,EAAczV,QAAQ/M,cACpD+hB,EAAcS,GAGdve,EAAK5B,IAAImgB,EAAgB,6CAA8C,UAI/EtgB,KAAKG,IAAI,YAAcuf,EAActd,OAAS,WAC9CpC,KAAKugB,uBAAuBb,EAAeniB,EAAQshB,KAI3D2B,OAAQ,SAASpF,GACbpb,KAAKygB,SAASD,OAAOpF,IAGzBsF,UAAW,WACP,GAAIC,MACA5e,EAAO/B,IAEXjC,IAAGwG,OAAOoc,EAAe3gB,KAAKof,YAC9BrhB,GAAGY,KAAKgiB,EAAe,SAAShhB,EAAKihB,GACjC7e,EAAKye,OAAOI,KAGhB5gB,KAAKygB,SAASC,aAGlBG,iBAAkB,WACd7gB,KAAKof,eAGT0B,eAAgB,SAAS1F,GACrB,GAAI2F,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAEhD,UAAKrd,GAAGiW,kBAAkBoD,QAAUpX,KAAKpB,SAAS4X,SAASyK,WAIvDF,EAAWrF,SAAW3d,GAAG2d,OAAOwC,QAChCle,KAAKG,IAAIpC,GAAG0L,OAAO,yDAA0D2R,EAAIpb,KAAKkhB,QAAQ9F,KAC9Fpb,KAAKmhB,YAAY/F,IACV,IAGPpb,KAAKG,IAAIpC,GAAG0L,OAAO,sDAAuD2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,UAG9F,KAGXgG,WAAY,SAAShG,GACjB,MAAOpb,MAAKqhB,gBAAgBjG,IAIhCkG,UAAW,SAASC,GAChB,MAAOvhB,MAAKygB,SAASe,QAAQD,IAOjCE,cAAe,SAASC,EAAQC,EAAaC,EAASC,EAAYC,GAC9D,GACIC,GAAWhlB,EADXilB,EAAkB,GAAIjkB,IAAGoP,OAqC7B,OAlCInN,MAAKiiB,iBACLF,EAAY/hB,KAAKkiB,eAAeR,GAChC3kB,GACI+kB,qBAAsBA,EACtBF,QAASA,EAAU,EAAIA,EAAU,KACjCO,MAAOP,EAAU,IAKhBC,GAAc9jB,GAAGiW,kBAAkBiD,gBACpC8K,EAAY/hB,KAAKoiB,QAAQV,IAIZ,MAAbK,EACAC,EAAgBzU,SAAS8U,UAAWV,EAAazhB,MAAO,2BAGxDF,KAAKiiB,gBAAgBK,SAASP,EAAWJ,EAAa5kB,GAASkb,KAC3D,SAAiBsK,GACbP,EAAgB3U,QAAQkV,IAG5B,SAAiBF,EAAWG,GACxBR,EAAgBzU,SAAS8U,UAAWA,EAAWniB,MAAOsiB,GAAU,oCAM5ER,EAAgBzU,SAAS8U,UAAWV,EAAazhB,MAAO,mCAGrD8hB,GAGXS,UAAW,SAASf,GAChB,MAAO1hB,MAAK0iB,WAAW1iB,KAAK2iB,qBAAqBjB,KAGrDkB,YAAa,SAASlB,GAClB,MAAO1hB,MAAK6iB,eAAeC,IAAIpB,IAGnCU,QAAS,SAASb,GACd,MAAOvhB,MAAKygB,SAAS2B,QAAQb,IAAiB,MAGlDwB,cAAe,WACX,MAAO/iB,MAAKghB,YAAYrE,UACpBjB,QACI3d,GAAG2d,OAAOyC,UACVpgB,GAAG2d,OAAO0C,gBACVrgB,GAAG2d,OAAOsC,UAEf5b,QAGP8e,QAAS,SAAS9F,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKrc,MAI/CikB,YAAa,SAAS5H,GAClB,GAAI6H,GAAkBjjB,KAAKkjB,YAAY9H,GAAIA,IACvCuC,EAAW,IAQf,OANIsF,IACiC5kB,SAA7B4kB,EAAgBtF,WAChBA,EAAWsF,EAAgBtF,UAI5BA,GAGXwF,sBAAuB,WACnB,MAAOnjB,MAAKygB,SAAS0C,yBAGzBC,QAAS,SAAShI,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKmB,MAG/C8G,cAAe,WACX,MAAOrjB,MAAKsjB,cAGhBC,yBAA0B,WACtB,GAAIC,GAAexjB,KAAKyjB,iBAExB,OAAID,GAAe,EACRA,EAAexjB,KAAK0jB,qBAGxB,MAGXR,WAAY,SAAStG,GACjB,MAAO5c,MAAKghB,YAAYrE,SAASC,IAGrC+G,QAAS,SAASvI,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKG,MAG/Cpb,IAAK,SAASuJ,EAAKvB,IACXnI,KAAKpB,SAASglB,OAAWzb,GAAmB,SAAVA,EAG7BA,GAAmB,SAAVA,GACdpK,GAAGoC,IAAI,kBAAoBpC,GAAGgW,QAAU,KAAOrK,EAAKvB,GAHpDpK,GAAGoC,IAAI,kBAAoBpC,GAAGgW,QAAU,KAAOrK,IAQvDma,YAAa,SAASzI,GAClB,GAAI2F,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAEhD,KAAKrd,GAAGiW,kBAAkBoD,QAAUpX,KAAKpB,SAAS4X,SAASyK,QACvD,OAAO,CAIX,IAAIljB,GAAG6J,SAAS7J,GAAG2d,OAAOyC,UAAWpgB,GAAG2d,OAAO0C,iBAAkB2C,EAAWrF,SAAW,EAAG,CACtF,GAAI1b,KAAKygB,SAASrJ,MAAMgE,GAEpB,MADApb,MAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOwC,SAClC,CAGPle,MAAKG,IAAIpC,GAAG0L,OAAO,mCAAoC2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,aAIlFpb,MAAKG,IAAIpC,GAAG0L,OAAO,wDAAyD2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,QAGvG,QAAO,GAGXN,MAAO,WACH9a,KAAKG,IAAI,yBAETH,KAAKygB,SAAS3F,QACd9a,KAAKof,cACLpf,KAAK8jB,gBACL9jB,KAAK+jB,kBACL/jB,KAAKgkB,mBACLhkB,KAAKkiB,kBAELnkB,GAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjCA,EAAOpJ,UAGX9a,KAAKmkB,aAAarJ,QAClB9a,KAAK6iB,eAAe/H,QACpB9a,KAAK0jB,qBAAuB,EAC5B1jB,KAAKsjB,aAAe,EACpBtjB,KAAKghB,YAAYlG,QACjB9a,KAAK2iB,wBAEL3iB,KAAKokB,eAAiBpkB,KAAKokB,cAActJ,QACzC9a,KAAKpB,SAASylB,QAAQC,gBAAkBtkB,KAAKukB,sBAE7CvkB,KAAKwkB,kCACLxkB,KAAKykB,+BAELzkB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAe5J,SAG/C6J,MAAO,SAASvJ,GACZ,MAAOpb,MAAK4kB,aAAaxJ,IAG7ByJ,WAAY,SAASzJ,EAAI0J,GACrB,GAAI/iB,GAAO/B,IAEX,OAAOjC,IAAGgnB,OAAOxlB,UAAUslB,WAAWzJ,EAAI0J,GACtC3kB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBqgB,QAASrkB,GAAGgT,KAAKhP,EAAKqgB,QAASrgB,GAC/Bgf,WAAYhf,EAAKif,eAIzBgE,iBAAkB,SAASC,EAAS7J,GAChCpb,KAAKklB,oBAAoBC,IAAIF,EAAS7J,IAG1CgK,2BAA4B,SAASH,EAAS7J,GAC1Cpb,KAAKqlB,8BAA8BF,IAAIF,EAAS7J,IAGpDkK,sBAAuB,SAASzG,EAAUzD,GACtCpb,KAAKulB,yBAAyBJ,IAAItG,EAAUzD,IAGhDoK,oBAAqB,SAASjoB,EAAQ6d,GAClCpb,KAAKylB,uBAAuBN,IAAI5nB,EAAQ6d,IAI5CsK,YAAa,SAAS7G,EAAUzD,GAC5Bpb,KAAK6iB,eAAesC,IAAItG,EAAUzD,IAGtCuK,QAAS,SAASC,GACd5lB,KAAK6lB,4BAA4BD,IAGrCE,aAAc,SAASC,GACnB/lB,KAAKyjB,kBAAoBsC,GAG7BC,QAAS,SAAS5K,EAAIkC,GAClBtd,KAAKghB,YAAY3D,WAAWjC,EAAIkC,IAGpC2I,UAAW,SAAS1oB,EAAQ6d,GACxBpb,KAAKmkB,aAAagB,IAAI5nB,EAAQ6d,IAGlC8K,QAAS,SAAS9K,EAAI+B,GAClB,MAAOnd,MAAKghB,YAAY9D,YAAY9B,EAAI+B,IAG5CgJ,kBAAmB,WACgB,IAA3BnmB,KAAKof,WAAWhd,OAChBpC,KAAKomB,WAAW,gBAGhBpmB,KAAKqmB,uBAQjBtoB,GAAGuoB,gBAECpH,eAAgB,SAASqH,GACrB,GAAInL,GAAKpb,KAAKghB,YAAY7E,SACtBZ,KAAMgL,EAAYhL,KAClBxc,KAAMwnB,EAAYxnB,KAClBwd,KAAMgK,EAAYhK,KAClBb,OAAQ3d,GAAG2d,OAAO2C,mBAatB,OAVAkI,GAAYC,oBAAsBxmB,KAAKslB,sBAAsBiB,EAAYC,mBAAoBpL,GAC7FmL,EAAYE,kBAAoBzmB,KAAKwlB,oBAAoBe,EAAYE,iBAAkBrL,GAEnFmL,EAAYG,eACZ1mB,KAAKkiB,eAAe9G,GAAMmL,EAAYG,cAG1C1mB,KAAKsjB,eACLtjB,KAAK0jB,uBAEEtI,GAGXuL,sBAAuB,SAASvG,EAAMwG,GAC9B7oB,GAAGgM,OAAOqW,KACVA,EAAKyG,WAAa7mB,KAAK8mB,aAAaF,KAI5CG,YAAa,SAAS3mB,GAClBJ,KAAKpB,SAASF,UAAUsoB,QAAQ,KAAM,KAAM5mB,EAAS/B,SAGzD4oB,qBAAsB,WAClB,GAAIllB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGmpB,yBACVC,OAAQnnB,KAAKpB,SAASwiB,WAAW+F,OAAOvpB,cACxCwpB,eAAgBpnB,KAAKpB,SAASwoB,eAC9BC,cAAernB,KAAKpB,SAAS0oB,QAAQC,SACrCC,cAAexnB,KAAKqlB,8BACpBoC,YAAaznB,KAAKylB,uBAClBiC,cAAe1nB,KAAKulB,yBACpBoC,KAAM3nB,KAAKpB,SAAS+oB,KACpBxnB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvB6lB,SAAU,SAASxM,GACfrZ,EAAK8lB,UAAUzM,GACfrZ,EAAKnD,SAASF,UAAUkpB,SAASxM,IAErC0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,GACrCjmB,EAAKkmB,kBAAkB7M,EAAI2M,EAAUC,GACrCjmB,EAAKnD,SAASF,UAAUopB,iBAAiB1M,EAAI2M,EAAUC,OAMnEE,oBAAqB,WACjB,GAAInmB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGoqB,cACVC,cAAepoB,KAAKpB,SAASypB,MAAMD,cACnC1pB,WACIyB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBumB,cAAe,SAASzb,GACpB9K,EAAKwmB,wBACDxpB,KAAM,kBACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAU8pB,gBAAiBzmB,EAAM8K,GACjE2L,UAAWza,GAAGgT,KAAKhP,EAAK0mB,oBAAqB1mB,EAAM8K,GACnD6b,WAAY,sBAOhCC,aAAc,SAASC,EAAcC,GACjC,GAAIC,MACAC,EAAWH,EACXI,KACAC,EAAiBJ,EACjBK,EAAO,SAASC,GACZ,MAAIprB,IAAGsK,SAAS8gB,GACLprB,GAAGwG,UAAW4kB,GAElBA,GAEXC,EAAoB,WAChB,MAAIrrB,IAAG0K,WAAWwgB,GACPA,IAEJA,GAEXI,EAAwB,SAASjO,EAAIkO,GAC7BL,GAAkBlrB,GAAGsK,SAASihB,IAC9BvrB,GAAGwG,OAAO+kB,EAAUF,KAGpBJ,EAAoB5N,IACpBrd,GAAGwG,OAAO+kB,EAAUN,EAAoB5N,IAIpD,QACI+J,IAAK,SAAShnB,EAAKid,GAEL,MAANA,GACA0N,KACAC,EAAWG,EAAK/qB,IAGhB2qB,EAAM1N,GAAM8N,EAAK/qB,IAIzB2kB,IAAK,SAAS1H,GACV,GAAImO,EAYJ,OARIA,GADM,MAANnO,GAAc0N,EAAM1N,GACX0N,EAAM1N,GAGN8N,EAAKH,GAGlBM,EAAsBjO,EAAImO,GAEnBL,EAAKK,IAGhBC,YAAa,SAASpO,EAAImO,GAElBxrB,GAAGsK,SAASygB,KAED,OAAP1N,EACIrd,GAAG0K,WAAW8gB,GACdN,EAAiBM,GAGjBN,EAAiBA,MACjBlrB,GAAGwG,OAAO0kB,EAAgBM,KAI9BP,EAAoB5N,GAAM4N,EAAoB5N,OAC9Crd,GAAGwG,OAAOykB,EAAoB5N,GAAKmO,MAK/CzlB,OAAQ,SAAS4d,GACb,aAAcoH,GAAMpH,IAGxB5G,MAAO,WACHgO,KACAE,KACAD,EAAWH,KAKvBa,yBAA0B,WACtB,GAAI1nB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGgd,YACVmG,QAAS,SAAS9F,GACd,MAAOrZ,GAAKmf,QAAQ9F,IAExBuI,QAAS,SAASvI,GACd,MAAOrZ,GAAK4hB,QAAQvI,IAExBgI,QAAS,SAAShI,GACd,MAAOrZ,GAAKqhB,QAAQhI,IAExBsB,eAAgB,SAAStB,EAAI2B,EAAWD,GACpC/a,EAAK2nB,sBAAsBtO,EAAI2B,EAAWD,GAC1C/a,EAAKnD,SAASF,UAAUge,eAAetB,EAAI2B,EAAWD,GACtD/a,EAAK4nB,kBAAkBvO,EAAI0B,GAEvB/a,EAAK2iB,gBACLkF,WAAW,WACP7nB,EAAK2iB,eAAehI,eAAetB,EAAI2B,EAAWD,IACnD,OAcnB+M,oBAAqB,SAASzN,GAM1B,QAAS0N,KACL,QAAI/rB,GAAGiW,kBAAkBqC,kBAEjBtU,EAAKnD,SAASmrB,YAAYC,gBAC1BjsB,GAAG6R,QACF7R,GAAG4R,QACJ5N,EAAKkoB,oBAAoBC,EAAmB,WAK1B7rB,SAAlB+d,EAAKhR,SACErJ,EAAKnD,SAASwM,SAGlBgR,EAAKhR,WApBpB,GAGI8Y,GAHAniB,EAAO/B,KACPuZ,EAAc6C,EAAK+N,QAAUnqB,KAAKpB,SAASwrB,WAAW7Q,YACtD2Q,EAAoB9N,EAAK8N,mBAAqBlqB,KAAKpB,SAASwrB,WAAWF,iBA6C3E,OArBAhG,GAAS,GAAInmB,IAAGgb,cACZQ,YAAaA,EACb9Y,QAAS2b,EAAK3b,QACd2Z,WAAYpa,KAAKpB,SAASyrB,QAAQC,YAClChR,QAAS8C,EAAK9C,QACda,WAAYna,KAAKpB,SAASyrB,QAAQE,YAClClQ,2BAA4Bra,KAAKpB,SAASmrB,YAAYS,iBACtDpf,SAAU0e,IACV/qB,KAAMiB,KAAKpB,SAAS0oB,QAAQmD,UAC5BvQ,SAAU,SAASjP,GACflJ,EAAK2oB,eAAezf,IAExBmO,MAAqB,MAAdgD,EAAKhD,MAAgBpZ,KAAKpB,SAASkH,KAAK6kB,eAAiBvO,EAAKhD,QAGzEpZ,KAAK4qB,gBAAgBnX,YAAY,WAC7ByQ,EAAO5Q,YAGXvR,EAAKkiB,SAASpkB,KAAKqkB,GAEZA,GAGX2G,qBAAsB,SAASC,EAAmBptB,GAC9C,GAAIqE,GAAO/B,KACP+qB,KACAhuB,GACI6mB,MAAO5jB,KAAKpB,SAASglB,MACrBwD,eAAgBpnB,KAAKpB,SAASwoB,eAC9BO,KAAM3nB,KAAKpB,SAAS+oB,KACpBF,YAAaznB,KAAKmkB,aAClBuD,cAAe1nB,KAAK6iB,eACpBrM,SAAUxW,KAAKpB,SAAS4X,SACxBc,OAAQtX,KAAKpB,SAAS0Y,OACtBkI,MAAOxf,KAAKpB,SAAS4gB,MACrBrf,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBipB,kBAAmBhrB,KAAKpB,SAAS+lB,MAAMsG,6BACvCC,WAAY,SAAS9P,EAAIrc,EAAMosB,EAAQC,GAC/BD,EAAS,GAAKC,EAAQ,IAItBL,EAAe3P,GACX2P,EAAe3P,GAAI+P,SAAWA,GAAUJ,EAAe3P,GAAIgQ,QAAUA,IACrErpB,EAAKspB,YAAYjQ,EAAIrc,EAAMosB,EAAQC,GACnCrpB,EAAKnD,SAASF,UAAUwsB,WAAW9P,EAAIrc,EAAMosB,EAAQC,KAIzDrpB,EAAKspB,YAAYjQ,EAAIrc,EAAMosB,EAAQC,GACnCrpB,EAAKnD,SAASF,UAAUwsB,WAAW9P,EAAIrc,EAAMosB,EAAQC,IAGzDL,EAAe3P,IAAO+P,OAAQA,EAAQC,MAAOA,KAGjDE,WAAY,SAASlQ,EAAIrc,EAAMqG,EAAQqP,SAC5BsW,GAAe3P,EAEtB,IACI9Z,GADAoa,EAAS3Z,EAAKmhB,YAAY9H,GAAIA,IAAKM,MAOnCA,KAAW3d,GAAG2d,OAAO2C,mBAAqB3C,IAAW3d,GAAG2d,OAAO4C,gBAInEhd,EAASS,EAAKwpB,YAAYnQ,EAAIrc,EAAMqG,EAAQqP,GAIxCnT,YAAmBvD,IAAGoP,QACtB7L,EAAOoX,KAAK,WACR3W,EAAKnD,SAASF,UAAU4sB,WAAWlQ,EAAIrc,EAAMqG,EAAQqP,KAIzD1S,EAAKnD,SAASF,UAAU4sB,WAAWlQ,EAAIrc,EAAMqG,EAAQqP,KAG7D+W,SAAU,SAASpQ,EAAIrc,EAAM0sB,GACzB,GAAIve,GAAU,GAAInP,IAAGoP,OAgBrB,OAdApL,GAAKwmB,wBACDxpB,KAAM,WACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAU8sB,SAAUzpB,EAAMqZ,EAAIrc,GAC9D0Z,UAAWvL,EAAQK,QACnBiL,UAAW,WACPiT,EAAyBxT,KAAK,WAC1BlW,EAAK2pB,UAAUtQ,EAAIrc,KAGvBmO,EAAQG,WAEZqb,WAAYtN,IAGTlO,GAEXye,aAAc5tB,GAAGgT,KAAK/Q,KAAK4rB,cAAe5rB,MAC1C6rB,SAAU,SAASzQ,EAAIrc,GACnBgD,EAAK+pB,UAAU1Q,EAAIrc,GACnBgD,EAAKnD,SAASF,UAAUmtB,SAASzQ,EAAIrc,IAEzCgtB,cAAe,SAAS3Q,EAAIrc,EAAMitB,GAC9BjqB,EAAKkqB,eAAe7Q,EAAI4Q,GACxBjqB,EAAKnD,SAASF,UAAUqtB,cAAc3Q,EAAIrc,EAAMitB,IAEpDE,qBAAsB,SAAS9Q,EAAI4Q,EAAW5mB,EAAQqP,GAClD1S,EAAKnD,SAASF,UAAUwtB,qBAAqBnsB,MAAMgC,EAAMtC,YAE7D0sB,SAAU,SAAS/Q,EAAIrc,EAAMitB,GACzB,MAAOjqB,GAAKnD,SAASF,UAAUytB,SAAS/Q,EAAIrc,EAAMitB,IAEtDI,YAAa,SAAShR,EAAIrc,EAAMstB,EAAc5X,GAC1C,MAAO1S,GAAKuqB,aAAavsB,MAAMgC,EAAMtC,YAEzC8sB,cAAe,SAASnR,EAAI+B,GACxBpb,EAAK5B,IAAI,sCAAwC4B,EAAK4hB,QAAQvI,GAAM,SAAW+B,EAAU,KACzFpb,EAAKmkB,QAAQ9K,EAAI+B,IAErB+D,QAASnjB,GAAGgT,KAAKhP,EAAKmf,QAASnf,GAC/B4hB,QAAS5lB,GAAGgT,KAAKhP,EAAK4hB,QAAS5hB,GAC/BqhB,QAASrlB,GAAGgT,KAAKhP,EAAKqhB,QAASrhB,GAC/ByqB,QAASzuB,GAAGgT,KAAKhP,EAAK0qB,SAAU1qB,GAChC2qB,cAAe,SAASnR,GACpB,MAAOxZ,GAAKmhB,YAAY3H,KAAMA,KAElCoR,SAAU,SAASvR,GACf,GAAIM,GAAS3Z,EAAKmhB,YAAY9H,GAAIA,IAAKM,MACvC,OAAOA,KAAW3d,GAAG2d,OAAOsC,QACxBtC,IAAW3d,GAAG2d,OAAOoC,WACrBpC,IAAW3d,GAAG2d,OAAO0C,iBACrB1C,IAAW3d,GAAG2d,OAAOwC,QAE7BN,mBAAoB7b,EAAKif,YAAYpD,mBACrCC,cAAe9b,EAAKif,YAAYnD,cAexC,OAZA9f,IAAGY,KAAKqB,KAAKpB,SAAS0oB,QAAS,SAASzoB,EAAMV,GAC1CpB,EAAQ8B,GAAQV,IAGpBpB,EAAQyqB,cAAgBxnB,KAAKklB,oBAEzB4F,GACA/sB,GAAGY,KAAKmsB,EAAmB,SAAS5sB,EAAKC,GACrCpB,EAAQmB,GAAOC,IAIhB,GAAIJ,IAAG6uB,wBAAwB7vB,EAASW,IAGnDmvB,oBAAqB,SAASzR,GAC1Bpb,KAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOqC,WAG7C+O,YAAa,SAASrgB,GAClB,GAAc,IAAVA,EACA,MAAOA,GAAQzM,KAAKpB,SAASkH,KAAKinB,YAAY,EAElD,IAAInb,IAAI,CACR,GACInF,IAAgB,IAChBmF,UACKnF,EAAQ;AAEjB,MAAOpI,MAAK2oB,IAAIvgB,EAAO,IAAKwgB,QAAQ,GAAKjtB,KAAKpB,SAASkH,KAAKinB,YAAYnb,IAK5Esb,0BAA2B,WACvB,GAAInrB,GAAO/B,IAEXA,MAAKmtB,qBAELpvB,GAAGY,KAAKqB,KAAKpB,SAASwuB,aAAc,SAASztB,EAAK0tB,GAC9C,GAAIjiB,GAAWiiB,EAAuBjiB,SAClCgf,EAAarsB,GAAGwG,UAAWxC,EAAKnD,SAASwrB,YAAY,GACrDkD,EAAkBvvB,GAAGwG,UAAW8oB,EAEnBhvB,UAAb+M,IACAA,EAAWrJ,EAAKnD,SAASwM,UAGzBkiB,EAAgBlD,YAChBrsB,GAAGwG,OAAO6lB,EAAYiD,EAAuBjD,YAAY,GAG7DrsB,GAAGwG,OAAO+oB,GACNliB,SAAUA,EACVgf,WAAYA,IACb,GAEHroB,EAAKwrB,iBAAiBD,MAI9B5K,WAAY,SAASvJ,GACjB,GAAIqU,GAAmBxtB,KAAKmtB,kBAAkBhU,EAE9C,OAAIqU,GACOA,EAAiB/sB,QAEnB0Y,IAAanZ,KAAKytB,iBAChBztB,KAAKpB,SAASslB,OADpB,QAYT4C,aAAc,SAAS4G,GACnB,GAAIC,GAAQC,EACRC,EAAkBH,CAQtB,IALIG,YAA2B9vB,IAAG4a,YAC9BkV,EAAkBA,EAAgBjV,eAIlCiV,IAAoB9vB,GAAG+M,OAAO+iB,GAAkB,CAChD,GAAI9vB,GAAGgM,OAAO8jB,GACV,MAAOA,GAAgBhH,UAEtB,IAA8C,UAA1CgH,EAAgBhjB,QAAQ/M,eACU,SAAvC+vB,EAAgB1sB,KAAKrD,cAErB,MAAO+vB,GAAgBxnB,aAAatI,GAAGgb,aAAaG,oBAYxD,IATAyU,EAASE,EAAgBtoB,qBAAqB,SAE9CxH,GAAGY,KAAKgvB,EAAQ,SAAShuB,EAAKsL,GAC1B,GAAmC,SAA/BA,EAAM5E,aAAa,QAEnB,MADAunB,GAAY3iB,GACL,IAIX2iB,EACA,MAAOA,GAAUvnB,aAAatI,GAAGgb,aAAaG,uBAK1D4U,gBAAiB,WACb,MAAO9tB,MAAKghB,YAAYrE,UACpBjB,QACI3d,GAAG2d,OAAOyC,UACVpgB,GAAG2d,OAAO0C,gBACVrgB,GAAG2d,OAAOsC,OACVjgB,GAAG2d,OAAOW,WACVte,GAAG2d,OAAOoC,UACV/f,GAAG2d,OAAOwC,UAEf9b,QAKP2rB,mBAAoB,SAAS5U,GACzB,GAAImU,GAAkBttB,KAAKmtB,kBAAkBhU,EAE7C,OAAOmU,GAAkBA,EAAgBlD,WAAapqB,KAAKpB,SAASwrB,YAGxE4D,yBAA0B,SAASC,GAC/B,MAAIA,GAAY7N,eAAgBriB,IAAG4a,WAE3B5Z,KAAMhB,GAAGkV,YAAYgb,EAAY7N,KAAKxH,eACtC2D,KAAM0R,EAAY7N,KAAKxH,cAAc2D,OAKzCxd,KAAMiB,KAAKkjB,YAAY9H,GAAI6S,EAAY7S,KAAKrc,KAC5Cwd,KAAMvc,KAAKkjB,YAAY9H,GAAI6S,EAAY7S,KAAKmB,OAIpD2R,0BAA2B,SAASC,GAChC,GAAIpsB,GAAO/B,KACPouB,IAMJ,OAJArwB,IAAGY,KAAKwvB,EAAc,SAASxuB,EAAKsuB,GAChCG,EAAgBvuB,KAAKkC,EAAKisB,yBAAyBC,MAGhDG,GAIXC,oBAAqB,WACjB,GAAIruB,KAAKpB,SAAS0vB,OAAO1e,KAAO7R,GAAG6R,MAAO,CACtC,GAAI2e,GAAkB,yBAClBrK,EAASlkB,KAAKpB,SAAS0vB,OAAOpK,OAC9B/K,EAAW+K,EAASlkB,KAAK8mB,aAAa5C,GAAUlkB,KAAKytB,iBACrDe,EAAaxuB,KAAKpB,QAGlBua,IAAYA,IAAanZ,KAAKytB,mBAC9Be,EAAaxuB,KAAKmtB,kBAAkBhU,IAIxCqV,EAAWpjB,UAAW,EAGoB,OAAtCojB,EAAWpE,WAAW7Q,YACtBiV,EAAWpE,WAAW7Q,YAAcgV,EAGpCC,EAAWpE,WAAW7Q,aAAe,IAAMgV,EAI/CxwB,GAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjC,GAAIA,EAAOzJ,gBAAkBtB,EAIzB,MAHA+K,GAAO7K,YAAYmV,EAAWpjB,UAC9B8Y,EAAOrJ,eAAe2T,EAAWjV,cAE1B,MAMvBgP,uBAAwB,SAASkG,GAC7B,GAAI1sB,GAAO/B,KACP0uB,EAAiBD,EAAQ9d,UAE7B,OAAI5S,IAAGga,iBAAiB2W,IACpB1uB,KAAKG,IAAIsuB,EAAQ1vB,KAAO,kBAAoB0vB,EAAQ1vB,KAAO,gCAAkC0vB,EAAQ/F,YAC9FgG,EAAezW,KAClB,SAAS0W,GACL5sB,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,YAC1D+F,EAAQjW,UAAUmW,IAEtB,WACQF,EAAQhW,WACR1W,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,YAC1D+F,EAAQhW,aAGR1W,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,gBAKtEgG,KAAmB,EACnBD,EAAQjW,UAAUkW,GAGdD,EAAQhW,WACRzY,KAAKG,IAAIsuB,EAAQ1vB,KAAO,mCAAqC0vB,EAAQ/F,WAAa,iCAClF+F,EAAQhW,aAGRzY,KAAKG,IAAIsuB,EAAQ1vB,KAAO,mCAAqC0vB,EAAQ/F,WAAa,wBAInFgG,IAIXnP,eAAgB,SAASa,EAAM5D,EAASoS,GACpC,GAAI7sB,GAAO/B,KACPub,EAAOxd,GAAGuQ,cACViO,GAAO,EACPxd,EAAOhB,GAAGkV,YAAYmN,GACtByO,EAAazO,EAAKvT,MAAQuT,EAC1B0O,EAAU9uB,KAAK+uB,sBACX/uB,KAAK+uB,sBACLhxB,GAAGgT,KAAKhP,EAAKitB,sBAAuBjtB,IAEvChE,GAAGwM,QAAQskB,IAAeA,EAAWtS,MAAQ,IAC9CA,EAAOsS,EAAWtS,MAGtBuS,EAAQD,EAAY9vB,EAAMwc,EAAMgB,EAAMqS,EAAoBpS,EAASxc,KAAKpB,SAAS0oB,QAAQC,UACrFxG,WAAYhf,EAAKif,YACjByG,YAAa1lB,EAAKoiB,aAClB8K,iBAAkB,SAAS7T,EAAIgF,GAC3Bre,EAAK0e,SAAS/O,IAAI0J,EAAIgF,GACtBre,EAAK2hB,uBACL3hB,EAAKmtB,aAAa9T,OAK9B4T,sBAAuB,SAAS5O,EAAMrhB,EAAMwc,EAAMgB,EAAM4S,EAAU3S,GAC9D,GAAIpB,GAAKpb,KAAKghB,YAAY7E,SAASZ,KAAMA,EAAMxc,KAAMA,EAAMwd,KAAMA,EAAMC,QAASA,GAEhFxc,MAAKygB,SAAS/O,IAAI0J,EAAIgF,GACtBpgB,KAAKkvB,aAAa9T,GAElBpb,KAAK0jB,uBAELyL,EAAStvB,MAAMub,GAAIA,EAAIgF,KAAMA,KAGjCqI,oBAAqB,SAAS5b,EAAMuiB,GAChC,GAAIC,GAAYxiB,EAAK1L,KAAKwG,MAAM,KAAK,GACjC5I,EAAOqwB,CAGC,OAARrwB,IACAA,EAAOiB,KAAKpB,SAASypB,MAAM5I,aAG/B1gB,GAAQ,IAAMswB,EAEdrvB,KAAK8e,UACD/f,KAAMA,EACN8N,KAAMA,KAKd0gB,iBAAkB,SAASnR,GACvB,GAAI8H,GAASlkB,KAAK6pB,qBACdM,OAAQ/N,EAAKgO,WAAW7Q,YACxB2Q,kBAAmB9N,EAAKgO,WAAWF,kBACnCzpB,QAAS2b,EAAK3b,QACd6Y,QAAS8C,EAAK9C,QACdlO,SAAUgR,EAAKhR,SACfgO,MAAOgD,EAAKuO,gBAGhB3qB,MAAKmtB,kBAAkBjJ,EAAOzJ,eAAiB2B,GAGnDkT,0BAA2B,WACvBtvB,KAAKuvB,aAAexxB,GAAGyxB,aAAe,GAAIzxB,IAAGyxB,YACzCxvB,KAAKpB,SAASwT,KAAMrU,GAAGgT,KAAK/Q,KAAKmmB,kBAAmBnmB,MAAOjC,GAAGgT,KAAK/Q,KAAKG,IAAKH,OAG7EA,KAAKuvB,cAAgBvvB,KAAKuvB,aAAaE,gBACvCzvB,KAAKmkB,aAAenkB,KAAK2oB,aACrB3oB,KAAKpB,SAAS0oB,QAAQ/pB,OAASyC,KAAKuvB,aAAaG,uBAGrD1vB,KAAKpB,SAAS+wB,WAAa3vB,KAAKuvB,aAAaK,cACzC5vB,KAAKuvB,aAAaM,cAClB7vB,KAAKpB,SAAS0oB,QAAQzI,SAAW7e,KAAKuvB,aAAaM,cAIvD7vB,KAAKmkB,aAAenkB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQ/pB,SAIpEuyB,kBAAmB,WACf,SAAK/xB,GAAGmpB,0BAA4BlnB,KAAKpB,SAASwiB,WAAWH,YAIzDjhB,KAAKpB,SAAS+oB,KAAKoI,aACfhyB,GAAGiW,kBAAkB2C,sBAIrB5Y,GAAGiW,kBAAkB0C,oBAAqB1W,KAAKpB,SAAS+oB,KAAKqI,aAUzE/F,oBAAqB,SAASgG,EAAS9c,GACnC,GAAI+c,IAAQ,CAEZ,QAAKD,EAAQ7tB,SAIbrE,GAAGY,KAAKsxB,EAAS,SAAStwB,EAAKwwB,GAK3B,GAAIpyB,GAAGoL,SAASgnB,GAAa,CAEzB,GAAIC,GAAW,GAAIzrB,QAAO,MAAQwrB,EAAa,IAAK,IAEpD,IAAgC,MAA5Bhd,EAAS/R,MAAMgvB,GAEf,MADAF,IAAQ,GACD,KAKZA,IAWX9J,WAAY,SAASiK,EAAMC,EAAkBrnB,GASzC,QAASuF,GAAEzP,EAAMwxB,GAAenwB,EAAUA,EAAQ4E,QAAQjG,EAAMwxB,GARhE,GAMIC,GAAsBC,EANtBrwB,EAAUJ,KAAKpB,SAAS8xB,SAASL,GACjCnG,KACAyG,KAAWxf,OAAOmf,GAClBvxB,EAAO4xB,EAAM,GACbxX,EAAWnZ,KAAK8mB,aAAa7d,GAC7B2nB,EAAiB5wB,KAAK+tB,mBAAmB5U,EA+B7C,OA1BApb,IAAGY,KAAKiyB,EAAe1G,kBAAmB,SAASvqB,EAAKkxB,GAKhD9yB,GAAGoL,SAAS0nB,IACZ3G,EAAkBrqB,KAAKgxB,KAI/BL,EAAuBtG,EAAkBnY,KAAK,MAAMjU,cAEpD0Q,EAAE,SAAUxO,KAAKpB,SAASkyB,eAAe/xB,IACzCyP,EAAE,eAAgBgiB,GAClBhiB,EAAE,cAAexO,KAAK8sB,YAAY8D,EAAeG,YACjDviB,EAAE,iBAAkBxO,KAAK8sB,YAAY8D,EAAeI,eAEpDP,EAAmBrwB,EAAQgB,MAAM,cACR,OAArBqvB,GACA1yB,GAAGY,KAAK8xB,EAAkB,SAAS9wB,EAAKsxB,GACpCziB,EAAEyiB,EAAaN,EAAMhxB,MAI7BK,KAAKpB,SAASF,UAAUsoB,QAAQ,KAAMjoB,EAAMqB,EAAS/B,QAE9C+B,GAYXwkB,aAAc,SAASxJ,EAAIzK,GACvB,GAAI3Q,KAAKkxB,qBAAqB9V,GAW1B,MAVApb,MAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO0C,iBAErCzN,EACAA,EAASyK,GAGTpb,KAAKygB,SAASkE,MAAMvJ,IAGjB,GAIfuO,kBAAmB,SAASvO,EAAIM,GAC5B,GAAI3Z,GAAO/B,KACPmxB,EAAcnxB,KAAK8tB,iBAEnBpS,KAAW3d,GAAG2d,OAAO2C,kBACrBre,KAAKwkB,+BAA+B3kB,KAAKub,GAEpCM,IAAW3d,GAAG2d,OAAO4C,eAC1Bte,KAAKykB,4BAA4B5kB,KAAKub,GAGtB,IAAhB+V,IACCnxB,KAAKwkB,+BAA+BpiB,QAAUpC,KAAKykB,4BAA4BriB,SAEhFwnB,WAAW,WACP7nB,EAAKqvB,eAAervB,EAAKyiB,+BAAgCziB,EAAK0iB,8BAC/D,IAIXtF,iCAAkC,WAC9B,GAAIpd,GAAO/B,IAEX,IAAIA,KAAKpB,SAASmrB,YAAYsH,mBAAqBtzB,GAAGgS,UAAYhS,GAAGkS,YAIjE,KAHA2Z,YAAW,WACPziB,OAAOmqB,MAAMvvB,EAAKnD,SAAS8xB,SAASa,+BACrC,GACG,GAAIxzB,IAAGmG,MAAMlE,KAAKpB,SAAS8xB,SAASa,+BAIlDC,8BAA+B,SAASpW,EAAIrc,EAAM0yB,EAAUhd,GAGxD,IAAKgd,EAASpkB,QACV,GAAIoH,GAAsB,MAAfA,EAAIiH,SAAmB+V,EAASvxB,MACvCF,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,8BAAgC0V,EAAIiH,OAAQjH,OAErF,CACD,GAAIid,GAAcD,EAASvxB,MAAQuxB,EAASvxB,MAAQF,KAAKpB,SAASkH,KAAK6rB,oBACvE3xB,MAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM2yB,EAAajd,KAKnEmd,6CAA8C,SAASC,EAAWjmB,EAAO1J,EAAO3E,EAAQshB,GACpF,GAAI9c,GAAO/B,IAEX,IAAI4L,EAAMxJ,OAASF,EACf,GAAI2vB,IAAc7xB,KAAKpB,SAASwrB,WAAW0H,uBAEvClI,WAAW,WACP,GAAImI,GAAuBhwB,EAAKisB,yBAAyBpiB,EAAM1J,IAC3DiX,EAAWpX,EAAK+kB,aAAalb,EAAM1J,GAAOke,MAC1C8D,EAASniB,EAAK2gB,WAAWvJ,EAE7BpX,GAAKwmB,wBACDxpB,KAAM,aACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAUszB,WAAYjwB,EAAMgwB,EAAsB7N,GAClF1L,UAAWza,GAAGgT,KAAKhP,EAAKkwB,2BAA4BlwB,EAAM6J,EAAO1J,EAAO3E,EAAQshB,GAChFpG,UAAW1a,GAAGgT,KAAKhP,EAAKmwB,2BAA4BnwB,EAAM6J,EAAO1J,EAAO3E,EAAQshB,GAChF6J,WAAY,SAAWqJ,EAAqBhzB,KAAO,YAAcgzB,EAAqBxV,QAE3F,OAEF,KAAKsV,EACN,KAAO3vB,EAAQ0J,EAAMxJ,OAAQF,IACzBH,EAAK8qB,oBAAoBjhB,EAAM1J,GAAOkZ,KAMtDgW,eAAgB,SAASe,EAAYC,GACjCpyB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAe2N,cAAcF,EAAYC,EAAQpyB,KAAKgkB,iBAElFhkB,KAAKpB,SAASF,UAAU2zB,cAAct0B,GAAGwG,UAAW4tB,GAAap0B,GAAGwG,UAAW6tB,IAE/EpyB,KAAKwkB,kCACLxkB,KAAKykB,gCAeT6H,aAAc,SAASlR,EAAIrc,EAAMstB,EAAc5X,EAAK9D,GAChD,GAAI5O,GAAO/B,IAIX,IAFA+B,EAAKiiB,gBAAgB5I,GAAMiR,EAAatqB,EAAKnD,SAAS+lB,MAAMsG,8BAExDlpB,EAAKuwB,iBAAiBlX,EAAIrc,EAAMstB,GAAe,CAC/C,GAAIkG,GAAyD,IAAvCxwB,EAAKnD,SAAS+lB,MAAM6N,gBAkB1C,OAhBAzwB,GAAKyvB,8BAA8BzxB,MAAMgC,EAAMtC,WAC/CsC,EAAKnD,SAASF,UAAU0tB,YAAYhR,EAAIrc,EAAMgD,EAAK+hB,aAAa1I,IAChErZ,EAAK0wB,mBAAmBrX,EAAIrc,GAE5BgD,EAAKif,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO0C,iBACzCrc,EAAKgiB,eAAe3I,GAAMwO,WAAW,WACjC7nB,EAAK5B,IAAI,sBAAwBpB,EAAO,OAEpC4R,EACAA,EAASyK,GAGTrZ,EAAK0e,SAASkE,MAAMvJ,IAEzBmX,IAEI,IAIfE,mBAAoB,SAASrX,EAAIrc,GAC7BiB,KAAKG,IAAI,WAAaH,KAAKpB,SAAS+lB,MAAM6N,iBAAmB,4BAA8BzzB,EAAO,QAItGmyB,qBAAsB,SAAS9V,GAC3B,GACIjI,GADAuf,EAAY1yB,KAAKyjB,iBAGrB,OAAIzjB,MAAKgkB,gBAAgB5I,IACrBpb,KAAKG,IAAI,gCAAkCib,EAAI,SACxC,GAEFpb,KAAKygB,SAASe,QAAQpG,IAC3BjI,EAAWnT,KAAKkhB,QAAQ9F,GAEpBpb,KAAKpB,SAASF,UAAUi0B,cAAcvX,EAAIjI,MAAc,IAIxDuf,EAAY,GAAK1yB,KAAK0jB,qBAAuB,EAAIgP,GACjD1yB,KAAKomB,WAAW,0BACT,IAGXpmB,KAAKG,IAAI,wBAA0BgT,EAAW,UAAYiI,EAAK,SACxD,MAGPpb,KAAKG,IAAI,IAAMib,EAAK,2BAA4B,UACzC,IAIfsQ,UAAW,SAAStQ,EAAIrc,GACpBiB,KAAK0jB,uBAELkP,aAAa5yB,KAAK+jB,eAAe3I,GAEjC,IAAIyX,GAAkB90B,GAAG6J,QAAQ5H,KAAKof,WAAYhE,IAC7Cpb,KAAKpB,SAAS+wB,YAAckD,GAAmB,GAChD7yB,KAAKof,WAAWnC,OAAO4V,EAAiB,GAG5C7yB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOuC,WAG7CsN,YAAa,SAASnQ,EAAIrc,EAAMqG,EAAQqP,GAoBpC,MAnBKrP,GAAOiI,SASJjI,EAAOshB,eACP1mB,KAAKkiB,eAAe9G,GAAMhW,EAAOshB,cAGrC1mB,KAAKsjB,eACLtjB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO2C,qBAbzCre,KAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO4C,eAErClZ,EAAOpF,KAAKpB,SAAS+lB,MAAMsG,iCAAkC,IAC7DjrB,KAAKgkB,gBAAgB5I,IAAM,IAYnCpb,KAAKwxB,8BAA8BpW,EAAIrc,EAAMqG,EAAQqP,KAE9CrP,EAAOiI,SAGlBwa,UAAW,SAASzM,GAChBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO8C,WAG7CyJ,kBAAmB,SAAS7M,EAAI2M,EAAUC,GACtC,GAAIjpB,GAAOiB,KAAKkhB,QAAQ9F,EAEpB4M,IACAhoB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO6C,eACzCve,KAAKG,IAAI,uBAAyBpB,EAAO,gBAAiB,SAIzBV,SAA7B0pB,EAASrT,gBACT1U,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,wBAAyBgpB,GAGnE/nB,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,4CAA8CgpB,EAASrM,OAAQqM,KAI7G/nB,KAAK0jB,uBACL1jB,KAAKsjB,eACLtjB,KAAKygB,SAASqS,QAAQ1X,GACtBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO+C,SACzCze,KAAKG,IAAI,uBAAyBpB,EAAO,sBAIjD2rB,eAAgB,SAASzf,GACrB,GAAI8nB,EAEJ,IAAIh1B,GAAGiW,kBAAkBqC,cAAe,CACpC,IAAK0c,EAAY,EAAGA,EAAY9nB,EAAMkV,MAAM/d,OAAQ2wB,IAChD/yB,KAAK2mB,sBAAsB1b,EAAMkV,MAAM4S,GAAY9nB,EAGvDjL,MAAK8e,SAAS7T,EAAMkV,WAGflV,GAAMvC,MAAMtG,OAAS,GAC1BpC,KAAK8e,SAAS7T,EAGlBlN,IAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjCA,EAAOpJ,WAIfuQ,YAAa,SAASjQ,EAAIrc,EAAMosB,EAAQC,GACpCprB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAesO,qBAAqB5X,EAAI+P,EAAQC,IAGhF6H,UAAW,SAAS7X,EAAIrc,KAIxBm0B,yBAA0B,SAAS9X,EAAIrc,GACnCiB,KAAKizB,UAAUlzB,MAAMC,KAAMP,WAC3BO,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOoC,WACzC9d,KAAKmzB,aAAapzB,MAAMC,KAAMP,WAE1BO,KAAKpB,SAAS+wB,YACd3vB,KAAKpB,SAASF,UAAU00B,YAAYrzB,MAAMC,KAAMP,WAChDO,KAAKmhB,YAAY/F,KAGjBpb,KAAKqzB,eAAejY,GACpBpb,KAAKpB,SAASF,UAAU00B,YAAYrzB,MAAMC,KAAMP,aAIxD4hB,gBAAiB,SAASjG,EAAIkY,EAAmBC,GAC7C,GACIC,GADAjY,EAAOvb,KAAK2jB,QAAQvI,EAOxB,OAJIkY,KACAE,EAA4Bz1B,GAAGgT,KAAKuiB,EAAmBtzB,KAAMob,EAAIG,EAAMgY,IAGvEvzB,KAAK8vB,qBACL9vB,KAAKuoB,wBACDxpB,KAAM,iBACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU+0B,eAAgBzzB,KAAMob,GAChE5C,UAAWgb,GACPz1B,GAAGgT,KAAK/Q,KAAK0zB,eAAeC,WAAY3zB,KAAMob,EAAIG,EAAMgY,GAC5D7K,WAAYtN,KAET,IAGPpb,KAAKG,IAAI,iCAAmCib,EAAK,wHACuB,SACjE,IAIf+X,aAAc,SAAS/X,KAIvBwY,iBAAkB,SAASzI,EAAQC,GAC/BprB,KAAKpB,SAASF,UAAUm1B,gBAAgB1I,EAAQC,IAGpDQ,cAAe,SAASxQ,KAIxB0Q,UAAW,SAAS1Q,EAAIrc,GACpBiB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOyC,YAG7C8N,eAAgB,SAAS7Q,EAAI4Q,KAI7BtC,sBAAuB,SAAStO,EAAI2B,EAAWD,GAEvCA,IAAc/e,GAAG2d,OAAOwC,QACxB0U,aAAa5yB,KAAK+jB,eAAe3I,KAIzC0Y,gCAAiC,SAAS3F,GACtC,GAAIpsB,GAAO/B,IAEXjC,IAAGY,KAAKwvB,EAAc,SAASxuB,EAAKsuB,GAChClsB,EAAK8qB,oBAAoBoB,EAAY7S,OAI7C2Y,gCAAiC,SAASC,EAAuBpoB,EAAOrO,EAAQshB,EAAUqF,GACtF,GAAI+P,GACAvB,EAAY1yB,KAAKyjB,kBACjByQ,EAAmCl0B,KAAK0jB,oBAE1B,KAAdgP,GAAmBwB,GAAoCxB,EACnD9mB,EAAMxJ,OAAS,EACfpC,KAAKuoB,wBACDxpB,KAAM,aACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAUszB,WAAYhyB,KAAMg0B,EAAsB,GAAI9P,GACtF1L,UAAWza,GAAGgT,KAAK/Q,KAAKiyB,2BAA4BjyB,KAAM4L,EAAO,EAAGrO,EAAQshB,GAC5EpG,UAAW1a,GAAGgT,KAAK/Q,KAAKkyB,2BAA4BlyB,KAAM4L,EAAO,EAAGrO,EAAQshB,GAC5E6J,WAAY,SAAW9c,EAAM,GAAGwU,KAAKrhB,KAAO,YAAc6M,EAAM,GAAGwU,KAAK7D,OAI5Evc,KAAKomB,WAAW,iBAIpBpmB,KAAK8zB,gCAAgCloB,GACrCqoB,EAAej0B,KAAKpB,SAAS8xB,SAASyD,kBACjCnvB,QAAQ,gBAAiBkvB,GACzBlvB,QAAQ,iBAAkB0tB,GAC/B1yB,KAAK+mB,YAAYkN,KAIzB/B,2BAA4B,SAAStmB,EAAO1J,EAAO3E,EAAQshB,GACvD,GAAIuV,GAAYlyB,EAAQ,CAExBlC,MAAK6sB,oBAAoBjhB,EAAM1J,GAAOkZ,GAAIxP,EAAM1J,GAAOke,KAAKrhB,MAE5DiB,KAAK4xB,8CAA6C,EAAOhmB,EAAOwoB,EAAW72B,EAAQshB,IAGvFoT,2BAA4B,SAASrmB,EAAO1J,EAAO3E,EAAQshB,GACvD,GAAI9c,GAAO/B,KACPo0B,EAAYlyB,EAAQ,EACpB6vB,EAAuB/xB,KAAKguB,yBAAyBpiB,EAAM1J,GAE/DlC,MAAKq0B,wBAAwBzoB,EAAM1J,GAAQ6vB,GACtC9Z,KACD,WACIlW,EAAKuyB,QAAQ1oB,EAAM1J,GAAOkZ,GAAI7d,EAAQshB,GACtC9c,EAAK6vB,8CAA6C,EAAMhmB,EAAOwoB,EAAW72B,EAAQshB,IAEtF,WACI9c,EAAK6vB,8CAA6C,EAAOhmB,EAAOwoB,EAAW72B,EAAQshB,MAK/F0B,uBAAwB,SAAS3U,EAAOrO,EAAQshB,GAC5C,GAAqB,IAAjBjT,EAAMxJ,OAEN,WADApC,MAAKomB,WAAW,eAIpB,IAAI4N,GAAwBh0B,KAAKkuB,0BAA0BtiB,GACvDuN,EAAWnZ,KAAK8mB,aAAalb,EAAM,GAAGwU,MACtC8D,EAASlkB,KAAK0iB,WAAWvJ,EAE7BnZ,MAAKuoB,wBACDxpB,KAAM,kBACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU61B,gBAAiBv0B,KAAMg0B,EAAuB9P,GACxF1L,UAAWza,GAAGgT,KAAK/Q,KAAK+zB,gCAAiC/zB,KAAMg0B,EAAuBpoB,EAAOrO,EAAQshB,EAAUqF,GAC/GzL,UAAW1a,GAAGgT,KAAK/Q,KAAK8zB,gCAAiC9zB,KAAM4L,GAC/D8c,WAAY,sBAIpB8L,wBAAyB,WACrB,GAAIzyB,GAAO/B,IAEXA,MAAK4qB,gBAAgB1nB,OAAOiE,OAAQ,eAAgB,SAASiJ,GACzD,GAAIrO,EAAKghB,gBAKL,MAJA3S,GAAIA,GAAKjJ,OAAOstB,MAEhBrkB,EAAEC,YAActO,EAAKnD,SAAS8xB,SAASgE,QAEhC3yB,EAAKnD,SAAS8xB,SAASgE,WAQ1CnQ,oBAAqB,WACjB,GAAIxiB,GAAO/B,KACPjD,EAAUiD,KAAKpB,SAASylB,OAGxBtmB,IAAG42B,SAA6C,MAAlC30B,KAAKpB,SAASylB,QAAQxF,WAC/B7e,KAAK40B,WACN72B,GAAGwG,OAAOxH,GAAU4qB,KAAM3nB,KAAKpB,SAAS+oB,OAExC5qB,EAAQoD,IAAMpC,GAAGgT,KAAK/Q,KAAKG,IAAKH,MAChCjD,EAAQ83B,cAAgB92B,GAAGgT,KAAK/Q,KAAKkf,eAAgBlf,MAErDA,KAAK40B,SAAW,GAAI72B,IAAG42B,QAAQ53B,IAGnC6sB,WAAW,WACP7nB,EAAK6yB,SAASE,UAAU7c,KAAK,SAASwZ,EAAU1J,GAC5ChmB,EAAKgzB,0BACLhzB,EAAKnD,SAASF,UAAUs2B,yBAAyBvD,GAAU,EAAM1J,IAElE,SAAS0J,EAAU1J,GAElBhmB,EAAKnD,SAASF,UAAUs2B,yBAAyBvD,GAAU,EAAO1J,MAEvE,KAIXgN,wBAAyB,aAEzBtI,SAAU,SAASrR,EAAIoC,GACnBxd,KAAKghB,YAAYzD,WAAWnC,EAAIoC,GAChCxd,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAeuQ,UAAU7Z,IAGzDkX,iBAAkB,SAASlX,EAAIrc,EAAMstB,GACjC,GAAItL,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAGhD,WAAKpb,KAAKgkB,gBAAgB5I,IACnBpb,KAAKpB,SAAS+lB,MAAMuQ,YACpBnU,EAAWrF,SAAW3d,GAAG2d,OAAOwC,SAEL7f,SAA1B2B,KAAK8jB,aAAa1I,KAClBpb,KAAK8jB,aAAa1I,GAAM,GAGxBpb,KAAK8jB,aAAa1I,GAAMpb,KAAKpB,SAAS+lB,MAAMwQ,oBAC5Cn1B,KAAK8jB,aAAa1I,IAAO,GAClB,IAOnBiY,eAAgB,SAASjY,GACrBpb,KAAKof,WAAWvf,KAAKub,IAIzB8T,aAAc,SAAS9T,GACnB,GAAIjC,EAGAA,GADApb,GAAGiW,kBAAkBqC,cACVrW,KAAKygB,SAAS2B,QAAQhH,GAAIyL,WAG1B7mB,KAAK8mB,aAAa9mB,KAAKygB,SAASjG,SAASY,IAGpDjC,IACAnZ,KAAK2iB,qBAAqBvH,GAAMjC,IAIxC0M,4BAA6B,SAASuP,GAClCp1B,KAAKpB,SAASwT,KAAK3R,QAAU20B,EAE7Bp1B,KAAKuvB,aAAexxB,GAAGyxB,aAAe,GAAIzxB,IAAGyxB,YACrCxvB,KAAKpB,SAASwT,KAAMrU,GAAGgT,KAAK/Q,KAAKmmB,kBAAmBnmB,MAAOjC,GAAGgT,KAAK/Q,KAAKG,IAAKH,OAGjFA,KAAKuvB,cAAgBvvB,KAAKuvB,aAAaE,iBACvCzvB,KAAKmkB,aAAaqF,YAAY,KAAMxpB,KAAKuvB,aAAaG,uBAEtD1vB,KAAKpB,SAAS+wB,WAAa3vB,KAAKuvB,aAAaK,cACzC5vB,KAAKuvB,aAAaM,aAClB7vB,KAAK0lB,YAAY1lB,KAAKuvB,aAAaM,eAK/CyE,QAAS,SAASlZ,EAAI7d,EAAQshB,GAC1B,GAAI9f,GAAOiB,KAAKkhB,QAAQ9F,EAEpB7d,IACAyC,KAAKimB,UAAU1oB,EAAQ6d,GAGvByD,GACA7e,KAAK0lB,YAAY7G,EAAUzD,GAG/Bpb,KAAKuoB,wBACDxpB,KAAM,WACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU22B,SAAUr1B,KAAMob,EAAIrc,GAC9DyZ,UAAWza,GAAGgT,KAAK/Q,KAAKkzB,yBAA0BlzB,KAAMob,EAAIrc,GAC5D0Z,UAAW1a,GAAGgT,KAAK/Q,KAAK6sB,oBAAqB7sB,KAAMob,EAAIrc,GACvD2pB,WAAYtN,KAIpB+F,YAAa,SAAS/F,GACbpb,KAAKygB,SAASlV,OAAO6P,IACtBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOsC,SAIjDqI,mBAAoB,WAIhB,IAHA,GAAIiP,GAAYC,EACZxzB,EAAO/B,KAEJA,KAAKof,WAAWhd,QACnBkzB,EAAat1B,KAAKof,WAAW5L,QAC7BxT,KAAKmhB,YAAYmU,EAIrBC,GAAkBv1B,KAAKkjB,YAAYxH,OAAQ3d,GAAG2d,OAAOW,aAAaja,OAC9DmzB,IACAx3B,GAAGoC,IAAI,qBAAuBo1B,EAAkB,yEAChD3L,WAAW,WACP7nB,EAAKskB,sBACN,OAYXgO,wBAAyB,SAASpG,EAAa8D,GAC3C,GAAIhwB,GAAO/B,KACPogB,EAAQ,WACJ,MAAI6N,GAAY7N,eAAgBriB,IAAG4a,UACxBsV,EAAY7N,KAAKxH,cAErBqV,EAAY7N,QAEvBrhB,EAAOgzB,EAAqBhzB,KAC5Bwd,EAAOwV,EAAqBxV,KAC5BpD,EAAWnZ,KAAK8mB,aAAamH,EAAY7N,MACzCwQ,EAAiB5wB,KAAK+tB,mBAAmB5U,GACzCqc,EAAkB,GAAIz3B,IAAGoP,OAQ7B,OANAqoB,GAAgBvd,KACZ,aACA,WACIlW,EAAK8qB,oBAAoBoB,EAAY7S,GAAIrc,KAG7ChB,GAAGsM,cAAc+V,KAAUpgB,KAAKiqB,oBAAoB2G,EAAe1G,kBAAmBnrB,IACtFiB,KAAKomB,WAAW,YAAarnB,EAAMqhB,GAC5BoV,EAAgBjoB,WAGtBvN,KAAKpB,SAASwrB,WAAWqL,YAAuB,IAATlZ,EAKxCA,EAAO,GAAKqU,EAAeG,WAAaxU,EAAOqU,EAAeG,WAC9D/wB,KAAKomB,WAAW,YAAarnB,EAAMqhB,GAC5BoV,EAAgBjoB,WAGvBgP,EAAO,GAAKA,EAAOqU,EAAeI,cAClChxB,KAAKomB,WAAW,eAAgBrnB,EAAMqhB,GAC/BoV,EAAgBjoB,YAGvBxP,GAAG23B,iBAAmB33B,GAAGiW,kBAAkBiD,eAAiBlZ,GAAGgM,OAAOqW,GACtE,GAAIriB,IAAG23B,gBAAgBtV,EAAMriB,GAAGgT,KAAKhP,EAAK5B,IAAK4B,IAAO4zB,SAAS/E,EAAegF,OAAO3d,KACjFud,EAAgBnoB,QAChB,SAASwoB,GACL9zB,EAAKqkB,WAAWyP,EAAY,aAAc92B,EAAMqhB,GAChDoV,EAAgBjoB,YAKxBioB,EAAgBnoB,UAGbmoB,IA3BHx1B,KAAKomB,WAAW,aAAcrnB,EAAMqhB,GAC7BoV,EAAgBjoB,YA6B/BuoB,eAAgB,WACZ,GAAI/zB,GAAMg0B,EAAcl3B,CAExBkD,GAAO/B,KAEP+1B,EAAe,SAASh3B,EAAM4R,EAAU/N,GACpC,GAAIozB,EAEJ,KACI,MAAOrlB,GAAS5Q,MAAMgC,EAAMa,GAEhC,MAAOqzB,GACHD,EAAWC,EAAU71B,SAAW61B,EAAUztB,WAC1CzG,EAAK5B,IAAI,wBAA0BpB,EAAO,gBAAkBi3B,EAAU,UAK9E,KAAKn3B,IAAQmB,MAAKpB,SAASF,WACtB,WACG,GAAIw3B,GAAcC,CAClBD,GAAer3B,EACfs3B,EAAep0B,EAAKnD,SAASF,UAAUw3B,GACvCn0B,EAAKnD,SAASF,UAAUw3B,GAAgB,WACpC,MAAOH,GAAaG,EAAcC,EAAc12B,oBCh0DvE,WACG,YAEA1B,IAAGq4B,kBAAoB,SAASpd,GAC5B,GAAIjX,GAAO/B,IAGXA,MAAKpB,UACDglB,OAAO,EACPM,OAAQ,KACR9Y,UAAU,EACVgc,eAAgB,EAChBiP,6BAA6B,EAC7B1G,YAAY,EAEZrI,SACIE,iBACA3I,SAAU,iBACVyX,cAAe,aACfC,gBAAgB,EAChB9L,UAAW,SACXtD,OAAQ,OACR5pB,UACAi5B,cAAc,EACdC,kBAAmB,kBACnBlP,SAAU,UAGd6C,YACIF,qBACA6G,UAAW,EACXC,aAAc,EACd0B,UAAW,EACXZ,wBAAwB,EACxBvY,YAAa,KACbqc,OACIc,UAAW,EACXC,SAAU,EACVC,UAAW,EACXC,SAAU,GAEdpB,YAAY,GAGhB/2B,WACI22B,SAAU,SAASja,EAAIrc,KACvBq0B,YAAa,SAAShY,EAAIrc,KAC1BusB,WAAY,SAASlQ,EAAIrc,EAAMstB,EAAcyK,KAC7CzE,cAAe,SAASF,EAAYC,KACpC5G,SAAU,SAASpQ,EAAIrc,KACvB8sB,SAAU,SAASzQ,EAAIrc,KACvBgtB,cAAe,SAAS3Q,EAAIrc,EAAMitB,KAClCE,qBAAsB,SAAS9Q,EAAI4Q,EAAWK,EAAc5X,KAC5D0X,SAAU,SAAS/Q,EAAIjI,EAAU6Y,KACjCd,WAAY,SAAS9P,EAAIrc,EAAMosB,EAAQC,KACvCyI,gBAAiB,SAAS1I,EAAQC,KAClCpE,QAAS,SAAS5L,EAAIrc,EAAMyjB,EAAQuU,KACpC3K,YAAa,SAAShR,EAAIrc,EAAMi4B,KAChCrE,cAAe,SAASvX,EAAIrc,KAC5Bw1B,gBAAiB,SAAS0C,KAC1BjF,WAAY,SAASiF,KACrBxD,eAAgB,SAASrY,KACzBwM,SAAU,SAASxM,KACnB0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,KACzCQ,gBAAiB,SAAS3b,KAC1B6P,eAAgB,SAAStB,EAAI2B,EAAWD,KACxCkY,yBAA0B,SAASvD,EAAUpkB,EAAS0a,MAG1D2I,UACIwG,UAAW,qEACXC,UAAW,yDACXC,aAAc,4DACdC,WAAY,yDACZC,aAAc,sBACdnD,kBAAmB,6EACnBoD,oBAAqB,qBACrBC,mBAAoB,qBACpBC,oBAAqB,4BACrBC,mBAAoB,4BACpBC,sBAAuB,mDACvBjD,QAAS,8EACTnD,6BAA8B,6KAGlC5M,OACIuQ,YAAY,EACZC,gBAAiB,EACjB3C,iBAAkB,EAClBvH,6BAA8B,gBAGlCZ,SACIE,YAAa,yBACbD,YAAa,0BAGjB9T,UACIyK,SAAS,EACT2W,YACI3W,SAAS,GAEb4W,WAAW,EACXC,YACIC,UAAW,cACXC,eAAgB,mBAChBC,UAAW,cACXC,cAAe,kBACfC,WAAY,gBAEhBC,SAAU,IAEV/qB,SACIwR,SAAU,OAIlBvH,QACI2J,SAAS,EACToX,gBAAiB,EACjBP,YACIQ,SAAU,aAIlBxH,eAAgB,SAASyH,GACrB,MAAOA,IAGXzyB,MACI6rB,qBAAsB,gCACtBhH,eAAgB,aAChBoC,aAAc,KAAM,KAAM,KAAM,KAAM,KAAM,OAGhD3L,YACIH,SAAS,EACTkG,OAAQ,SACRtI,SAAU,iBACV2I,iBACAjqB,WAGJoqB,MACIoI,UAAU,EACVyI,iBAAiB,EACjBxI,UAAU,GAGdxQ,OACIC,YAAa,aAGjB4I,OACID,cAAe,KACf3I,YAAa,gBAGjB6O,QACI1e,KAAK,EAGLsU,OAAQ,MASZkJ,gBAIA/I,SACIxF,SAAU,KACVthB,UACAiqB,iBACAlD,gBAAgB,GAIpBlS,MAEI3R,QAAS,UAGTkvB,YAAY,EAGZ8I,iBAAiB,GAIrBlhB,SACImhB,cAAe,KAGfC,cAAc,EAGdC,QAAQ,EAIRC,YAAa,KAEbC,eAAgB,GAEhBC,YAAa,kBAEbC,aAAa,EAGbC,UAGJlP,aACIC,gBAAgB,EAChBqH,mBAAmB,EACnB7G,kBAAkB,IAK1BzsB,GAAGwG,OAAOvE,KAAKpB,SAAUoa,GAAG,GAE5BhZ,KAAKikB,YACLjkB,KAAKmtB,qBACLntB,KAAK2iB,wBAEL3iB,KAAK81B,iBACL91B,KAAK4qB,gBAAmB,GAAI7sB,IAAGqV,eAE/BpT,KAAKof,cACLpf,KAAK8jB,gBACL9jB,KAAK+jB,kBACL/jB,KAAKgkB,mBACLhkB,KAAKkiB,kBAELliB,KAAK0jB,qBAAuB,EAC5B1jB,KAAKsjB,aAAe,EACpBtjB,KAAKghB,YAAchhB,KAAKypB,2BAExBzpB,KAAKsvB,4BAELtvB,KAAKklB,oBAAsBllB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQE,eACnExnB,KAAKqlB,8BAAgCrlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAWoG,eAEhFxnB,KAAKylB,uBAAyBzlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAW7jB,QAEzEyC,KAAK6iB,eAAiB7iB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQzI,UAC9D7e,KAAKulB,yBAA2BvlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAWvC,UAE3E7e,KAAKygB,SAAWzgB,KAAK6qB,uBAErB7qB,KAAK0zB,eAAiB31B,GAAGmpB,yBAA2BlnB,KAAKinB,uBAErDjnB,KAAKpB,SAASslB,SACdlkB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAKpB,SAASslB,OACvB9K,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGPza,KAAKktB,4BAELltB,KAAKquB,sBAEDruB,KAAKpB,SAASypB,MAAMD,gBAChBrqB,GAAGoqB,aACHnoB,KAAKokB,cAAgBpkB,KAAKkoB,sBAG1BloB,KAAKG,IAAI,iCAAkC,UAInDH,KAAKw0B,0BAELx0B,KAAKiiB,gBAAkBlkB,GAAGm7B,gBAAkB,GAAIn7B,IAAGm7B,eAAen7B,GAAGgT,KAAK/Q,KAAKG,IAAKH,OACpFA,KAAKukB,sBAELvkB,KAAKwkB,kCACLxkB,KAAKykB,+BAELzkB,KAAKm5B,QAAWp7B,GAAGgnB,QAAU,GAAIhnB,IAAGgnB,OAAO/kB,KAAKpB,SAAS2Y,QAASxZ,GAAGgT,KAAK/Q,KAAKG,IAAKH,WAChFA,KAAKm5B,QAAQlY,UACbjhB,KAAK+uB,sBAAwBhxB,GAAGgT,KAAK/Q,KAAKm5B,QAAQC,cAAep5B,KAAKm5B,UAGtEp7B,GAAGs7B,eAAiBt7B,GAAGiW,kBAAkBqD,cACzCrX,KAAK0kB,eAAiB,GAAI3mB,IAAGs7B,cACzBt7B,GAAGgT,KAAK/Q,KAAK4zB,iBAAkB5zB,MAE/B,SAASob,GACL,GAAIke,GAAQv3B,EAAKif,YAAYrE,UAAUvB,GAAIA,GAC3C,OAAQke,IAASA,EAAM/c,MAAS,KAK5Cvc,KAAKyjB,kBAAoBzjB,KAAKpB,SAASwrB,WAAWsI,WAItD30B,GAAGq4B,kBAAkB72B,UAAYxB,GAAG2gB,cACpC3gB,GAAGwG,OAAOxG,GAAGq4B,kBAAkB72B,UAAWxB,GAAGuoB,mBCnTjDvoB,GAAGw7B,cAAgB,SAASvgB,GACxB,YA2CA,SAASwgB,KACL,MAAOz7B,IAAG6J,SAAS,MAAO,OAAQ,QAAS7K,EAAQoqB,SAAW,EAMlE,QAASsS,GAAyBxU,GAC9B,GAAIyU,IAAoB,CASxB,OAPA37B,IAAGY,KAAK+6B,EAAmB,SAAS/5B,EAAKg6B,GACrC,GAAI57B,GAAG6J,SAAS,SAAU,kBAAmB,mBAAoB,gBAAiB+xB,GAAU,EAExF,MADAD,IAAoB,GACb,IAIRA,EAGX,QAASE,GAAMnlB,GAEX,MAAO1X,GAAQ4qB,KAAKoI,UAAoC1xB,SAAxBoW,EAAIC,gBAIxC,QAASmlB,KACL,GAAI9R,EAeJ,QAbI5gB,OAAOqE,gBAAkBrE,OAAOsE,iBAChCsc,EAAWhqB,GAAGuN,oBAEmBjN,SAA7B0pB,EAASrT,kBACTqT,EAAW,GAAInT,gBAEfmT,EAAS3a,OAAS,aAClB2a,EAASza,QAAU,aACnBya,EAAS+R,UAAY,aACrB/R,EAASgS,WAAa,eAIvBhS,EAIX,QAASiS,GAAY5e,EAAI6e,GACrB,GAAIlS,GAAWmS,EAAY9e,GAAI3G,GAkB/B,OAhBKsT,KAEGA,EADAkS,EACWA,EAGPl9B,EAAQ4qB,KAAKoI,SACF8J,IAGA97B,GAAGuN,oBAItB4uB,EAAY9e,GAAI3G,IAAMsT,GAGnBA,EAIX,QAASoS,GAAQ/e,GACb,GAEIgf,GAFAxoB,EAAI7T,GAAG6J,QAAQyyB,EAAOjf,GACtB4R,EAAMjwB,EAAQqqB,qBAGX8S,GAAY9e,GACnBif,EAAMpd,OAAOrL,EAAG,GAEZyoB,EAAMj4B,QAAU4qB,GAAOpb,EAAIob,IAC3BoN,EAASC,EAAMrN,EAAM,GACrBsN,EAAYF,IAIpB,QAAS9O,GAAWlQ,EAAImf,GACpB,GAAI9lB,GAAMulB,EAAY5e,GAClB+L,EAASpqB,EAAQoqB,OACjBa,EAAUuS,KAAa,CAE3BJ,GAAQ/e,GAEJ4M,EACA7nB,EAAIgnB,EAAS,gBAAkB/L,EAAK,cAAe,SAE7Cwe,EAAMnlB,IAAS+lB,EAAqB/lB,EAAIiH,UAC9CsM,GAAU,EACV7nB,EAAIgnB,EAAS,gBAAkB/L,EAAK,+BAAiC3G,EAAIiH,OAAQ,UAGrF3e,EAAQuuB,WAAWlQ,EAAI3G,EAAKuT,GAGhC,QAASyS,GAAUrf,GACf,GAEI7d,GAFAm9B,EAAiBR,EAAY9e,GAAIuf,iBACjCC,EAAiB79B,EAAQ69B,cAqB7B,OAlBI79B,GAAQ0qB,YAAY3E,MACpBvlB,EAASR,EAAQ0qB,YAAY3E,IAAI1H,IAGjCsf,GACA38B,GAAGY,KAAK+7B,EAAgB,SAAS37B,EAAMZ,GACnCZ,EAASA,MACTA,EAAOwB,GAAQZ,IAInBy8B,GACA78B,GAAGY,KAAKi8B,EAAgB,SAAS77B,EAAMZ,GACnCZ,EAASA,MACTA,EAAOwB,GAAQZ,IAIhBZ,EAGX,QAAS+8B,GAAYlf,EAAIyf,GACrB,GAIIC,GAJArmB,EAAMulB,EAAY5e,EAAIyf,GACtB1T,EAASpqB,EAAQoqB,OACjB5pB,EAASk9B,EAAUrf,GACnB2f,EAAUb,EAAY9e,GAAI2f,OA+C9B,OA5CAh+B,GAAQi+B,OAAO5f,GAEf0f,EAAMG,EAAU7f,EAAI7d,EAAQ28B,EAAY9e,GAAI8f,uBAGxCtB,EAAMnlB,IACNA,EAAIrH,OAAS+tB,EAAkB/f,GAC/B3G,EAAInH,QAAU8tB,EAAmBhgB,IAGjC3G,EAAI4mB,mBAAqBC,EAA8BlgB,GAG3DmgB,EAA0BngB,GAG1B3G,EAAI+mB,KAAKrU,EAAQ2T,GAAK,GAIlB/9B,EAAQ4qB,KAAKoI,UAAYhzB,EAAQ4qB,KAAK6Q,kBAAoBoB,EAAMnlB,KAChEA,EAAIC,iBAAkB,GAG1B+mB,EAAWrgB,GAEXjb,EAAI,WAAagnB,EAAS,gBAAkB/L,GAExC2f,EACAtmB,EAAIinB,KAAKX,GAEJY,IAAgCp+B,EACrCkX,EAAIinB,OAECn+B,GAAUR,EAAQ6+B,aAAe7+B,EAAQ6+B,YAAY99B,cAAc8J,QAAQ,sCAAwC,EACxH6M,EAAIinB,KAAK39B,GAAGqT,QAAQ7T,EAAQ,KAEvBA,GAAUR,EAAQ6+B,aAAe7+B,EAAQ6+B,YAAY99B,cAAc8J,QAAQ,qBAAuB,EACvG6M,EAAIinB,KAAKjpB,KAAKopB,UAAUt+B,IAGxBkX,EAAIinB,KAAKn+B,GAGNkX,EAGX,QAASwmB,GAAU7f,EAAI7d,EAAQ29B,GAC3B,GAAIrc,GAAW9hB,EAAQ2qB,cAAc5E,IAAI1H,GACrC0gB,EAAY5B,EAAY9e,GAAI0gB,SAehC,OAZiBz9B,SAAby9B,IACAjd,GAAY,IAAMid,GAGlBH,GAA+Bp+B,IAC/BshB,EAAW9gB,GAAGqT,QAAQ7T,EAAQshB,IAG9Bqc,IACArc,EAAW9gB,GAAGqT,QAAQ8pB,EAAuBrc,IAG1CA,EAKX,QAASyc,GAA8BlgB,GACnC,MAAO,YACgC,IAA/B4e,EAAY5e,GAAI2gB,YAChBzQ,EAAWlQ,IAKvB,QAASmgB,GAA0BngB,GAC/B,GAAI8P,GAAanuB,EAAQmuB,UAErBA,KACA8O,EAAY5e,GAAI7P,OAAOwuB,WAAa,SAAS3pB,GACrCA,EAAE4rB,kBACF9Q,EAAW9P,EAAIhL,EAAE+a,OAAQ/a,EAAEgb,SAQ3C,QAAS+P,GAAkB/f,GACvB,MAAO,YACHkQ,EAAWlQ,IAMnB,QAASggB,GAAmBhgB,GACxB,MAAO,YACHkQ,EAAWlQ,GAAI,IAIvB,QAASqgB,GAAWrgB,GAChB,GAAI3G,GAAMulB,EAAY5e,GAClBoM,EAAgBzqB,EAAQyqB,cACxByU,EAAkB/B,EAAY9e,GAAI8gB,sBAClC/U,EAASpqB,EAAQoqB,OACjBgV,IAGCvC,GAAMnlB,KACP1X,EAAQq/B,cAAgB3nB,EAAI4nB,iBAAiB,SAAUt/B,EAAQq/B,cAG3Dr/B,EAAQu/B,qCAKHv/B,EAAQ4qB,KAAKoI,UAAcyJ,MAAoBC,EAAyBjS,KACzE/S,EAAI4nB,iBAAiB,mBAAoB,kBACzC5nB,EAAI4nB,iBAAiB,gBAAiB,eAI1Ct/B,EAAQ6+B,aAA2B,SAAXzU,GAAgC,QAAXA,GAC7C1S,EAAI4nB,iBAAiB,eAAgBt/B,EAAQ6+B,aAGjD79B,GAAGwG,OAAO43B,EAAYp+B,GAAG0K,WAAW+e,GAAiBA,EAAcpM,GAAMoM,GACzEzpB,GAAGwG,OAAO43B,EAAYF,GAEtBl+B,GAAGY,KAAKw9B,EAAY,SAASp9B,EAAMZ,GAC/BsW,EAAI4nB,iBAAiBt9B,EAAMZ,MAKvC,QAASq8B,GAAqB+B,GAC1B,MAAOx+B,IAAG6J,QAAQ7K,EAAQy/B,wBAAwBz/B,EAAQoqB,QAASoV,IAAiB,EAGxF,QAASE,GAAcrhB,EAAIyf,EAAQiB,EAAWnB,EAAkBO,EAAuBgB,EAAmBnB,GACtGb,EAAY9e,IACR0gB,UAAWA,EACXnB,iBAAkBA,EAClBO,sBAAuBA,EACvBgB,kBAAmBA,EACnBnB,QAASA,EAGb,IAAI3sB,GAAMisB,EAAMx6B,KAAKub,EAGrB,IAAIhN,GAAOrR,EAAQqqB,eACf,MAAOkT,GAAYlf,EAAIyf,GA7U/B,GAAI16B,GAAKw7B,EACLtB,KACAH,KACAn9B,GACIq/B,aAAc,KACdM,cAAe,QAAS,OAAQ,OAChCvV,OAAQ,OACRyU,YAAa,oCACbxU,eAAgB,EAChBI,iBACAE,iBACAD,eACAmT,kBACA0B,oCAAoC,EACpCE,yBACIG,QAAS,IAAK,IAAK,KACnBC,OAAQ,IAAK,IAAK,IAAK,IAAK,KAC5BC,MAAO,IAAK,IAAK,IAAK,IAAK,KAC3BC,KAAM,IAAK,IAAK,IAAK,IAAK,KAC1BC,KAAM,MAEVpV,MACIoI,UAAU,EACVyI,iBAAiB,GAErBr4B,IAAK,SAASuJ,EAAKvB,KACnB6yB,OAAQ,SAAS5f,KACjBkQ,WAAY,SAASlQ,EAAI2M,EAAUC,KACnCkD,WAAY,KAMpB,IAHAntB,GAAGwG,OAAOxH,EAASic,GACnB7Y,EAAMpD,EAAQoD,IAEVpC,GAAG6J,QAAQ7K,EAAQ2/B,aAAc3/B,EAAQoqB,QAAU,EACnD,KAAM,IAAIjjB,OAAM,IAAMnH,EAAQoqB,OAAS,wDA8S3CwU,GAAiD,QAAnB5+B,EAAQoqB,QAAuC,WAAnBpqB,EAAQoqB,OAElEppB,GAAGwG,OAAOvE,MAENg9B,cAAe,SAAS5hB,GACpB,GAAI6hB,GAAM1/B,EAAQ0nB,EAAS8V,EAASmC,EAAahC,CAEjD,QAEIiC,SAAU,SAASC,GAEf,MADAH,GAAOG,EACAp9B,MAOXq9B,WAAY,SAAS1C,GAEjB,MADAp9B,GAASo9B,EACF36B,MAGXs9B,gBAAiB,SAASC,GAEtB,MADArC,GAAwBqC,EACjBv9B,MAIXw9B,YAAa,SAAStB,GAElB,MADAjX,GAAUiX,EACHl8B,MAIXy9B,YAAa,SAASC,GAElB,MADA3C,GAAU2C,EACH19B,MAIX29B,gBAAiB,WAEb,MADAT,IAAc,EACPl9B,MAIX07B,KAAM,SAASb,GAKX,MAJIqC,IAAen/B,GAAG6J,SAAS,MAAO,UAAW7K,EAAQoqB,SAAW,IAChE5pB,EAAOqgC,aAAc,GAAIC,OAAOC,WAG7BrB,EAAcrhB,EAAIyf,EAAQoC,EAAM1/B,EAAQ29B,EAAuBjW,EAAS8V,MAK3FgD,SAAU,SAAS3iB,GACf+e,EAAQ/e,OC1YpBrd,GAAGigC,cAAgB,SAAS5hB,GACxB,YAEA,IAAI6hB,GAAQ7hB,EAAK6hB,MACbC,KACA1S,EAAWyS,EAAMzS,SACjBtK,EAAU+c,EAAM/c,OAEpBnjB,IAAGwG,OAAOvE,MACN0R,IAAK,SAAS0J,EAAI+iB,GACdD,EAAU9iB,GAAM+iB,EAChBD,EAAU9iB,GAAI9J,SAGlBkP,OAAQ,SAASpF,GACb,GAAIrZ,GAAO/B,KACPyrB,EAA2B,GAAI1tB,IAAGoP,QAClCixB,EAAiB5S,EAASpQ,EAAI8F,EAAQ9F,GAAKqQ,EAE/C2S,GAAenmB,KAAK,WACZlW,EAAKyf,QAAQpG,KACb8iB,EAAU9iB,GAAI2iB,UAAW,EACzBh8B,EAAK+wB,QAAQ1X,IAEjBqQ,EAAyBpe,aAIjCylB,QAAS,SAAS1X,SACP8iB,GAAU9iB,IAGrBijB,oBAAqB,SAASjjB,GAC1B,MAAO8iB,GAAU9iB,GAAIld,KAGzBsjB,QAAS,SAASpG,GACd,MAAyB/c,UAAlB6/B,EAAU9iB,IAGrBN,MAAO,WACHojB,MAGJI,cAAe,SAASljB,GACpB,MAAO8iB,GAAU9iB,IAGrBmjB,qBAAsB,SAASnjB,EAAIojB,GAC/BN,EAAU9iB,GAAIld,IAAMsgC,GAGxBC,aAAc,SAASrjB,GACnB,QAAS8iB,EAAU9iB,GAAI2iB,aCpDnChgC,GAAG6uB,wBAA0B,SAAS5T,EAAGtb,GACrC,YAEA,IAGcghC,GAAsBv+B,EAAK2uB,EAHrC6P,EAAa3+B,KACb4+B,GAAmB,EACnBC,GAA6B,EAGjC9hC,GACI0qB,eACAL,eAAgB,EAChB5Q,UACIyK,SAAS,EACT7V,UACI6V,SAAS,IAGjB9gB,IAAK,SAASuJ,EAAKvB,KACnB+iB,WAAY,SAAS9P,EAAIjI,EAAUgY,EAAQC,KAC3CE,WAAY,SAASlQ,EAAIjI,EAAUse,EAAUhd,KAC7C+W,SAAU,SAASpQ,EAAIjI,KACvBwY,aAAc,SAASvQ,KACvByQ,SAAU,SAASzQ,EAAIjI,KACvB4Y,cAAe,SAAS3Q,EAAIjI,EAAU6Y,KACtCE,qBAAsB,SAAS9Q,EAAI4Q,EAAWyF,EAAUhd,KACxD2X,YAAa,SAAShR,EAAIjI,EAAUse,EAAUhd,KAC9C0X,SAAU,SAAS/Q,EAAIjI,EAAU6Y,KACjCO,cAAe,SAASnR,EAAI+B,KAC5B+D,QAAS,SAAS9F,KAClBoR,QAAS,SAASpR,EAAIoC,KACtBmP,SAAU,SAASvR,KACnBwC,mBAAoB,SAASxC,KAC7ByC,cAAe,SAASzC,MAG5B0jB,GAEIpmB,KAAM,SAAS0C,EAAI2jB,EAAUtN,EAAUhd,GACnC,GAAIuX,GAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,EAE1CjQ,GAAQwP,cAAcljB,GAAI6jB,kBAAmB,QAEtCnQ,GAAQwP,cAAcljB,GAAI9J,KAAK4tB,cAAcH,GACpDjQ,EAAQwP,cAAcljB,GAAI+P,QAAUa,EAAUzP,KAE9Cxf,EAAQmvB,qBAAqB9Q,EAAI0T,EAAQqQ,yBAAyBnT,GAAYyF,EAAUhd,IAK5F2qB,SAAU,SAAShkB,GACf,GAAImB,GAAOxf,EAAQqmB,QAAQhI,GACvBrc,EAAOhC,EAAQmkB,QAAQ9F,EAE3Bjb,GAAI,qCAAuCib,EAAK,qBAChD0T,EAAQuQ,eAAejkB,GAAInD,KACvB,SAASwZ,EAAUhd,GACftU,EAAI,2BAA6Bib,EAEjC,IAAIkkB,GAAoB/zB,EAAOg0B,kBAAkB9N,GAAU,EAE3D10B,GAAQmuB,WAAW9P,EAAIrc,EAAMwd,EAAMA,GACnCuS,EAAQ0Q,+BAA+BpkB,GACvC7P,EAAOk0B,QAAQrkB,EAAIkkB,EAAmB7qB,IAE1C,SAASgd,EAAUhd,GACf,GAAI6qB,GAAoB/zB,EAAOg0B,kBAAkB9N,GAAU,EAE3DtxB,GAAI,yCAA2Cib,EAAK,MAAQkkB,EAAkBp/B,MAAO,SAEjFo/B,EAAkBxkB,OAClBgkB,EAAQhkB,MAAMM,GAGbre,EAAQqvB,YAAYhR,EAAIrc,EAAMugC,EAAmB7qB,IAClDlJ,EAAOk0B,QAAQrkB,EAAIkkB,EAAmB7qB,MAMtDirB,cAAe,SAASX,EAAU3jB,EAAIqW,EAAUhd,GAC5C,GAAI1V,GAAOhC,EAAQmkB,QAAQ9F,EAE3Bjb,GAAI,qCAAuCib,EAAK,WAAa2jB,GAE7DjQ,EAAQ6Q,iBAAiBvkB,EAAI2jB,EAE7B,IACIa,GADAC,EAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,EAGtDoO,GAAiB/kB,MACjBgkB,EAAQhkB,MAAMM,IAGdwkB,EAAgB7hC,GAAG6J,QAAQknB,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAYf,GACtEa,GAAiB,IACjB9Q,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAW7iB,OAAO2iB,EAAe,GACpE9Q,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAUC,QAAQjB,KAMxDjQ,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,gBAG5BpB,IACA/P,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,eAAgB,EAE/C9/B,EAAIpC,GAAG0L,OAAO,mFAAoFgJ,KAAKopB,UAAUtzB,OAAO23B,KAAKpR,EAAQqR,SAAS/kB,KAAO3I,KAAKopB,UAAU/M,EAAQwP,cAAcljB,GAAI5E,SAASspB,cACvM/hC,GAAGY,KAAKmwB,EAAQqR,SAAS/kB,GAAK,SAASglB,EAAMC,GACzClgC,EAAIpC,GAAG0L,OAAO,sDAAuD2R,EAAIglB,EAAMC,EAAMtE,aACrFsE,EAAMC,QAGND,EAAME,YAAa,IAIvBzR,EAAQ0R,0BAA0BplB,GAIlCqlB,EAAkBC,KAAKtlB,GAAI,IAG1Bre,EAAQqvB,YAAYhR,EAAIrc,EAAM8gC,EAAkBprB,IAIjDlJ,EAAOk0B,QAAQrkB,EAAIykB,EAAkBprB,KAKjDksB,aAAc,SAASvlB,GACnB,QAAS0T,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAU39B,QAG1Dw+B,SAAU,SAASxlB,GACf,GAAIylB,GAAU/R,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAUvsB,OAM3D,OAJIqtB,IAAW/R,EAAQgS,gBAAgB1lB,KACnCylB,EAAU,MAGPA,GAGX/lB,MAAO,SAASM,GACZjb,EAAI,8FAAgGib,EAAI,SAExG0T,EAAQ0Q,+BAA+BpkB,GACvC0T,EAAQiS,mBAAmB3lB,GAC3B0T,EAAQwP,cAAcljB,GAAI+P,OAAS,GAGvC6V,SAAU,SAAS5lB,GACf,GAAImB,GAAOxf,EAAQqmB,QAAQhI,GACvBrc,EAAOhC,EAAQmkB,QAAQ9F,GACvB2jB,EAAWD,EAAQ8B,SAASxlB,GAC5B4Q,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCzG,EAAWxJ,EAAQwP,cAAcljB,GAAI6jB,iBACrCgC,EAAmBnS,EAAQwP,cAAcljB,GAAI5E,SAASspB,cAElB,OAApChR,EAAQwP,cAAcljB,GAAI+P,SAC1B2D,EAAQwP,cAAcljB,GAAI+P,OAAS,GAInCmN,GAAYv7B,EAAQovB,SAAS/Q,EAAIrc,EAAMitB,MAAe,IACtD8S,EAAQhkB,MAAMM,GACd2jB,EAAWD,EAAQ8B,SAASxlB,GAC5B4Q,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCzG,GAAW,GAIC,MAAZyG,GAAgD,IAA5BkC,EAAiB7+B,OACrC08B,EAAQM,SAAShkB,IAKjBjb,EAAIpC,GAAG0L,OAAO,oEAAqE2R,EAAI2jB,EAAU/S,EAAU5f,MAAQ,EAAG4f,EAAU3f,IAAKkQ,IACrIxf,EAAQgvB,cAAc3Q,EAAIrc,EAAM+vB,EAAQqQ,yBAAyBnT,IACjEiV,EAAiBphC,KAAKk/B,GACtBjQ,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAamB,EAE5CpC,GACA4B,EAAkBjF,KAAKpgB,EAAI2jB,GAG3BF,GAA8B4B,EAAkBS,aAAepS,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAU39B,QAC5G08B,EAAQkC,SAAS5lB,GAGO,IAAxB4Q,EAAUnf,KAAK0P,MACfpc,EAAIpC,GAAG0L,OAAO,+DAAgEs1B,EAAU3jB,GAAK,SAC7F0jB,EAAQY,cAAcX,EAAU3jB,EAAI,8BAA+B,OAGnE0T,EAAQqS,YAAY/lB,EAAI2jB,EAAUzG,GAAUrgB,KAExC,SAAiBwZ,EAAUhd,GACvBtU,EAAI,wCAA0Cib,EAAK,WAAa2jB,GAEhEjQ,EAAQ6Q,iBAAiBvkB,EAAI2jB,EAE7B,IAAIkC,GAAmBnS,EAAQwP,cAAcljB,GAAI5E,SAASspB,eACtDD,EAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,GACtD2P,EAAqBrjC,GAAG6J,QAAQq5B,EAAkBlC,EAEtD5+B,GAAIpC,GAAG0L,OAAO,8CAA+Cs1B,EAAU3jB,IAEvE0jB,EAAQpmB,KAAK0C,EAAI2jB,EAAUc,EAAkBprB,GAEzC2sB,GAAsB,GACtBH,EAAiBhkB,OAAOmkB,EAAoB,GAGhDtS,EAAQuS,0BAA0BjmB,GAE7B0jB,EAAQ6B,aAAavlB,IAAmC,IAA5B6lB,EAAiB7+B,OAGzC08B,EAAQ6B,aAAavlB,GAC1B0jB,EAAQkC,SAAS5lB,GAGjBjb,EAAIpC,GAAG0L,OAAO,oGAAqG2R,EAAI3I,KAAKopB,UAAUoF,KANtInC,EAAQM,SAAShkB,IAWzB,SAAiBqW,EAAUhd,GACvBqqB,EAAQY,cAAcX,EAAU3jB,EAAIqW,EAAUhd,KAGjDiE,KAAK,WACFoW,EAAQwS,SAASlmB,EAAI2jB,QAO7C0B,GACIc,SACAC,eACAC,YAEAP,UAAW,WACP,GAAIlU,GAAMjwB,EAAQqqB,eACdsa,EAAwB,EACxBC,EAAkB,CAOtB,OALA5jC,IAAGY,KAAK8hC,EAAkBe,YAAa,SAAS9f,EAAQkgB,GACpDF,IACAC,GAAmBC,EAAiBx/B,SAGjC4qB,GAAOyT,EAAkBc,MAAMn/B,OAASs/B,EAAwBC,IAM3EjB,KAAM,SAAStlB,EAAIymB,GACf,GAGIzH,GAHA0H,GAAaD,EACbE,EAAehkC,GAAG6J,QAAQ64B,EAAkBgB,SAAUrmB,GACtD4mB,EAAmBjkC,GAAG6J,QAAQ64B,EAAkBc,MAAOnmB,SAGpDqlB,GAAkBe,YAAYpmB,GAEjC7P,EAAO02B,eAAe7mB,YAAerd,IAAG4a,YACxCxY,EAAI,uCAAyCib,EAAK,qCAC3C0T,GAAQwP,cAAcljB,GAAIgF,MAIjC2hB,GAAgB,EAChBtB,EAAkBgB,SAASxkB,OAAO8kB,EAAc,GAG3CD,GAAaE,GAAoB,IACtCvB,EAAkBc,MAAMtkB,OAAO+kB,EAAkB,GAEjD5H,EAASqG,EAAkBgB,SAASjuB,QAChC4mB,GAAU,IACVqG,EAAkBc,MAAM1hC,KAAKu6B,GAC7B7uB,EAAOa,MAAMguB,MAKzB8H,sBAAuB,WACnB,GAAIC,KAqBJ,OAjBApkC,IAAGY,KAAK8hC,EAAkBe,YAAa,SAAS9f,EAAQ0gB,GAChDA,GAAUA,EAAOhgC,QACjB+/B,EAAmBtiC,KAAKwiC,SAAS3gB,MAMzC3jB,GAAGY,KAAK8hC,EAAkBc,MAAO,SAAS5hC,EAAK+hB,GACtC+e,EAAkBe,YAAY9f,IAC/BygB,EAAmBtiC,KAAKwiC,SAAS3gB,MAKzCygB,EAAqBA,EAAmBhxB,OAAOsvB,EAAkBgB,WAKrEa,kBAAmB,SAASlnB,GACxB,MAAOrd,IAAG6J,QAAQ64B,EAAkBc,MAAOnmB,IAAO;EAGtDogB,KAAM,SAASpgB,EAAI2jB,GAKf,MAJgB,OAAZA,GACA0B,EAAkBgB,SAAS5hC,KAAKub,KAGhCqlB,EAAkBS,cACF,MAAZnC,GACA0B,EAAkBgB,SAASc,MAC3B9B,EAAkBc,MAAM1hC,KAAKub,KAG5B,WACG,GAAIonB,GAAkB/B,EAAkBe,YAAYpmB,MACpDonB,GAAgB3iC,KAAKk/B,GACrB0B,EAAkBe,YAAYpmB,GAAMonB,MAIrC,IAMf1nB,MAAO,WACH2lB,EAAkBgB,YAClBhB,EAAkBc,WAI1BkB,GACI/G,KAAM,SAAStgB,EAAIrc,GACf+vB,EAAQwP,cAAcljB,GAAI+P,OAAS,EAEnChrB,EAAI,qCAAuCib,GAC3C0T,EAAQ4T,WAAWtnB,GAAInD,KACnB,SAASwZ,EAAUoJ,GACf16B,EAAI,uCAAyCib,EAE7C,IAAIykB,GAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,GACtDlV,EAAOxf,EAAQqmB,QAAQhI,EAE3Bre,GAAQmuB,WAAW9P,EAAIrc,EAAMwd,EAAMA,GACnChR,EAAOo3B,aAAavnB,EAAIykB,GACxBt0B,EAAOk0B,QAAQrkB,EAAIykB,EAAkBhF,IAGzC,SAASpJ,EAAUoJ,GACf16B,EAAI,oCAAsCib,EAE1C,IAAIykB,GAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,EAErD10B,GAAQqvB,YAAYhR,EAAIrc,EAAM8gC,EAAkBhF,IACjDtvB,EAAOk0B,QAAQrkB,EAAIykB,EAAkBhF,OAOzDtvB,GACIiV,OAAQ,SAASpF,GACbjb,EAAI,cAAgBib,GACpBre,EAAQ0qB,YAAY3jB,OAAOsX,GAC3BqlB,EAAkBC,KAAKtlB,IAG3BqkB,QAAS,SAASrkB,EAAIqW,EAAUoJ,GAC5B,GAAI97B,GAAOhC,EAAQmkB,QAAQ9F,EAE3Bre,GAAQuuB,WAAWlQ,EAAIrc,EAAM0yB,EAAUoJ,GAEnC/L,EAAQwP,cAAcljB,IACtB0T,EAAQ8T,YAAc9T,EAAQ8T,WAAWxnB,GAG7CqlB,EAAkBC,KAAKtlB,IAK3B6mB,eAAgB,SAAS7mB,GACrB,MAAQ0T,GAAQ+T,UAAY/T,EAAQ+T,SAASznB,IACxC0T,EAAQ1M,SAAW0M,EAAQ1M,QAAQhH,IAG5C0nB,YAAa,WACT,GAAIC,GAAcrlC,EAAYK,GAAGL,GAAaK,GAAGilC,YAC7CC,EAAuBllC,GAAGiW,kBAAkBqC,cAAgB,MAAQ,MAExEyY,GAAU,GAAIiU,GAAYE,EAAuB,iBAC7ClmC,GAEI2vB,cAAe3vB,EAAQ2vB,cACvBxL,QAASnkB,EAAQmkB,QACjBkC,QAASrmB,EAAQqmB,QACjBO,QAAS5mB,EAAQ4mB,QACjBxjB,IAAKA,EACLqrB,SAAUzuB,EAAQyuB,SAClBN,WAAYnuB,EAAQmuB,WACpBqB,cAAexvB,EAAQwvB,gBAI3BuC,EAAQoU,+BACRpU,EAAQoU,iCAIhBC,4BAA6B,SAAS/nB,GAClC,MAAOre,GAAQ4vB,SAASvR,IAM5BgoB,WAAY,SAAShoB,EAAIvO,GAIrB,MAAIA,KAASiiB,EAAQ1M,QAAQhH,IAAOvO,YAAgB9O,IAAG4a,WAKnD5b,EAAQ4uB,aAAavQ,GAErBjb,EAAI,+CAAiDib,GACrDvO,EAAKiM,SAASb,KAAK,SAASorB,GACxBljC,EAAI,mCAAqCib,GAGzC0T,EAAQwU,WAAWloB,EAAIioB,GAGvBtmC,EAAQyvB,QAAQpR,EAAIioB,EAAc9mB,MAGlCuS,EAAQiS,mBAAmB3lB,GAE3B7P,EAAOg4B,uBAAuBnoB,IAIlC,SAAS6Y,GACL,GAAIuP,KAEAvP,KACAuP,EAActjC,MAAQ+zB,GAG1B9zB,EAAIpC,GAAG0L,OAAO,yDAA0D2R,EAAI6Y,GAAe,SAE3Fl3B,EAAQuuB,WAAWlQ,EAAIre,EAAQmkB,QAAQ9F,GAAKrd,GAAGwG,OAAOi/B,EAAe9E,GAAuB,MAC5FnzB,EAAOg4B,uBAAuBnoB,GAC9BqlB,EAAkBC,KAAKtlB,MAOxB,GAHI7P,EAAOg4B,uBAAuBnoB,IAO7CmoB,uBAAwB,SAASnoB,GAC7B,GAAIqoB,GAAa1mC,EAAQ6gB,mBAAmBxC,GACxCsoB,GAAiB,CAoBrB,OAlBID,IAAcA,EAAWrhC,QACzBjC,EAAI,0CAA4Cib,GAEhDrd,GAAGY,KAAK8kC,EAAY,SAAS9jC,EAAKgkC,GAC9B,GAAIp4B,EAAO43B,4BAA4BQ,IAAgB7U,EAAQ1M,QAAQuhB,GACnED,EAAiBC,IAAcvoB,EAC/B7P,EAAOq4B,IAAID,OAEV,IAAIp4B,EAAO43B,4BAA4BQ,GACxC,OAAO,MAKfD,GAAiB,EACjBn4B,EAAOq4B,IAAIxoB,IAGRsoB,GAGXf,aAAc,SAASvnB,EAAIqW,GACEpzB,SAArBozB,EAAStU,SACTpgB,EAAQwvB,cAAcnR,EAAIqW,EAAStU,UAO3CoiB,kBAAmB,SAASsE,EAAkB1R,GAC1C,GAAIV,GAAWoS,CAcf,OAVK9lC,IAAGsK,SAASw7B,KACbpS,KAEI1zB,GAAGoL,SAAS06B,KAAsB1R,IAClCV,EAASvxB,MAAQ2jC,IAIzBpS,EAASpkB,QAAU8kB,EAEZV,GAGXmS,IAAK,SAASxoB,GACV,GAAIrc,GAAOhC,EAAQmkB,QAAQ9F,EAE3B,KAAKujB,EAAWnd,QAAQpG,GACpB,KAAM,IAAIrd,IAAGmG,MAAMkX,EAAK,qCAG5Bre,GAAQ8uB,SAASzQ,EAAIrc,GAEjB6/B,GAAoB9P,EAAQgV,qBAAqB1oB,GACjD0jB,EAAQkC,SAAS5lB,GAGjBqnB,EAAO/G,KAAKtgB,EAAIrc,IAIxBqN,MAAO,SAASgP,GACZ,GAAI2oB,GAAex4B,EAAO02B,eAAe7mB,EAEzC,OAAI2oB,GACOx4B,EAAO63B,WAAWhoB,EAAI2oB,IAG7Bx4B,EAAOq4B,IAAIxoB,IACJ,IAKnBrd,IAAGwG,OAAOvE,MAIN0R,IAAK,SAAS0J,EAAIgF,GACd0O,EAAQpd,IAAI3R,MAAMC,KAAMP,YAM5B8L,OAAQ,SAAS6P,GACb,QAAIqlB,EAAkBjF,KAAKpgB,IAChB7P,EAAOa,MAAMgP,IAK5BuJ,MAAO,SAASvJ,GAWZ,MANIyjB,KACA/P,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,eAAgB,GAK/CQ,EAAkB6B,kBAAkBlnB,GAC7B7P,EAAOa,MAAMgP,GAObujB,EAAWpzB,OAAO6P,IAOjCoF,OAAQ,SAASpF,GACb,GAAI4oB,GAAelV,EAAQtO,OAAOpF,EAE9Brd,IAAGga,iBAAiBisB,GACpBA,EAAa/rB,KAAK,WACd1M,EAAOiV,OAAOpF,KAGb4oB,KAAiB,GACtBz4B,EAAOiV,OAAOpF,IAOtBsF,UAAW,WACP,GACI9O,GADAuwB,EAAqB1B,EAAkByB,uBAK3C,IAAIC,EAAmB//B,OACnB,IAAKwP,EAAIuwB,EAAmB//B,OAAS,EAAGwP,GAAK,EAAGA,IAC5C+sB,EAAWne,OAAO2hB,EAAmBvwB,GAI7C6uB,GAAkB3lB,SAKtBsH,QAAS,SAAShH,GACd,MAAI0T,GAAQ+T,UAAY/T,EAAQ+T,SAASznB,GAC9B0T,EAAQ+T,SAASznB,GAAIxC,cAGzBkW,EAAQ1M,SAAW0M,EAAQ1M,QAAQhH,IAI9C6oB,UAAW,SAAS7oB,GAChB,SAAU0T,EAAQ+T,WAAY/T,EAAQ+T,SAASznB,KAGnDZ,SAAU,SAASY,GACf,GAAI0T,EAAQtU,SACR,MAAOsU,GAAQtU,SAASY,IAIhCN,MAAO,WACH3a,EAAI,4BACJw+B,EAAWje,YACX+f,EAAkB3lB,QAClBgU,EAAQhU,SAGZgY,QAAS,SAAS1X,GACd,GAAIujB,EAAWnd,QAAQpG,GACnB,MAAO0T,GAAQgE,QAAQ1X,IAO/BoG,QAAS,SAASpG,GACd,MAAO0T,GAAQtN,QAAQpG,IAG3B+H,sBAAuB,WACnB,MAAI2L,GAAQ3L,sBACD2L,EAAQ3L,4BAavBkb,oBAAqB,SAASjjB,GAC1B,GAAIujB,EAAWnd,QAAQpG,GACnB,MAAO0T,GAAQuP,oBAAoBjjB,IAS3ChE,MAAO,SAASgE,GACZ,SAAIujB,EAAWuF,YAAY9oB,IAAO0T,EAAQ1X,OAASunB,EAAWnd,QAAQpG,IAAO0T,EAAQ1X,MAAMgE,MACvFqlB,EAAkBC,KAAKtlB,GACvB0T,EAAQ0R,0BAA0BplB,IAC3B,IAMf8oB,YAAa,SAAS9oB,GAClB,QAAS0T,EAAQoV,aAAepV,EAAQoV,YAAY9oB,MAI5Drd,GAAGwG,OAAOxH,EAASic,GACnB7Y,EAAMpD,EAAQoD,IACdy+B,EAAmB7hC,EAAQyZ,SAASyK,SAAWljB,GAAGiW,kBAAkBwC,SACpEqoB,EAA6BD,GAAoB7hC,EAAQyZ,SAASohB,WAAW3W,QAE7Eyd,EAAwB,WACpB,GAAIjN,KAIJ,OAFAA,GAAS10B,EAAQiuB,oBAAqB,EAE/ByG,KAGXlmB,EAAOu3B,eC9uBX/kC,GAAGomC,qBAAuB,SAASnrB,GAC/B,YAEA,IAAIjc,IACIoD,IAAK,SAASC,EAAS+H,MAE3Bi8B,IAEJrmC,IAAGwG,OAAOxH,EAASic,GAEnBjb,GAAGwG,OAAOvE,MACNqkC,eAAgB,SAASjpB,EAAIzK,GACzB,GAAI2zB,GAA2B,SAAS7P,GAChC9jB,EAAS8jB,EAAMr2B,MAGnB+I,QAAOiP,YACPguB,EAAyBhpB,GAAMrd,GAAGoJ,QAAQjE,OAAO,UAAWohC,GAG5DnkC,IAAI,wDAAyD,UAIrEokC,sBAAuB,SAASnpB,GAC5B,GAAIjU,OAAOiP,YAAa,CACpB,GAAIouB,GAAWJ,EAAyBhpB,EACpCopB,IACAA,SCvBpBzmC,GAAG0mC,kBAAoB,SAASroB,GAC5B,YAoBA,SAASsoB,GAAYtpB,SACVupB,GAAiBvpB,GAKpBwpB,IACAhS,aAAaiS,EAA0BzpB,UAChCypB,GAA0BzpB,GACjC0pB,EAAoBP,sBAAsBnpB,GAG9C,IAAI2pB,GAAS75B,SAAS85B,eAAelW,EAAQmW,eAAe7pB,GACxD2pB,KAIAA,EAAO1yB,aAAa,MAAO,qBAE3BtU,GAAGgnC,GAAQjhC,UAQnB,QAASohC,GAAuBC,GAC5B,MAAOA,GAAWx9B,MAAM,KAAK,GAUjC,QAASy9B,GAAoBrmC,GACzB,GAAIgmC,GAAShnC,GAAGuS,UAAU,yCAA2CvR,EAAO,OAO5E,OALAgmC,GAAO1yB,aAAa,KAAMtT,GAE1BgmC,EAAO/hC,MAAMC,QAAU,OACvBiI,SAASm6B,KAAK/yB,YAAYyyB,GAEnBA,EAUX,QAASO,GAA4BP,EAAQp0B,GACzC,GAAIw0B,GAAaJ,EAAO3pB,GACpBsG,EAASwjB,EAAuBC,GAChC5pB,EAAOoI,EAAQjC,EAEnB6jB,GAAgBhqB,GAAQ5K,EAIxBg0B,EAAiBjjB,GAAU3jB,GAAGgnC,GAAQ7hC,OAAO,OAAQ,WAC7C4rB,EAAQtU,SAASkH,KACjBvhB,EAAI,mEAAqEglC,EAAa,KAEtFN,EAA0BM,GAAcvb,WAAW,WAC/C,GAAIqK,GAAe,gEAAkEkR,CACrFhlC,GAAI8zB,EAAc,SAClBtjB,GACIzQ,MAAO+zB,KAEZ,QAMX6Q,EAAoBT,eAAec,EAAY,SAAS/kC,GACpDD,EAAI,2CAA6CC,EAAU,IAC3D,IAGIolC,GAFA/T,GADSyT,EAAuBC,GACrBrW,EAAQ2W,mBAAmBrlC,IACtCmb,EAAOkW,EAASlW,IAGhBA,IAAQgqB,EAAgBhqB,IACxBpb,EAAI,qCAAuCglC,GAC3CvS,aAAaiS,EAA0BM,UAChCN,GAA0BM,GAEjCrW,EAAQ4W,iBAAiBP,GAEzBK,EAAiBD,EAAgBhqB,SAE1BgqB,GAAgBhqB,GACvBupB,EAAoBP,sBAAsBY,GAC1CK,EAAe/T,IAETlW,GACNpb,EAAI,IAAMC,EAAU,2CAxHhC,GAAIrD,GAAUqf,EAAKrf,QACf+xB,EAAU9uB,KACVi+B,EAAQ7hB,EAAK6hB,MACb0H,EAAwB5nC,GAAGuQ,cAC3Bi3B,KACAZ,KACAE,KACAD,EAAS7nC,EAAQ6nC,OACjBna,EAAY1tB,EAAQ0tB,UACpB9G,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,IACZ2kC,EAAsB,GAAI/mC,IAAGomC,sBAAsBhkC,IAAKA,GAkH5DpC,IAAGwG,OAAOvE,KAAM,GAAIjC,IAAGigC,cAAc5hB,IAErCre,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OAII4D,IAAK,SAAS0J,EAAIwS,GACd9f,EAAO4D,IAAI0J,GAAKnQ,MAAO2iB,IAEvBA,EAAUvb,aAAa,OAAQoY,GAG3BmD,EAAU/pB,YACV9F,GAAG6vB,GAAW9pB,UAItBgvB,QAAS,SAAS1X,GACdspB,EAAYtpB,GACZtN,EAAOglB,QAAQ1X,IAGnBoG,QAAS,SAASpG,GACd,MAAOtN,GAAO0T,QAAQpG,IACkB/c,SAApCywB,EAAQwP,cAAcljB,GAAInQ,UAK1ClN,GAAGwG,OAAOvE,MACNwa,SAAU,SAASY,GACf,MAAO0T,GAAQwP,cAAcljB,GAAInQ,OAWrC26B,iBAAkB,SAASb,EAAQp0B,GAE/B,GAAIk1B,EAEAjB,GACAU,EAA4BP,EAAQp0B,GAGpCg0B,EAAiBI,EAAO3pB,IAAMrd,GAAGgnC,GAAQ7hC,OAAO,OAAQ,WAMpD,GALA/C,EAAI,yBAA2B4kC,EAAO3pB,IAKjC2pB,EAAOlhC,WAAZ,CAIA,IAEI,GAAIkhC,EAAOe,iBACPf,EAAOe,gBAAgBT,MACkB,SAAzCN,EAAOe,gBAAgBT,KAAK50B,UAK5B,OAGR,MAAOvQ,GAEHC,EAAI,8EAAgFD,EAAME,QAAU,IAAK,SACzGylC,GAAsBx4B,SAAS,GAGnCsD,EAASk1B,OAWrBE,cAAe,SAAS3qB,GACpB,GAAI+pB,GAAarW,EAAQmW,eAAe7pB,EAExC,OAAOgqB,GAAoBD,IAQ/BO,iBAAkB,SAAStqB,GACM/c,SAAzBsmC,EAAiBvpB,KACjBupB,EAAiBvpB,WACVupB,GAAiBvpB,KAQhC6pB,eAAgB,SAASvjB,GACrB,MAAOA,GAAS,IAAMikB,GAY1BK,mBAAoB,SAAS5pB,GACzB,GAAI+K,GAAS/K,EAAK+K,OACdtI,EAAWzC,EAAKyC,SAChBthB,EAAS6e,EAAK7e,OACdi5B,EAAepa,EAAKoa,aACpByP,EAAa7pB,EAAK6pB,WAClB7zB,EAAOrU,GAAGuS,UAAU,iBAAmB6W,EAAS,2CAChD2T,EAAMjc,CAcV,OAZI2X,GACAz4B,GAAGoU,WAAW5U,EAAQ6U,GAGtB0oB,EAAM/8B,GAAGqT,QAAQ7T,EAAQshB,GAG7BzM,EAAKC,aAAa,SAAUyoB,GAC5B1oB,EAAKC,aAAa,SAAU4zB,GAC5B7zB,EAAKpP,MAAMC,QAAU,OACrBiI,SAASm6B,KAAK/yB,YAAYF,GAEnBA,GAOXqzB,mBAAoB,SAASS,GACzB,GAAIzU,KAEJ,KACIA,EAAW1zB,GAAGwU,UAAU2zB,GAE5B,MAAOhmC,GACHC,EAAI,0DAA4DD,EAAME,QAAU,IAAK,SAGzF,MAAOqxB,OCnSnB1zB,GAAGooC,iBAAmB,SAAS/pB,GAC3B,YAkBA,SAASkkB,GAAMllB,GACXrd,GAAGY,KAAKmwB,EAAQqR,SAAS/kB,GAAK,SAASgrB,EAAO3xB,GAC1C,GAAI4xB,GAAgBvX,EAAQwX,kBAAkBlrB,EAAIgrB,EAElD3xB,GAAI4mB,mBAAqB,KACzB5mB,EAAIlJ,OAAOwuB,WAAa,KACxBtlB,EAAI6rB,QACJ+F,GAAiBA,EAActI,UAAYsI,EAActI,SAAS3iB,KAvB1E,GAAI0T,GAAU9uB,KACVtC,EAAY0e,EAAKrf,QAAQW,UACzBugC,EAAQ7hB,EAAK6hB,MACbznB,EAAW4F,EAAKrf,QAAQyZ,SACxBc,EAAS8E,EAAKrf,QAAQua,OACtBivB,EAAa/vB,GAAY4F,EAAKrf,QAAQyZ,SAASyK,SAAWljB,GAAGiW,kBAAkBwC,SAC/EgwB,EAAgBlvB,GAAU8E,EAAKrf,QAAQua,OAAO2J,SAAWslB,GAAcxoC,GAAGiW,kBAAkBsD,OAC5F4J,EAAU+c,EAAM/c,QAChBkC,EAAU6a,EAAM7a,QAChBO,EAAUsa,EAAMta,QAChBf,EAAcqb,EAAMrb,YACpB8J,EAAgBuR,EAAMvR,cACtBH,EAAgB0R,EAAM1R,cACtBrB,EAAa+S,EAAM/S,WACnB/qB,EAAM89B,EAAM99B,GAahBpC,IAAGwG,OAAOvE,KAAM,GAAIjC,IAAGigC,cAAc5hB,IAErCre,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OAII4D,IAAK,SAAS0J,EAAIqrB,GACd,GAAI1oC,GAAGgM,OAAO08B,IAAgB1oC,GAAG+M,OAAO27B,GACpC34B,EAAO4D,IAAI0J,GAAKgF,KAAMqmB,QAErB,CAAA,KAAIA,YAAuB1oC,IAAG4a,WAI/B,KAAM,IAAIzU,OAAM,2CAHhB4J,GAAO4D,IAAI0J,GAAK6iB,MAAOwI,IAM3B3X,EAAQ4X,eAAetrB,GACvBorB,GAAiB1X,EAAQ6X,uBAAuBvrB,IAGpD0X,QAAS,SAAS1X,GACdklB,EAAMllB,GACN0T,EAAQ0Q,+BAA+BpkB,GACvC0T,EAAQ8T,WAAWxnB,GACnBtN,EAAOglB,QAAQ1X,OAK3Brd,GAAGwG,OAAOvE,MAEN2/B,iBAAkB,SAASvkB,EAAI2jB,SACpBjQ,GAAQwP,cAAcljB,GAAI9J,KAAKs1B,aAAa7H,IAGvDuC,SAAU,SAASlmB,EAAI2jB,GACnB,GAAI8H,GAAY/X,EAAQwP,cAAcljB,GAAI9J,IAEtCu1B,GAAUC,YACHD,GAAUC,KAAK/H,GAEtB8H,EAAUE,sBACHF,GAAUE,eAAehI,IAMxCM,eAAgB,SAASjkB,EAAI4rB,GACzB,GAAIC,GAAenY,EAAQgS,gBAAgB1lB,GAAM,EAC7C3G,EAAMqa,EAAQoY,QAAQ9rB,EAAI6rB,EAE9B,OAAID,IACO,GAAIjpC,IAAGoP,SAAUE,QAAQ25B,EAAevyB,GAAMA,IAGlD,GAAI1W,IAAGoP,SAAUE,WAAYoH,IAGxC2N,QAAS,SAAShH,GACd,MAAO0T,GAAQtN,QAAQpG,IAAO0T,EAAQwP,cAAcljB,GAAIgF,MAG5DyiB,SAAU,SAASznB,GACf,MAAO0T,GAAQtN,QAAQpG,IAAO0T,EAAQwP,cAAcljB,GAAI6iB,OAO5D9a,sBAAuB,WACnB,GAAIgkB,KAmBJ,OAjBArY,GAAQsY,sBAAsB,SAASlpC,EAAK6iB,GACxC+N,EAAQ0R,0BAA0B,KAAMzf,EAAWvK,SAASspB,WAAa/e,EAAWvK,SAASupB,UAE7F,IAAI3hC,IACAW,KAAMgiB,EAAWhiB,KACjBghC,UAAWhf,EAAWvK,SAASupB,UAC/BxjB,KAAMwE,EAAWxE,KACjBhB,KAAMwF,EAAWxF,KAGjBwF,GAAW7iB,MACXE,EAAKF,IAAM6iB,EAAW7iB,KAG1BipC,EAAmBtnC,KAAKzB,KAGrB+oC,GAGXjD,YAAa,SAAS9oB,GAClB,QAAS5E,GAAYsY,EAAQtN,QAAQpG,KAAQ0T,EAAQwP,cAAcljB,GAAIisB,cAG3E7G,0BAA2B,SAASplB,EAAIksB,EAAeC,GACnD,GAAIzH,GAAawH,GAAiBxY,EAAQwP,cAAcljB,GAAI5E,SAASspB,WACjEC,EAAYwH,GAAgBzY,EAAQwP,cAAcljB,GAAI5E,SAASupB,SAE/DD,KACA3/B,EAAIpC,GAAG0L,OAAO,yDAA0DgJ,KAAKopB,UAAUiE,KACvFA,EAAW0H,UACXzpC,GAAGY,KAAKmhC,EAAY,SAASngC,EAAKo/B,GAC9BgB,EAAUC,QAAQjB,KAEtBe,EAAW19B,OAAS,IAI5BgV,MAAO,SAASgE,GACZ,GAAI0T,EAAQtN,QAAQpG,GAIhB,MAHAjb,GAAIpC,GAAG0L,OAAO,4DAA6D2R,EAAI8F,EAAQ9F,KACvF0T,EAAQwP,cAAcljB,GAAIqsB,QAAS,EACnCnH,EAAMllB,IACC,GAIf2lB,mBAAoB,SAAS3lB,GACzB,GAAI5E,GAAYsY,EAAQtN,QAAQpG,GAAK,CACjC,GACIssB,GACA91B,EAFA2G,EAAQuW,EAAQwP,cAAcljB,EAQlC,UAJO7C,GAAM/B,SAEb+B,EAAM/B,YACNkxB,EAAc5Y,EAAQgS,gBAAgB1lB,GAClCssB,EAAc,GAAKlxB,EAASqhB,UAAW,CAKvC,IAJAtf,EAAM/B,SAASyK,SAAU,EACzB1I,EAAM/B,SAASmxB,MAAQD,EACvBnvB,EAAM/B,SAASupB,aAEVnuB,EAAI,EAAGA,EAAI81B,EAAa91B,IACzB2G,EAAM/B,SAASupB,UAAUlgC,KAAK+R,EAGlCkd,GAAQ4X,eAAetrB,OAGvB7C,GAAM/B,SAASyK,SAAU,IAKrCqiB,WAAY,SAASloB,EAAIwsB,GACjB9Y,EAAQtN,QAAQpG,KAChB0T,EAAQwP,cAAcljB,GAAIgF,KAAOwnB,IAIzChF,WAAY,SAASxnB,GACjB,GAAIyrB,GAAY/X,EAAQwP,cAAcljB,GAAI9J,IAE1CvT,IAAGY,KAAKkoC,EAAUE,eAAgB,SAASc,SAChChB,GAAUE,eAAec,KAGpC9pC,GAAGY,KAAKkoC,EAAUC,KAAM,SAASe,SACtBhB,GAAUC,KAAKe,MAW9BC,WAAY,SAAS1sB,EAAI2sB,GACrB,MAAOjZ,GAAQkZ,aAAa5sB,EAAI2sB,EAAahqC,GAAGuN,sBAGpDg7B,kBAAmB,SAASlrB,EAAI2sB,GAC5B,GAAIhJ,GAA0B,MAAfgJ,GAAsB,EAAKA,CAC1C,OAAOjZ,GAAQwP,cAAcljB,GAAI9J,KAAKy1B,eAAehI,IAGzDC,cAAe,SAAS5jB,EAAI6sB,GACxB,GAAIhQ,GAAYzhB,EAAS4hB,SACrB8P,EAAW9kB,EAAQhI,GACnBjP,EAAa2iB,EAAQ1M,QAAQhH,GAC7B+sB,EAAalQ,EAAYgQ,EACzBG,EAAWD,EAAalQ,GAAaiQ,EAAWA,EAAWC,EAAalQ,EACxEyP,EAAc5Y,EAAQgS,gBAAgB1lB,GACtCwrB,EAAe5mC,KAAKs+B,cAAcljB,GAAI9J,KAAKs1B,aAI3C/5B,EAAO+5B,EAAaqB,IAAelqC,GAAGmO,UAAUC,EAAYg8B,EAAYC,EAI5E,OAFAxB,GAAaqB,GAAcp7B,GAGvBw7B,KAAMJ,EACN77B,MAAO+7B,EACP97B,IAAK+7B,EACLE,MAAOZ,EACP76B,KAAMA,EACN0P,KAAM6rB,EAAWD,IAIzBhJ,yBAA0B,SAASnT,GAC/B,OACI+L,UAAW/L,EAAUqc,KACrBE,UAAWvc,EAAU5f,MAAQ,EAC7Bo8B,QAASxc,EAAU3f,IACnB8rB,WAAYnM,EAAUsc,QAQ9BG,mBAAoB,SAASrtB,GACzB,GAAIstB,GAAgB,MAChB3pC,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,GACf6c,EAAYzhB,EAAS4hB,SACrBvZ,EAAW+D,EAAYxH,EAE3B,OAAOrd,IAAG0L,OAAO,2BAA4B/L,EAAWgrC,EAAe3pC,EAAMwd,EAAM0b,EAAWpZ,IAGlG8pB,aAAc,SAASvtB,GACnB,MAAO0T,GAAQ1M,QAAQhH,GAAIja,MAG/BynC,oBAAqB,SAASxtB,GAC1B,MAAO0T,GAAQwP,cAAcljB,GAAI5E,UAOrCsqB,gBAAiB,SAAS1lB,GACtB,GAAI5E,EAAU,CACV,GAAI0xB,GAAW9kB,EAAQhI,GACnB6c,EAAYzhB,EAAS4hB,QAEzB,OAAO/zB,MAAKwkC,KAAKX,EAAWjQ,KAIpCiP,QAAS,SAAS9rB,EAAI2sB,GAClB,GAAIhJ,GAA0B,MAAfgJ,GAAsB,EAAKA,CAC1C,OAAOjZ,GAAQwP,cAAcljB,GAAI9J,KAAKw1B,KAAK/H,IAG/CoB,SAAU,SAAS/kB,GACf,MAAO0T,GAAQwP,cAAcljB,GAAI9J,KAAKw1B,MAK1CM,sBAAuB,SAASz2B,GACxB61B,GACAzoC,GAAGY,KAAKsW,aAAc,SAAS/W,EAAK+K,GAChC,GAAwD,IAApD/K,EAAI0J,QAAQ7J,GAAG0L,OAAO,aAAc/L,IAAmB,CACvD,GAAIqjB,GAAatO,KAAKC,MAAMzJ,EAC5B0H,GAASzS,EAAK6iB,OAM9B2lB,eAAgB,SAAStrB,GACrB0T,EAAQwP,cAAcljB,GAAI9J,MACtBy1B,kBACA7H,iBACA4H,QACAF,kBAIRkC,kBAAmB,SAAS1tB,GACxB0T,EAAQwP,cAAcljB,GAAIisB,cAAe,GAK7C7H,+BAAgC,SAASpkB,GACrC,GAAI2tB,EAEJ,UAAIvC,GAAiB1X,EAAQoV,YAAY9oB,KACrC2tB,EAAiBja,EAAQ2Z,mBAAmBrtB,GAExC2tB,GAAkB9zB,aAAanE,QAAQi4B,OACvC9zB,aAAa+zB,WAAWD,IACjB,IASnBpC,uBAAwB,SAASvrB,GAC7B,GACI2tB,GAAgBE,EADhB1wB,EAAQuW,EAAQwP,cAAcljB,EAK9BorB,IAA+BnoC,SAAdka,EAAMra,MACvB6qC,EAAiBja,EAAQ2Z,mBAAmBrtB,GAC5C6tB,EAAgBh0B,aAAanE,QAAQi4B,GAGjCE,IACAA,EAAgBx2B,KAAKC,MAAMu2B,GAIvBvc,EAAcuc,EAAc1tB,MAC5BuT,EAAQga,kBAAkB1tB,IAG1Bjb,EAAIpC,GAAG0L,OAAO,0DAA2D2R,EAAI8F,EAAQ9F,KAErFmR,EAAcnR,EAAI6tB,EAAc1tB,MAEhChD,EAAMra,IAAM+qC,EAAc/qC,IAC1Bqa,EAAM/B,SAAWyyB,EAAczyB,SAC/B+B,EAAM4S,OAAS8d,EAAc9d,OAC7B5S,EAAM0mB,kBAAmB,EAEzBnQ,EAAQ0R,0BAA0BplB,OAOlDimB,0BAA2B,SAASjmB,GAChC,GACI2tB,GAAgBE,EADhB1wB,EAAQuW,EAAQwP,cAAcljB,EAIlC,IAAIorB,GAAiB1X,EAAQoV,YAAY9oB,GAAK,CAC1C2tB,EAAiBja,EAAQ2Z,mBAAmBrtB,GAE5C6tB,GACIlqC,KAAMmiB,EAAQ9F,GACdmB,KAAM6G,EAAQhI,GACdG,KAAMoI,EAAQvI,GACdld,IAAKqa,EAAMra,IACXsY,SAAU+B,EAAM/B,SAChB2U,OAAQ5S,EAAM4S,OACd+d,YAAarL,KAAK+F,MAGtB,KACI3uB,aAAaC,QAAQ6zB,EAAgBt2B,KAAKopB,UAAUoN,IAExD,MAAO/oC,GACHC,EAAIpC,GAAG0L,OAAO,0DAA2D2R,EAAIlb,EAAMsI,YAAa,WAK5G2gC,yBAA0B,SAAS/tB,EAAI2jB,EAAU9G,GAC7C,GAAIxjB,GAAMqa,EAAQoY,QAAQ9rB,EAAI2jB,GAC1BhgC,EAAOmiB,EAAQ9F,GACfguB,GACI3G,OAAQ,SAAStX,EAAQC,GACrB,GAAI8c,GAAW9kB,EAAQhI,EAEnB+P,KAAWC,EACXF,EAAW9P,EAAIrc,EAAMmpC,EAAUA,GAG/Bhd,EAAW9P,EAAIrc,EAAOosB,GAAU+c,EAAWA,EAAW,EAAI/c,EAAS+c,IAI3EpJ,QAAS,SAAS3T,EAAQC,GACtB,GAAI8T,GAAgBpQ,EAAQwP,cAAcljB,GAAI9J,KAAK4tB,cAC/CmK,EAAiCva,EAAQwP,cAAcljB,GAAI+P,OAC3Dme,EAAmBne,EACnBoe,EAAkBne,EAClB8M,EAAgB9U,EAAQhI,GACxBouB,EAAuBF,GAAoBC,EAAkBtR,GAC7DwR,EAAqBJ,CAEzBnK,GAAcH,GAAYyK,EAE1BzrC,GAAGY,KAAKugC,EAAe,SAASH,EAAU2K,GACtCD,GAAsBC,IAG1Bxe,EAAW9P,EAAIrc,EAAM0qC,EAAoBvR,IAIrDzjB,GAAIlJ,OAAOwuB,WAAa,SAAS3pB,GAC7B,GAAIA,EAAE4rB,iBAAkB,CAEpB,GAAI76B,GAAoB,MAAb82B,EAAoB,SAAW,SAC1CmR,GAAmBjoC,GAAMiP,EAAE+a,OAAQ/a,EAAEgb,UAcjD4c,aAAc,SAAS5sB,EAAI2sB,EAAatzB,EAAKk1B,GACzC,GAAIC,GAAwB,MAAf7B,GAAsB,EAAKA,EACpClB,EAAY/X,EAAQwP,cAAcljB,GAAI9J,IAW1C,OATAu1B,GAAUC,KAAOD,EAAUC,SAC3BD,EAAUE,eAAiBF,EAAUE,mBAErCF,EAAUC,KAAK8C,GAAUn1B,EAErBk1B,IACA9C,EAAUE,eAAe6C,GAAUD,GAGhCl1B,GAIXyuB,8BAA+B,WAC3B,GAAI2G,GAAiBvyB,EAAO+gB,eAE5BvJ,GAAQsY,sBAAsB,SAASlpC,EAAK6iB,GACxC,GAAI+oB,GAAiB,GAAIjM,MAAK9c,EAAWmoB,YAGzCY,GAAeC,QAAQD,EAAeE,UAAYH,GAE9CC,EAAehM,WAAaD,KAAK+F,QACjCzjC,EAAI,2CAA6CjC,GACjD+W,aAAa+zB,WAAW9qC,OAWpC4lC,qBAAsB,SAAS1oB,GAC3B,GAAI7C,GAAQuW,EAAQwP,cAAcljB,EAMlC,OAJK7C,GAAM/B,UACPsY,EAAQiS,mBAAmB3lB,GAGxB7C,EAAM/B,SAASyK,YCxflCljB,GAAGmpB,wBAA0B,SAASlO,GAClC,YAqBA,SAASixB,KACL,MAAqC,SAAjCltC,EAAQoqB,OAAOvpB,eAEXssC,QAAS,aAtBrB,GAAIC,GACAptC,GACIoqB,OAAQ,SACRE,cAAe,SACfK,iBACAN,eAAgB,EAChBI,cAAe,SAASpM,GAAK,UAC7BqM,eACAE,MACIoI,UAAU,EACVyI,iBAAiB,GAErBr4B,IAAK,SAASuJ,EAAKvB,KACnByf,SAAU,SAASxM,KACnB0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,KAGjDjqB,IAAGwG,OAAOxH,EAASic,GAYnBmxB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAe,OAAQ,UACvBvV,OAAQpqB,EAAQoqB,OAChBO,cAAe3qB,EAAQ2qB,cACvBD,YAAa1qB,EAAQ0qB,YACrBmT,eAAgBqP,IAChB7iB,eAAgBrqB,EAAQqqB,eACxBI,cAAe,SAASpM,GACpB,MAAOre,GAAQyqB,cAAc1E,IAAI1H,IAErCjb,IAAKpD,EAAQoD,IACb66B,OAAQj+B,EAAQ6qB,SAChB0D,WAAYvuB,EAAQ+qB,iBACpBH,KAAM5qB,EAAQ4qB,QAGlB5pB,GAAGwG,OAAOvE,MACN2zB,WAAY,SAASvY,EAAIG,EAAMgY,GAC3B,GAAIzI,GAAoByI,KAExBx2B,GAAQoD,IAAI,sCAAwCib,GAE7B,WAAnBre,EAAQoqB,OACRgjB,EAAUnN,cAAc5hB,GACnB+hB,SAAS5hB,GACT8hB,WAAWvS,GACX4Q,QAGL5Q,EAAkB/tB,EAAQsqB,eAAiB9L,EAC3C4uB,EAAUnN,cAAc5hB,GACnBiiB,WAAWvS,GACX4Q,YCpDrB,WAMI,QAAS0O,GAAkBC,GACvB,GAGIC,GAHAC,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTnkC,EAAS2E,SAASC,cAAc,SAGpC,OAAIo/B,GAAKE,EAAK,UACVlkC,EAAOokC,MAAQpkC,EAAOyT,OAAS,EAC/BswB,EAAM/jC,EAAOqkC,WAAW,MACxBN,EAAIO,UAAUR,GAAME,EAAK,EAAG,GAIoB,IAAzCD,EAAIQ,aAAa,EAAG,EAAG,EAAG,GAAG1sC,KAAK,IAUjD,QAAS2sC,GAAqBV,EAAKE,EAAIE,GACnC,GAIIH,GAAKlsC,EAAM4sC,EAAOC,EAJlB1kC,EAAS2E,SAASC,cAAc,UAChC+/B,EAAK,EACLC,EAAKV,EACLW,EAAKX,CAUT,KAPAlkC,EAAOokC,MAAQ,EACfpkC,EAAOyT,OAASywB,EAChBH,EAAM/jC,EAAOqkC,WAAW,MACxBN,EAAIO,UAAUR,EAAK,EAAG,GACtBjsC,EAAOksC,EAAIQ,aAAa,EAAG,EAAG,EAAGL,GAAIrsC,KAG9BgtC,EAAKF,GACRF,EAAQ5sC,EAAgB,GAAVgtC,EAAK,GAAS,GACd,IAAVJ,EACAG,EAAKC,EAELF,EAAKE,EAETA,EAAMD,EAAKD,GAAO,CAItB,OADAD,GAASG,EAAKX,EACI,IAAVQ,EAAe,EAAIA,EAM/B,QAASI,GAAqBhB,EAAKx9B,EAAM9P,EAASuuC,GAC9C,GAAI/kC,GAAS2E,SAASC,cAAc,UAChC3E,EAAOzJ,EAAQyJ,MAAQ,aACvB0G,EAAU,GAAInP,IAAGoP,OASrB,OAPAo+B,GAAoBlB,EAAKx9B,EAAMtG,EAAQxJ,EAASuuC,GAC3CrzB,KAAK,WACF/K,EAAQG,QACJ9G,EAAOI,UAAUH,EAAMzJ,EAAQ0J,SAAW,OAI/CyG,EAGX,QAASs+B,GAAoCpvB,GACzC,GAAIqvB,GAAY,MAEhB,KAAK1tC,GAAG6R,MACJ,KAAM,IAAI7R,IAAGmG,MAAM,kEAGvB,IAAIkY,EAAKsvB,WAAatvB,EAAKuvB,UAAYF,EACnC,OACIG,UAAWvnC,KAAKC,MAAMD,KAAKwnC,KAAKJ,GAAarvB,EAAKsvB,WAAatvB,EAAKuvB,aACpEG,SAAUznC,KAAKC,MAAMD,KAAKwnC,KAAKJ,GAAarvB,EAAKuvB,UAAYvvB,EAAKsvB,eAQ9E,QAASH,GAAoBlB,EAAKx9B,EAAMtG,EAAQxJ,EAASuuC,GACrD,GAMIS,GANAxB,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTC,EAAQ5tC,EAAQ4tC,MAChB3wB,EAASjd,EAAQid,OACjBswB,EAAM/jC,EAAOqkC,WAAW,MACxB19B,EAAU,GAAInP,IAAGoP,OAKrB,OAFAm9B,GAAI0B,OAEAjvC,EAAQkvC,OACDC,GACHr/B,KAAMA,EACNtG,OAAQA,EACRqvB,MAAOyU,EACP8B,YAAa1B,EACb2B,WAAY7B,EACZ8B,YAAatvC,EAAQsvC,YACrBJ,OAAQlvC,EAAQkvC,OAChBK,aAActyB,EACduyB,YAAa5B,KAIhB5sC,GAAGiW,kBAAkByD,2BACtBs0B,EAAqBP,GACjBG,UAAWhB,EACXe,WAAY1xB,IAGZ+xB,IACAhuC,GAAGoC,IAAIpC,GAAG0L,OAAO,iFACbkhC,EAAO3wB,EAAQ+xB,EAAmBD,SAAUC,EAAmBH,WAC/D,QAEJjB,EAAQoB,EAAmBD,SAC3B9xB,EAAS+xB,EAAmBH,YAIpCY,EAAoBjmC,EAAQokC,EAAO3wB,EAAQjd,EAAQsvC,aAI/CtuC,GAAG6R,OACF,WACOw6B,EAAkBC,KAClBE,GAAM,EACNE,GAAM,EAGV,IAOIgC,GAAQC,EAAIC,EAPZC,EAAI,KACJC,EAAY3hC,SAASC,cAAc,UACnC2hC,EAAkBxB,EAAWP,EAAqBV,EAAKE,EAAIE,GAAM,EACjEsC,EAAK1oC,KAAKwkC,KAAK+D,EAAIjC,EAAQJ,GAC3ByC,EAAK3oC,KAAKwkC,KAAK+D,EAAI5yB,EAASywB,EAAKqC,GACjC5B,EAAK,EACL+B,EAAK,CAMT,KAHAJ,EAAUlC,MAAQkC,EAAU7yB,OAAS4yB,EACrCH,EAASI,EAAUjC,WAAW,MAEvBM,EAAKT,GAAI,CAGZ,IAFAiC,EAAK,EACLC,EAAK,EACED,EAAKnC,GACRkC,EAAOS,UAAU,EAAG,EAAGN,EAAGA,GAC1BH,EAAO5B,UAAUR,GAAMqC,GAAKxB,GAC5BZ,EAAIO,UAAUgC,EAAW,EAAG,EAAGD,EAAGA,EAAGD,EAAIM,EAAIF,EAAIC,GACjDN,GAAME,EACND,GAAMI,CAEV7B,IAAM0B,EACNK,GAAMD,EAEV1C,EAAI6C,UACJN,EAAYJ,EAAS,QAIzBnC,EAAIO,UAAUR,EAAK,EAAG,EAAGM,EAAO3wB,GAGpCzT,EAAO6mC,iBAAmB7mC,EAAO6mC,kBACjClgC,EAAQG,UAEDH,GAGX,QAASg/B,GAAqCmB,GAC1C,GAAIxgC,GAAOwgC,EAAWxgC,KAClB+oB,EAAQyX,EAAWzX,MACnBuW,EAAckB,EAAWlB,YACzBC,EAAaiB,EAAWjB,WACxBC,EAAcgB,EAAWhB,YACzBn/B,EAAU,GAAInP,IAAGoP,QACjB8+B,EAASoB,EAAWpB,OACpBqB,EAAepiC,SAASC,cAAc,UACtCoiC,EAAsBD,EAAa1C,WAAW,MAC9C4C,EAAeH,EAAW9mC,OAC1B+lC,EAAee,EAAWf,aAC1BC,EAAcc,EAAWd,WAyB7B,OAvBAC,GAAoBc,EAAclB,EAAYD,EAAaE,GAE3DmB,EAAaxzB,OAASsyB,EACtBkB,EAAa7C,MAAQ4B,EAErBgB,EAAoB1C,UAAUjV,EAAO,EAAG,GAExCqW,GACIp/B,KAAMA,EACNmN,OAAQsyB,EACR1W,MAAOA,EACP0X,aAAcA,EACdE,aAAcA,EACd7C,MAAO4B,IAENt0B,KACG,WACIu1B,EAAaJ,iBAAmBI,EAAaJ,kBAC7ClgC,EAAQG,WAEZH,EAAQK,SAGTL,EAOX,QAASs/B,GAAoBjmC,EAAQokC,EAAO3wB,EAAQqyB,GAChD,OAAQA,GACJ,IAAK,GACL,IAAK,GACL,IAAK,GACL,IAAK,GACD9lC,EAAOokC,MAAQ3wB,EACfzT,EAAOyT,OAAS2wB,CAChB,MACJ,SACIpkC,EAAOokC,MAAQA,EACfpkC,EAAOyT,OAASA,EAExB,GAAIswB,GAAM/jC,EAAOqkC,WAAW,KAC5B,QAAQyB,GACJ,IAAK,GAED/B,EAAImD,UAAU9C,EAAO,GACrBL,EAAInoB,OAAM,EAAI,EACd,MACJ,KAAK,GAEDmoB,EAAImD,UAAU9C,EAAO3wB,GACrBswB,EAAIoD,OAAOrpC,KAAKspC,GAChB,MACJ,KAAK,GAEDrD,EAAImD,UAAU,EAAGzzB,GACjBswB,EAAInoB,MAAM,GAAG,EACb,MACJ,KAAK,GAEDmoB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAInoB,MAAM,GAAG,EACb,MACJ,KAAK,GAEDmoB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAImD,UAAU,GAAIzzB,EAClB,MACJ,KAAK,GAEDswB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAImD,UAAU9C,GAAQ3wB,GACtBswB,EAAInoB,OAAM,EAAI,EACd,MACJ,KAAK,GAEDmoB,EAAIoD,QAAO,GAAOrpC,KAAKspC,IACvBrD,EAAImD,WAAW9C,EAAO,IAUlC,QAASiD,GAAaC,EAAUC,GAC5B,GAAI/rC,GAAO/B,IAEPmH,QAAOO,MAAQmmC,YAAoBnmC,QAClC,WACG,GAAI2iC,GAAM,GAAI0D,OACVC,EAAM7mC,OAAO6mC,KAAO7mC,OAAO6mC,IAAIC,gBAAkB9mC,OAAO6mC,IACpD7mC,OAAO+mC,WAAa/mC,OAAO+mC,UAAUD,gBAAkB9mC,OAAO+mC,UAAY,IAClF,KAAKF,EAAO,KAAM9pC,OAAM,uDACxBmmC,GAAI8D,IAAMH,EAAIC,gBAAgBJ,GAC9B9rC,EAAK8K,KAAOghC,EACZA,EAAWxD,KAGdwD,EAASrD,cAAiBqD,EAASnD,gBACpCmD,EAASzgC,OAAS,WACd,GAAIghC,GAAYrsC,EAAKssC,kBACjBD,KACArsC,EAAKssC,mBAAqB,KAG1BzkB,WAAW,WACP,IAAK,GAAIhY,GAAI,EAAGxD,EAAMggC,EAAUhsC,OAAQwP,EAAIxD,EAAKwD,IAC7Cw8B,EAAUx8B,MAEf,KAGXi8B,EAASvgC,QAAUwgC,EACnB9tC,KAAKquC,uBAETruC,KAAK6tC,SAAWA,EAMpBD,EAAaruC,UAAU+uC,OAAS,SAAS1gC,EAAQ7Q,GAC7CA,EAAUA,KAEV,IASIwxC,GATAxsC,EAAO/B,KACPwuC,EAAWxuC,KAAK6tC,SAASrD,aACzBiE,EAAYzuC,KAAK6tC,SAASnD,cAC1BC,EAAQ5tC,EAAQ4tC,MAChB3wB,EAASjd,EAAQid,OACjB2c,EAAW55B,EAAQ45B,SACnBD,EAAY35B,EAAQ25B,UACpB4U,GAAYtrC,KAAK6M,MAA2B,eAAnB7M,KAAK6M,KAAK1L,KACnC0J,EAAU+C,EAAO/C,QAAQ/M,aAG7B,OAAIkC,MAAKquC,uBACLruC,MAAKquC,mBAAmBxuC,KAAK,WAAakC,EAAKusC,OAAO1gC,EAAQ7Q,MAI9D4tC,IAAU3wB,EACVA,EAAUy0B,EAAY9D,EAAQ6D,GAAa,EACpCx0B,IAAW2wB,EAClBA,EAAS6D,EAAWx0B,EAASy0B,GAAc,GAE3C9D,EAAQ6D,EACRx0B,EAASy0B,GAET9X,GAAYgU,EAAQhU,IACpBgU,EAAQhU,EACR3c,EAAUy0B,EAAY9D,EAAQ6D,GAAa,GAE3C9X,GAAa1c,EAAS0c,IACtB1c,EAAS0c,EACTiU,EAAS6D,EAAWx0B,EAASy0B,GAAc,GAG/CF,GAAQ5D,MAAOA,EAAO3wB,OAAQA,GAC9Bjc,GAAGY,KAAK5B,EAAS,SAAS2xC,EAAYC,GAClCJ,EAAIG,GAAcC,IAGN,QAAZ9jC,GACC,WACG,GAAI+jC,GAAehhC,EAAOugC,GAC1B9C,GAAqBtpC,EAAK8rC,SAAU9rC,EAAK8K,KAAM0hC,EAAKjD,GAC/CrzB,KAAK,SAASrR,GACXgH,EAAOugC,IAAMvnC,EACbgoC,IAAiBhhC,EAAOugC,KAAOvgC,EAAOR,cAG/B,WAAZvC,GACP0gC,EAAoBvrC,KAAK6tC,SAAU7tC,KAAK6M,KAAMe,EAAQ2gC,EAAKjD,QAElC,kBAAlBtrC,MAAK6uC,UACZ7uC,KAAK6uC,SAASjhC,MAItB7P,GAAG6vC,aAAeA,KCtYtB7vC,GAAGm7B,eAAiB,SAAS/4B,GACzB,YAEA,SAAS2uC,GAAM3sC,GACX,MAAoC,QAA7BA,EAAG0I,QAAQ/M,cAGtB,QAASixC,GAAS5sC,GACd,MAAoC,WAA7BA,EAAG0I,QAAQ/M,cAGtB,QAASkxC,KACL,MAAmC3wC,WAA5B,GAAI0vC,QAAQkB,YAGvB,QAASC,KACL,GAAI3oC,GAAS2E,SAASC,cAAc,SAEpC,OAAO5E,GAAOqkC,YAAcrkC,EAAOqkC,WAAW,MAMlD,QAASuE,GAAwBC,GAE7B,GAAIC,GAAeD,EAAaznC,MAAM,KAClC5I,EAAOswC,EAAaA,EAAajtC,OAAS,GAAGuF,MAAM,KAAK,GACxD0nB,EAAYtxB,GAAG6U,aAAa7T,EAIhC,QAFAswB,EAAYA,GAAaA,EAAUvxB,eAG/B,IAAK,OACL,IAAK,MACD,MAAO,YACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,OACL,IAAK,MACD,MAAO,cASnB,QAASwxC,GAAcxU,GACnB,GACIyU,GAAgBC,EAAgBC,EADhCC,EAAexkC,SAASC,cAAc,IAS1C,OANAukC,GAAaC,KAAO7U,EAEpByU,EAAiBG,EAAaE,SAC9BH,EAAaC,EAAaG,KAC1BL,EAAiBE,EAAaI,SAE1BP,EAAezxC,gBAAkBqJ,OAAO4oC,SAASH,SAAS9xC,gBAI1D0xC,EAAe1xC,gBAAkBqJ,OAAO4oC,SAASD,SAAShyC,eAK1D2xC,IAAetoC,OAAO4oC,SAASF,OAAS9xC,GAAG4Q,MAOnD,QAASqhC,GAAyB3F,EAAKn9B,GACnCm9B,EAAIj9B,OAAS,WACTi9B,EAAIj9B,OAAS,KACbi9B,EAAI/8B,QAAU,KACdJ,EAAQG,QAAQg9B,IAGpBA,EAAI/8B,QAAU,WACV+8B,EAAIj9B,OAAS,KACbi9B,EAAI/8B,QAAU,KACdnN,EAAI,6BAA8B,SAClC+M,EAAQK,QAAQ88B,EAAK,+BAI7B,QAAS4F,GAAgC1pC,EAAQ2G,GAO7C3G,EAAO6mC,gBAAkB,WACrBlgC,EAAQG,QAAQ9G,IAQxB,QAAS2pC,GAAkCvuB,EAAazU,GACpD,GAAIijC,GAAarB,EAAMntB,IAAgBotB,EAASptB,EAahD,OAXImtB,GAAMntB,GACNquB,EAAyBruB,EAAazU,GAEjC6hC,EAASptB,GACdsuB,EAAgCtuB,EAAazU,IAG7CA,EAAQK,QAAQoU,GAChBxhB,EAAIpC,GAAG0L,OAAO,iDAAkDkY,EAAY9W,SAAU,UAGnFslC,EAKX,QAASC,GAAKjkC,EAAYkW,EAAWtlB,GACjC,GAAIszC,GAAc,GAAItyC,IAAGoP,QACrBub,EAAa,GAAI3qB,IAAGuyC,SAASnkC,EAAYhM,GACzCyhB,EAAU7kB,EAAQ6kB,QAElBgX,EAA2B,MAAlB77B,EAAQ67B,QAAwB77B,EAAQ67B,OACjD2X,EAAsB,WAClBluB,EAAU/U,QAAU,KACpB+U,EAAUjV,OAAS,KACnBjN,EAAI,mDAAoD,SACxDkwC,EAAY9iC,QAAQ8U,EAAW,gCAiDvC,OA9CAqG,GAAW8nB,gBAAgBv4B,KACvB,SAASzR,GAGL,GAAIiqC,IACI/9B,MAAO,WACH,OAAO,GAAI3U,IAAGoP,SAAUE,YAGhCqjC,EAAO9X,EAAS,GAAI76B,IAAG4yC,KAAKxkC,EAAYhM,GAAOswC,EAC/CG,EAAQ,GAAI7yC,IAAG6vC,aAAazhC,EAAYokC,EAExCL,GAAkC7tB,EAAWguB,IAC7CK,EAAKh+B,QAAQuF,KACT,SAASy4B,GACL,GAAIrE,GAAcqE,GAAQA,EAAKG,WAE/BD,GAAMtC,OAAOjsB,GACTsU,SAAU/U,EACV8U,UAAW9U,EACXyqB,YAAaA,EACb7lC,KAAMA,EACNylC,OAAQlvC,EAAQ+kB,wBAIxB,SAASgvB,GACL3wC,EAAIpC,GAAG0L,OAAO,iEAAkEqnC,IAEhFF,EAAMtC,OAAOjsB,GACTsU,SAAU/U,EACV8U,UAAW9U,EACXpb,KAAMA,EACNylC,OAAQlvC,EAAQ+kB,0BAOpC,WACI3hB,EAAI,mBACJkwC,EAAY9iC,QAAQ8U,EAAW,qBAIhCguB,EAGX,QAASU,GAAyBjW,EAAKkW,EAAaZ,EAAMxuB,EAASE,GAC/D,GAAImvB,GAAU,GAAIlD,OACdmD,EAAgB,GAAInzC,IAAGoP,OAE3B+iC,GAAkCe,EAASC,GAEvC5B,EAAcxU,KACdmW,EAAQhC,YAAc,aAG1BgC,EAAQ9C,IAAMrT,EAEdoW,EAAcj5B,KACV,WACIi4B,EAAkCc,EAAaZ,EAE/C,IAAIQ,GAAQ,GAAI7yC,IAAG6vC,aAAaqD,EAChCL,GAAMtC,OAAO0C,GACTra,SAAU/U,EACV8U,UAAW9U,EACXpb,KAAM2oC,EAAwBrU,GAC9BmR,OAAQnqB,KAIhBsuB,EAAK7iC,SAIb,QAAS4jC,GAA+BrW,EAAKuP,EAAK+F,EAAMxuB,GACpDsuB,EAAkC7F,EAAK+F,GAKvCryC,GAAGssC,GAAKrmC,KACJ2yB,SAAU/U,EAAU,KACpB8U,UAAW9U,EAAU,OAGzByoB,EAAI8D,IAAMrT,EAWd,QAASsW,GAAYtW,EAAKzY,EAAWtlB,GACjC,GAAIqzC,GAAO,GAAIryC,IAAGoP,QACdgV,EAAQplB,EAAQolB,MAChBP,EAAUO,EAAQplB,EAAQ6kB,QAAU,IA8BxC,OA3BIO,IAAS2sB,EAAMzsB,GAGX6sB,IAIII,EAAcxU,KAASkU,IACvBmC,EAA+BrW,EAAKzY,EAAW+tB,EAAMxuB,GAGrDmvB,EAAyBjW,EAAKzY,EAAW+tB,EAAMxuB,GAInDuvB,EAA+BrW,EAAKzY,EAAW+tB,EAAMxuB,GAIpDmtB,EAAS1sB,GACd0uB,EAAyBjW,EAAKzY,EAAW+tB,EAAMxuB,GAG1CsuB,EAAkC7tB,EAAW+tB,KAClD/tB,EAAU8rB,IAAMrT,GAGbsV,EAGXryC,GAAGwG,OAAOvE,MAWNsiB,SAAU,SAAS+uB,EAAehvB,EAAWtlB,GACzC,MAAIgB,IAAGoL,SAASkoC,IACZlxC,EAAI,4DACGixC,EAAYC,EAAehvB,EAAWtlB,SAG7CoD,EAAI,iDACGiwC,EAAKiB,EAAehvB,EAAWtlB,WAMlDiD,KAAKsxC,YACLtxC,KAAKsxC,SAASxC,MAAQA,EACtB9uC,KAAKsxC,SAASvC,SAAWA,EACzB/uC,KAAKsxC,SAAShC,cAAgBA,EAC9BtvC,KAAKsxC,SAASnC,wBAA0BA,GChT5CpxC,GAAG4yC,KAAO,SAASxkC,EAAYhM,GAC3B,YAYA,SAASoxC,GAAkBC,GAIvB,IAHA,GAAIpsC,GAAS,EACTqsC,EAAM,EAEHD,EAAIpvC,OAAS,GAChBgD,GAAUi9B,SAASmP,EAAItyC,UAAU,EAAG,GAAI,IAAMmF,KAAKotC,IAAI,EAAGA,GAC1DD,EAAMA,EAAItyC,UAAU,EAAGsyC,EAAIpvC,QAC3BqvC,GAAO,CAGX,OAAOrsC,GAKX,QAASssC,GAAWC,EAAQzkC,GACxB,GAAI0kC,GAAYD,EACZE,EAAa3kC,CAwBjB,OAvBkB7O,UAAduzC,IACAA,EAAY,EACZC,EAAa,GAAI9zC,IAAGoP,SAGxBpP,GAAG6O,cAAcT,EAAYylC,EAAW,GAAG35B,KAAK,SAASu5B,GACrD,GACIM,GADA1wC,EAAQ,cAAcnC,KAAKuyC,EAG3BpwC,GACiB,MAAbA,EAAM,IACN0wC,EAAgBzP,SAASmP,EAAI3zC,MAAM,EAAG,GAAI,IAC1C6zC,EAAWE,EAAYE,EAAgB,EAAGD,IAG1CA,EAAWxkC,QAAQukC,GAIvBC,EAAWtkC,QAAQ,iCAIpBskC,EAIX,QAASE,KACL,GAAI7kC,GAAU,GAAInP,IAAGoP,OAgBrB,OAdApP,IAAG6O,cAAcT,EAAY,EAAG,GAAG8L,KAAK,SAASu5B,GACjB,IAAxBA,EAAI5pC,QAAQ,QACZsF,EAAQK,QAAQ,qBAGhBmkC,IAAaz5B,KAAK,SAAS05B,GACvBzkC,EAAQG,QAAQskC,IAEpB,SAASzxC,GACLgN,EAAQK,QAAQrN,OAKrBgN,EAIX,QAAS8kC,GAAeC,GACpB,GAAI/kC,GAAU,GAAInP,IAAGoP,OAMrB,OAJApP,IAAG6O,cAAcT,EAAY8lC,EAAY,GAAI,GAAGh6B,KAAK,SAASu5B,GAC1DtkC,EAAQG,QAAgB,SAARmkC,KAGbtkC,EAIX,QAASglC,GAAiBD,EAAWE,GACjC,GAAIjlC,GAAU,GAAInP,IAAGoP,OAWrB,OATApP,IAAG6O,cAAcT,EAAY8lC,EAAY,GAAI,GAAGh6B,KAAK,SAASu5B,GAC1D,MAAIW,GACOjlC,EAAQG,QAAQkkC,EAAkBC,QAGzCtkC,GAAQG,QAAQg1B,SAASmP,EAAK,OAI/BtkC,EAIX,QAASklC,GAAOH,EAAWI,GACvB,GAAIV,GAASM,EAAY,GACrBxlC,EAAqB,GAAb4lC,CAEZ,OAAOt0C,IAAG6O,cAAcT,EAAYwlC,EAAQllC,GAIhD,QAAS6lC,GAAcC,GAInB,IAHA,GAAIp3B,MACAw2B,EAAS,EAENA,EAAS,IAAMY,EAAOnwC,QACzB+Y,EAAQtb,KAAK0yC,EAAO10C,MAAM8zC,EAAQA,EAAS,KAC3CA,GAAU,EAGd,OAAOx2B,GAIX,QAASq3B,GAAaL,EAAcE,GAChC,GAAII,GAAiB,GACjBC,EAAa30C,GAAGwG,UAAWouC,GAC3BC,IAsBJ,OApBA70C,IAAGY,KAAK0zC,EAAY,SAAS1yC,EAAK25B,GAC9B,GAGIuZ,GAAWhoC,EAASioC,EAHpBC,EAAQzZ,EAAMz7B,MAAM,EAAG,GACvBud,EAAK+2B,EAAeZ,EAAkBwB,GAAS1Q,SAAS0Q,EAAO,IAC/DC,EAAgBN,EAAW9qC,QAAQwT,EAYvC,IATI43B,GAAiB,IACjBnoC,EAAUooC,EAAS73B,GAAIrc,KACvB+zC,EAAeG,EAAS73B,GAAI3O,MAC5BomC,EAAYvZ,EAAMz7B,MAAM40C,EAAgBA,EAAiC,EAAfK,GAC1DF,EAAK/nC,GAAWsnC,EAAeZ,EAAkBsB,GAAaxQ,SAASwQ,EAAW,IAElFH,EAAWz1B,OAAO+1B,EAAe,IAGX,IAAtBN,EAAWtwC,OACX,OAAO,IAIRwwC,EApJX,GAAID,IAAW,KACXM,GACIC,KACIn0C,KAAM,cACN0N,MAAO,GAmJnB1O,IAAGwG,OAAOvE,MAON0S,MAAO,WACH,GAAIygC,GAAS,GAAIp1C,IAAGoP,QAChBimC,EAAiB,SAAShzC,GACtBD,EAAIpC,GAAG0L,OAAO,kCAAmCrJ,IACjD+yC,EAAO5lC,QAAQnN,GA0BvB,OAvBA2xC,KAAgB95B,KAAK,SAASo7B,GAC1BlzC,EAAIpC,GAAG0L,OAAO,mDAAwEpL,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,OAEtHizC,EAAeqB,GAAYp7B,KAAK,SAASk6B,GAErChyC,EAAIpC,GAAG0L,OAAO,+BAAgC0oC,EAAe,SAAW,QAExED,EAAiBmB,EAAYlB,GAAcl6B,KAAK,SAASq7B,GAErDnzC,EAAIpC,GAAG0L,OAAO,kCAAmC6pC,IAEjDlB,EAAOiB,EAAYC,GAAer7B,KAAK,SAASs6B,GAC5C,GAAIF,GAAaC,EAAcC,GAC3BgB,EAAYf,EAAaL,EAAcE,EAE3ClyC,GAAI,sCAEJgzC,EAAO9lC,QAAQkmC,IAChBH,IACJA,IACJA,IACJA,GAEID,KAKfnzC,KAAKsxC,YACLtxC,KAAKsxC,SAASC,kBAAoBA,GC7MtCxzC,GAAGuyC,SAAW,SAASnkC,EAAYhM,GAC/B,YAEA,SAASqzC,GAAeC,EAAYC,GAChC,GAAIC,IAAe,EACfC,KAAuBziC,OAAOsiC,EASlC,OAPA11C,IAAGY,KAAKi1C,EAAmB,SAASj0C,EAAKk0C,GACrC,GAAwD,IAApDH,EAAkB9rC,QAAQisC,GAE1B,MADAF,IAAe,GACR,IAIRA,EAGX51C,GAAGwG,OAAOvE,MASNwwC,cAAe,WACX,GAAIzuC,GAAO/B,KACP0oB,EAAa,GAAI3qB,IAAGoP,QACpB2mC,GAAc,EACd/0C,EAA2BV,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,IAsC/D,OApCAoB,GAAIpC,GAAG0L,OAAO,gEAAiE1K,IAE/EoB,EAAI,oDAEAH,KAAK+zC,qBACL5zC,EAAI,sDAEJpC,GAAG6O,cAAcT,EAAY,EAAG,GAAG8L,KAAK,SAASu5B,GAC7CzzC,GAAGY,KAAKoD,EAAKiyC,uBAAwB,SAASxtC,EAAMiG,GAChD,GAAI+mC,EAAe/mC,EAAO+kC,GAQtB,OALa,eAAThrC,GAAyBzI,GAAGiW,kBAAkBwD,gBAC9Cs8B,GAAc,EACdprB,EAAWrb,QAAQ7G,KAGhB,IAIfrG,EAAIpC,GAAG0L,OAAO,iDAAkD1K,EAAM+0C,EAAc,GAAK,QAEpFA,GACDprB,EAAWnb,WAGnB,WACIpN,EAAI,+BAAiCpB,EAAO,gDAC5C2pB,EAAWnb,aAIfmb,EAAWnb,UAGRmb,GAWXqrB,kBAAmB,WACf,GAAIE,GAAW9nC,EAAWhL,KAEtB+yC,EAAoBn2C,GAAG6J,QAAQW,OAAO23B,KAAKlgC,KAAKg0C,wBAAyBC,IAAa,EACtFH,GAAc,EACd/0C,EAA2BV,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,IAa/D,OAXIm1C,KAEIJ,EADa,eAAbG,GACcl2C,GAAGiW,kBAAkBwD,eAO1Cs8B,GAAe3zC,EAAIpB,EAAO,gEAEpB+0C,MAKnB/1C,GAAGuyC,SAAS/wC,UAAUy0C,wBAClBG,aAAc,SACdC,YAAa,SACbC,YAAa,SACbC,YAAa,OACbC,cAAe,WAAY,aCpG/Bx2C,GAAG23B,gBAAkB,SAAS7oB,EAAM1M,GAChC,YAMA,SAASq0C,GAAiBC,GACtB,GAAIC,IAAa,CASjB,OAPA32C,IAAGY,KAAK81C,EAAQ,SAASE,EAAOjsC,GAC5B,GAAIA,EAAQ,EAER,MADAgsC,IAAa,GACN,IAIRA,EAQX,QAASE,KACL,GAAIC,GAAoB,GAAI92C,IAAGoP,OA6B/B,OA3BA,IAAIpP,IAAGuyC,SAASzjC,EAAM1M,GAAKqwC,gBAAgBv4B,KAAK,WAC5C,GAAI2d,GAAQ,GAAImY,OACZjT,EAAM3zB,OAAO6mC,KAAO7mC,OAAO6mC,IAAIC,gBAAkB9mC,OAAO6mC,IAClD7mC,OAAO+mC,WAAa/mC,OAAO+mC,UAAUD,gBAAkB9mC,OAAO+mC,UAC9D,IAENpT,IACAlF,EAAMtoB,QAAU,WACZnN,EAAI,4DAA6D,SACjE00C,EAAkBtnC,WAGtBqoB,EAAMxoB,OAAS,WACXynC,EAAkBxnC,SACds9B,MAAO3qC,KAAK2qC,MACZ3wB,OAAQha,KAAKga,UAIrB4b,EAAMuY,IAAMrT,EAAImT,gBAAgBphC,KAGhC1M,EAAI,+DAAgE,SACpE00C,EAAkBtnC,YAEvBsnC,EAAkBtnC,SAEdsnC,EASX,QAASC,GAAgBL,EAAQM,GAC7B,GAAIC,EA0BJ,OAxBAj3C,IAAGY,KAAK81C,EAAQ,SAASQ,EAAWC,GAChC,GAAIA,EAAa,EAAG,CAChB,GAAIC,GAAe,0BAA0Bl2C,KAAKg2C,GAC9CG,EAAoBD,EAAa,GAAGx3C,OAAO,GAAGG,cAAgBq3C,EAAa,GAAGt3C,MAAM,GACpFw3C,EAAcN,EAAWK,EAG7B,QAAQD,EAAa,IACjB,IAAK,MACD,GAAIE,EAAcH,EAEd,MADAF,GAAeC,GACR,CAEX,MACJ,KAAK,MACD,GAAII,EAAcH,EAEd,MADAF,GAAeC,GACR,MAOpBD,EAWXh1C,KAAK21B,SAAW,SAAS8e,GACrB,GAAIa,GAAmB,GAAIv3C,IAAGoP,OAoB9B,OAlBAhN,GAAI,iCAEAq0C,EAAiBC,GACjBG,IAAiB38B,KAAK,SAAS88B,GAC3B,GAAIC,GAAeF,EAAgBL,EAAQM,EAEvCC,GACAM,EAAiB/nC,QAAQynC,GAGzBM,EAAiBjoC,WAEtBioC,EAAiBjoC,SAGpBioC,EAAiBjoC,UAGdioC,IC7Hfv3C,GAAG42B,QAAU,SAASvY,GAClB,YAaA,SAASm5B,GAAoB9jB,GACzB,QAAI1zB,GAAG8C,QAAQ4wB,QAIf10B,GAAQoD,IAAI,oCAAqC,SAGrD,QAASq1C,GAAgBC,EAAWpoC,EAAS0a,EAAU7a,GACnD,GAAIwoC,IAAmB,CAEvBroC,GAAUA,GAAWkoC,EAAoBE,GAErCpoC,GACAtP,GAAGY,KAAK82C,EAAW,SAAS91C,EAAKw+B,GAE7B,GAAqB,MAAjBA,EAAS5iB,KACTm6B,GAAmB,EACnB34C,EAAQoD,IAAIpC,GAAG0L,OAAO,oEAAqE9J,GAAM,aAEhG,IAAqB,MAAjBw+B,EAASp/B,KACd22C,GAAmB,EACnB34C,EAAQoD,IAAIpC,GAAG0L,OAAO,oEAAqE9J,GAAM,aAGjG,KAEI,MADA5C,GAAQ83B,cAAcsJ,IACf,EAEX,MAAOwX,GACHD,GAAmB,EACnB34C,EAAQoD,IAAIw1C,EAAIv1C,QAAS,SAIjC,OAAO,IAIf8M,EAAQG,IAAYqoC,EAAmB,UAAY,WAAWD,EAAW1tB,GAlD7E,GAAIhrB,IACA8hB,SAAU,KACVthB,UACAiqB,iBACAG,QACAkN,cAAe,SAAStO,KACxBpmB,IAAK,SAASC,EAAS+H,KAG3BpK,IAAGwG,OAAOxH,EAASqf,GAAM,GA8CzBpc,KAAK80B,QAAU,WAEX,GAAI8gB,GAAgB,GAAI73C,IAAGoP,QACvB0oC,EAA0B,SAASpkB,EAAUpkB,EAAS0a,GAClDytB,EAAgB/jB,EAAUpkB,EAAS0a,EAAU6tB,IAEjDE,EAAmB/3C,GAAGwG,UAAWxH,GACjCotC,EAAY,GAAIpsC,IAAGg4C,qBACfh4C,GAAGwG,OAAOuxC,GAAmBxqB,WAAYuqB,IAKjD,OAFA1L,GAAU6L,cAEHJ,ICrEf73C,GAAGg4C,qBAAuB,SAAS35B,GAC/B,YAiBA,SAASkP,GAAWlQ,EAAI2M,EAAUC,GAC9B,GAAIyJ,GAAW,IAGf,IAA6B,MAAzB1J,EAASkuB,aACT,IACIxkB,EAAW1zB,GAAGwU,UAAUwV,EAASkuB,cAErC,MAAON,GACH54C,EAAQoD,IAAI,qCAAuCw1C,EAAIv1C,QAAS,SAChE4nB,GAAU,EAIlBjrB,EAAQuuB,WAAWmG,GAAWzJ,EAASD,GA7B3C,GAAIoiB,GACAptC,GACI8hB,SAAU,KACV2I,iBACAjqB,UACAoqB,MACIoI,UAAU,EACVyI,iBAAiB,GAErBlN,WAAY,SAASmG,EAAUpkB,EAAS0a,KACxC5nB,IAAK,SAASuJ,EAAKvB,KAG3BpK,IAAGwG,OAAOxH,EAASqf,GAmBnB+tB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAe,OACfvV,OAAQ,MACRO,eACI5E,IAAK,WACD,MAAO/lB,GAAQ8hB,WAGvB2I,cAAezqB,EAAQyqB,cACvBrnB,IAAKpD,EAAQoD,IACbmrB,WAAYA,EACZ3D,KAAM5qB,EAAQ4qB,QAGlB5pB,GAAGwG,OAAOvE,MACNg2C,YAAa,WACT,GAAIz4C,GAASQ,GAAGwG,UAAWxH,EAAQQ,OAEnCR,GAAQoD,IAAI,0BAEZgqC,EAAUnN,cAAc,kBACnBK,WAAW9/B,GACXogC,kBACAjC,WCzDjB39B,GAAGgnB,OAAS,SAAS3I,EAAMjc,GACvB,YAEA,IACI2hB,GAAuB1F,EAAKsc,cAC5Bwd,EAAkB95B,EAAKuc,aACvBC,EAASxc,EAAKwc,OACdC,EAAczc,EAAKyc,YACnBC,EAAiB1c,EAAK0c,eAAiB,IACvCqd,EAAoB/5B,EAAK2c,YACzBC,EAAc5c,EAAK4c,YACnBC,EAAQj5B,KAAKo2C,gBAAgBh6B,EAAK6c,MAGtCl7B,IAAGwG,OAAOvE,MAGNihB,QAASljB,GAAGiW,kBAAkBuD,SAAW0hB,EAAM72B,OAAS,EAExDi0C,eAAgB,SAASC,EAAkBC,EAAkBC,GACzD,GAAIz0C,GAAO/B,KACPy2C,KACAC,EAAeF,EAAuB3pC,KAAO2pC,EAAuB3pC,KAAO2pC,EAC3E9tB,EAAa,GAAI3qB,IAAGuyC,SAASoG,EAAcv2C,EAiD/C,OA9CIuoB,GAAWqrB,qBAEXh2C,GAAGY,KAAKs6B,EAAO,SAASt5B,EAAKg3C,GACzB,GAAIC,GAAa70C,EAAK80C,sBAClBhe,YAAaA,EACbie,cAAeH,EAAWx1C,KAC1B41C,QAASL,EAAav1C,MAG1Bs1C,GAAQ52C,MACJ0b,KAAMxd,GAAGuQ,cACTvP,KAAMgD,EAAKi1C,SAAST,GAChBx3C,KAAM43C,EAAW53C,KACjBoC,KAAMy1C,EACNG,QAASL,EAAav1C,OAE1B0L,KAAM,GAAI9O,IAAG4a,UAAU+9B,EACvB34C,GAAGgT,KAAKhP,EAAKk1C,qBAAsBl1C,GAC/B+f,qBAAsBA,EACtBF,QAAS+0B,EAAW/0B,QACpBgX,OAAQA,EACRz3B,KAAMy1C,EACNnwC,QAASqyB,EACToe,WAAYf,EACZnd,YAAaA,EACb74B,IAAKA,SAKjBs2C,EAAQ52C,MACJ0b,KAAM+6B,EACNv3C,KAAMw3C,EACNh6B,KAAMm6B,EAAan6B,KACnB1P,KAAMqpC,EAAkBQ,EAAe,QAI3CD,EAAQ52C,MACJ0b,KAAM+6B,EACNv3C,KAAMw3C,EACNh6B,KAAMm6B,EAAan6B,KACnB1P,KAAM6pC,IAIPD,GAGXrd,cAAe,SAAShZ,EAAMrhB,EAAMwc,EAAMgB,EAAM4S,EAAU3S,EAAS6K,EAAe8vB,GAC9E,GAAIp1C,GAAO/B,KAEPo3C,GADWh3B,EAAKyG,YAAezG,EAAKvT,MAAQuT,EAAKvT,KAAKga,eAEtDwwB,EAAa,KACbpoB,EAAmBkoB,EAAIloB,iBACvBlO,EAAao2B,EAAIp2B,WACjB0G,EAAc0vB,EAAI1vB,YAClBhL,EAAe1e,GAAGuQ,aAEtBvQ,IAAGY,KAAKoD,EAAKs0C,eAAe96B,EAAMxc,EAAMqhB,GAAO,SAASzgB,EAAK23C,GACzD,GACIl8B,GADAm8B,EAAWD,EAAO/6B,IAGlB+6B,GAAOzqC,eAAgB9O,IAAG4a,YAC1B4+B,GAAW,GAGfn8B,EAAK2F,EAAW5E,SACZZ,KAAM+7B,EAAO/7B,KACbxc,KAAMu4C,EAAOv4C,KACbwd,KAAMg7B,EACN/6B,QAASA,EACTC,aAAcA,IAGd66B,EAAOzqC,eAAgB9O,IAAG4a,UAC1By+B,EAAUv3C,KAAKub,GAGfi8B,EAAaj8B,EAGbk8B,EAAOzqC,MACPoiB,EAAiB7T,EAAIk8B,EAAOzqC,MAC5BsiB,EAAStvB,MAAMub,GAAIA,EAAIgF,KAAMk3B,EAAOzqC,QAGpCkU,EAAWlE,UAAUzB,EAAIrd,GAAG2d,OAAOqC,YAOxB,OAAfs5B,IACAt5C,GAAGY,KAAKy4C,EAAW,SAASz3C,EAAK63C,GAC7B,GAAIj6C,IACAk6C,aAAc12B,EAAWpE,UAAUvB,GAAIi8B,IAAa97B,KACpDm8B,aAAc32B,EAAWpE,UAAUvB,GAAIi8B,IAAa96B,KAKxDhf,GAAO8pB,GAAiBtG,EAAWpE,UAAUvB,GAAIo8B,IAAWj8B,KAE5DwF,EAAWtD,YAAY+5B,EAAUH,GACjC5vB,EAAY+B,YAAYguB,EAAUj6C,KAKlC65C,EAAUh1C,SACT,WACG,GAAIu1C,KACJA,GAAMtwB,GAAiBtG,EAAWpE,UAAUvB,GAAIi8B,IAAa97B,KAC7DkM,EAAY+B,YAAY6tB,EAAYM,WAQ5D55C,GAAGwG,OAAOxG,GAAGgnB,OAAOxlB,WAChBslB,WAAY,SAASzJ,EAAI0J,EAAOqyB,GAC5B,YAEA,KAAKp5C,GAAGiW,kBAAkBuD,QACtB,KAAM,IAAIxZ,IAAGmG,MAAM,4CAGvB,IAAI0zC,GAAgB,GAAI75C,IAAGoP,QACvBhN,EAAMg3C,EAAIh3C,IACVigB,EAAO+2B,EAAI/0B,QAAQhH,GACnB2F,EAAao2B,EAAIp2B,WAAWpE,UAAUvB,GAAIA,IAC1Crc,EAAOgiB,GAAcA,EAAWhiB,KAChCwc,EAAOwF,GAAcA,EAAWxF,KAChCs8B,GACInf,cAAe5T,EAAM4T,cACrBC,cAAc,EACdC,OAAQ9T,EAAM8T,OACdC,YAAa/T,EAAM3jB,MAAQ,KAC3B23B,eAAgBhU,EAAMre,QACtB0vC,kBAAmB,kBACnBld,QAASl6B,KAAM,GAAI6iB,QAASkD,EAAMlD,WAEtCk2B,EAAS,GAAI/5C,IAAGgnB,OAAO8yB,EAAgB13C,EAuB3C,OArBKpC,IAAGgnB,QAAWhnB,GAAGiW,kBAAkBiD,eAAkBmJ,EAOrDriB,GAAGgT,KAAK,WAEL,GAAIumC,GAASQ,EAAOzB,eAAe96B,EAAMxc,EAAMqhB,GAAM,EAEjDk3B,IAAUA,EAAOzqC,eAAgB9O,IAAG4a,UACpC2+B,EAAOzqC,KAAKiM,SAASb,KAAK2/B,EAAcvqC,QAASuqC,EAAcrqC,UAG/DpN,EAAIib,EAAK,4BAA6B,SACtCw8B,EAAcrqC,YAEnBvN,SAjBH43C,EAAcrqC,UAEdpN,EAAI,iDAAmDib,EAAK,uFAC6B,UAiBtFw8B,GAKXf,qBAAsB,SAASz6B,GAC3B,YAEA,IAAI06B,GAAgB16B,EAAK06B,cACrBje,EAAczc,EAAKyc,YACnBkf,EAAgB37B,EAAK26B,OAIzB,OAAKle,IAAgBie,EAQhBA,GAKD/4C,GAAG6J,QAAQW,OAAO23B,KAAKniC,GAAGuyC,SAAS/wC,UAAUy0C,wBAAyB8C,IAAkB,EAClE,eAAlBA,EACO/4C,GAAGiW,kBAAkBwD,aAAes/B,EAAgBje,EAGxDie,EATAje,EARe,eAAlBkf,EACO,YAEJA,GAqBff,SAAU,SAAS16B,EAAc07B,GAC7B,YAEA,IAAIC,GAAa37B,EAAavJ,YAAY,KACtCmlC,EAAcF,EAAwB72C,MAAQ,YAC9C42C,EAAgBC,EAAwBjB,QACxCoB,EAAa,GACbC,EAAYr6C,GAAG6U,aAAa0J,GAC5B+7B,EAAgB,EAmBpB,OAjBIL,GAAwBj5C,MAAQi5C,EAAwBj5C,KAAKyK,OAAOpH,SACpEi2C,EAAgB,KAAOL,EAAwBj5C,KAAO,KAGtDk5C,GAAc,GACdE,EAAa77B,EAAatJ,OAAO,EAAGilC,GAEhCF,IAAkBG,IAClBE,EAAYF,EAAYvwC,MAAM,KAAK,IAGvCwwC,GAAcE,EAAgB,IAAMD,GAGpCD,EAAa77B,EAAe+7B,EAGzBF,GAIX/B,gBAAiB,SAASnd,GACtB,YAIA,OAFAA,GAAQl7B,GAAGwG,UAAW00B,GAEfA,EAAMqf,KAAK,SAASC,EAAGC,GAC1B,MAAID,GAAE32B,QAAU42B,EAAE52B,QACP,EAEP22B,EAAE32B,QAAU42B,EAAE52B,SACP,EAEJ,KAIfq1B,qBAAsB,SAAS76B,EAAMq8B,GACjC,YAEA,IAAI12C,GAAO/B,KACP8hB,EAAuB1F,EAAK0F,qBAC5B3hB,EAAMic,EAAKjc,IACXyhB,EAAUxF,EAAKwF,QACfgX,EAASxc,EAAKwc,OACdz3B,EAAOib,EAAKjb,KACZsF,EAAU2V,EAAK3V,QACfywC,EAAa96B,EAAK86B,WAClBle,EAAc5c,EAAK4c,aAAmC,eAApByf,EAAWt3C,MAAkC,eAATA,EACtEy2C,EAAgB,GAAI75C,IAAGoP,QACvBurC,EAAiB,GAAI36C,IAAGm7B,eAAe/4B,GACvCoG,EAAS2E,SAASC,cAAc,SA8BpC,OA5BAhL,GAAI,6CAA+Cs4C,EAAW15C,MAE9D25C,EAAep2B,SAASm2B,EAAYlyC,GAASqb,QAASA,EAASgX,OAAQA,EAAQ9W,qBAAsBA,IAAuB7J,KAAK,WAC7H,GAAI0gC,GAAqBpyC,EAAOI,UAAUxF,EAAMsF,GAC5CmyC,EAAgB,WACZz4C,EAAI,yCAA2Cs4C,EAAW15C,KAC1D,IAAI8N,GAAO9O,GAAG2I,cAAciyC,EAC5Bf,GAAcvqC,QAAQR,GAG1BmsB,GACAj3B,EAAK82C,kBAAkBJ,EAAYE,EAAoBx4C,GAAK8X,KAAK,SAAS6gC,GACtEH,EAAqBG,EACrBF,KAEJ,WACIz4C,EAAI,wFAAyF,SAC7Fy4C,MAIJA,KAEL,WACCz4C,EAAI,iDAAmDs4C,EAAW15C,KAAM,SACxE64C,EAAcrqC,QAAQ2pC,KAGnBU,GAIXiB,kBAAmB,SAASE,EAAeJ,EAAoBx4C,GAC3D,YAEA,IAAI64C,GAAS,GAAI/rC,YACbgsC,EAAkB,GAAIl7C,IAAGoP,QACzB+rC,EAAuB,EAc3B,OAZAF,GAAO5rC,OAAS,WACZ8rC,EAAuBF,EAAO5zC,OAC9B6zC,EAAgB5rC,QAAQtP,GAAGo7C,aAAahM,QAAQ+L,EAAsBP,KAG1EK,EAAO1rC,QAAU,WACbnN,EAAI,mBAAqB44C,EAAch6C,KAAO,2DAA4D,SAC1Gk6C,EAAgB1rC,WAGpByrC,EAAOI,cAAcL,GAEdE,GAGXI,eAAgB,SAASzyC,GACrB,YAEA,IAAIE,GAAYE,EAAYH,EAAaE,CAsBzC,OAlBID,GADAF,EAAQe,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKjB,EAAQe,MAAM,KAAK,IAGxBG,UAAUlB,EAAQe,MAAM,KAAK,IAI9CX,EAAaJ,EAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBd,EAAc,GAAIkB,aAAYjB,EAAW1E,QACzC2E,EAAW,GAAIiB,YAAWnB,GAC1B9I,GAAGY,KAAKmI,EAAY,SAASnH,EAAKsI,GAC9BlB,EAASpH,GAAOsI,EAAUC,WAAW,KAGlClI,KAAKs5C,YAAYzyC,EAAaG,IAGzCsyC,YAAa,SAASl7C,EAAMoI,GACxB,YAEA,IAAIU,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOpJ,GACZmJ,EAAYE,QAAQjB,IAGpB,GAAIkB,OAAMtJ,IAAQ+C,KAAMqF,OChZ3CzI,GAAGo7C,aAAe,WAGjB,GAAIA,KA+KD,OA7KAA,GAAaI,QAAU;AAMvBJ,EAAaK,SAAW,SAASvuC,GAE7B,GACIwuC,GAAMC,EACNC,EAAMC,EAAMC,EAFZC,EAAS,GACGC,EAAO,GACDC,EAAO,GACzBpoC,EAAI,CAER,GACI6nC,GAAOxuC,EAAM2G,KACb8nC,EAAOzuC,EAAM2G,KACbmoC,EAAO9uC,EAAM2G,KAEb+nC,EAAOF,GAAQ,EACfG,GAAgB,EAAPH,IAAa,EAAMC,GAAQ,EACpCG,GAAgB,GAAPH,IAAc,EAAMK,GAAQ,EACrCC,EAAc,GAAPD,EAEHE,MAAMP,GACPG,EAAOG,EAAO,GACNC,MAAMF,KACdC,EAAO,IAGVF,EAASA,EACN95C,KAAKu5C,QAAQ57C,OAAOg8C,GACpB35C,KAAKu5C,QAAQ57C,OAAOi8C,GACpB55C,KAAKu5C,QAAQ57C,OAAOk8C,GACpB75C,KAAKu5C,QAAQ57C,OAAOq8C,GACvBP,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SACvBpoC,EAAI3G,EAAM7I,OAEnB,OAAO03C,IAGXX,EAAahM,QAAU,SAAS+M,EAAgBC,GAE5C,GAAIC,GAAuB,yBAE3B,KAAKF,EAAe94C,MAAMg5C,GAEzB,MAAOD,EAGR,IAAIE,GAAWr6C,KAAKs6C,SAASJ,EAAel1C,QAAQo1C,EAAsB,KACtEG,EAAWv6C,KAAKw6C,eAAeH,GAE/BzkB,EAAQ51B,KAAKy6C,iBAAiBN,EAAmBI,EAErD,OAAOH,GAAuBp6C,KAAKw5C,SAAS5jB,IAKhDujB,EAAasB,iBAAmB,SAASN,EAAmBI,GAEpD,GAAIG,GAAY16C,KAAK26C,aAAaJ,GAC9BK,EAAgB56C,KAAK66C,WAAWV,EAAmBO,GACnDI,EAAU,GAAI9yC,YAAW4yC,EAE7B,OAAOE,IAIf3B,EAAawB,aAAe,SAASJ,GAG7B,IAAK,GADDQ,GACKC,EAAI,EAAGA,EAAIT,EAASn4C,OAAQ44C,IAGjC,GADAD,EAAMR,EAASS,GACD,KAAVD,EAAI,GAAsB,KAAVA,EAAI,GAEpB,MAAOA,EAGf,WAIR5B,EAAa0B,WAAa,SAASV,EAAmBO,GAE9C,GAAIO,GAAYd,EAAkBn1C,QAAQ,0BAA2B,IACjEk2C,EAAMl7C,KAAKs6C,SAASW,GACpBE,EAAgBD,EAAItzC,QAAQ,IAAI,GAChCwzC,EAAMF,EAAIr9C,MAAM,EAAGs9C,GACnBE,EAAMH,EAAIr9C,MAAMs9C,GAChBG,EAAQF,CAIb,OAFCE,GAAQA,EAAMnqC,OAAOupC,GACrBY,EAAQA,EAAMnqC,OAAOkqC,IAM7BlC,EAAaqB,eAAiB,SAASe,GAKnC,IAHA,GAAIC,GAAO,EACPjB,OAGJ,CACI,GAA2B,KAAvBgB,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAAW,KACjE,IAA2B,KAAvBD,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAElDA,GAAQ,MAGZ,CACI,GAAIp5C,GAAmC,IAA1Bm5C,EAAcC,EAAO,GAAWD,EAAcC,EAAO,GAC9DC,EAAWD,EAAOp5C,EAAS,EAC3B24C,EAAMQ,EAAc19C,MAAM29C,EAAMC,EACpClB,GAAS16C,KAAKk7C,GACdS,EAAOC,EAEX,GAAID,EAAOD,EAAcn5C,OAAQ,MAGrC,MAAOm4C,IAKXpB,EAAamB,SAAW,SAASrvC,GAE7B,GACIwuC,GAAMC,EACNC,EAAMC,EAAMC,EADAE,EAAO,GACDC,EAAO,GACzBpoC,EAAI,EACJspC,KAGAQ,EAAa,qBACjB,IAAIA,EAAWz8C,KAAKgM,GAChB,KAAM,IAAI/G,OAAM,uHAGpB+G,GAAQA,EAAMjG,QAAQ,sBAAuB,GAE7C,GACI20C,GAAO35C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCgoC,EAAO55C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCioC,EAAO75C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCooC,EAAOh6C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MAEzC6nC,EAAQE,GAAQ,EAAMC,GAAQ,EAC9BF,GAAgB,GAAPE,IAAc,EAAMC,GAAQ,EACrCE,GAAgB,EAAPF,IAAa,EAAKG,EAE3BkB,EAAIr7C,KAAK45C,GAEG,IAARI,GACDqB,EAAIr7C,KAAK65C,GAEA,IAARM,GACDkB,EAAIr7C,KAAKk6C,GAGZN,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SAEvBpoC,EAAI3G,EAAM7I,OAEnB,OAAO84C,IAIJ/B,KC7KXp7C,GAAGs7B,cAAgB,SAAS1oB,EAAUyS,GAClC,YAEA,IAAIu4B,MACAC,EAAc,EACdC,EAAY,EAEZC,GAAiB,EACjBC,GAAgB,EAChBC,EAAgB,SAAS7wB,EAAQC,GACzBD,IAAW2wB,GAAkB1wB,IAAU2wB,GACvCprC,EAASwa,EAAQC,GAGrB0wB,EAAiB3wB,EACjB4wB,EAAgB3wB,GAQpB6wB,EAAmB,SAAS7pB,EAAQ8pB,GAChC,GAAIC,IAAO,CASX,OAPAp+C,IAAGY,KAAKyzB,EAAQ,SAASzyB,EAAKy8C,GAC1B,GAAIr+C,GAAG6J,QAAQs0C,EAAWE,IAAa,EAEnC,MADAD,IAAO,GACA,IAIRA,GAGX3wB,EAAW,SAASpQ,GAChBihC,EAAoBjhC,GAAI,GAAI,SACrBugC,GAAgBvgC,IAG3BiX,EAAgB,SAASF,EAAYC,EAAQ8pB,IACnB,IAAlB9pB,EAAOhwB,QAAgB65C,EAAiB7pB,EAAQ8pB,MAChDF,EAAcH,EAAWA,GACzB77C,KAAK8a,UAIbwhC,EAAQ,SAASlhC,GACb,GAAImB,GAAO6G,EAAQhI,EAGfmB,GAAO,IACP8/B,EAAoBjhC,EAAI,EAAGmB,GAC3Bo/B,EAAgBvgC,IAAO+P,OAAQ,EAAGC,MAAO7O,KAYjD8/B,EAAsB,SAASjhC,EAAImhC,EAAWC,GAC1C,GAAIC,GAAYd,EAAgBvgC,GAAMugC,EAAgBvgC,GAAI+P,OAAS,EAC/DuxB,EAAWf,EAAgBvgC,GAAMugC,EAAgBvgC,GAAIgQ,MAAQ,CAE7DmxB,MAAc,GAAMC,KAAa,GACjCZ,GAAea,EACfZ,GAAaa,IAGTH,IACAX,GAAeW,EAAYE,GAE3BD,IACAX,GAAaW,EAAWE,IAIhCV,EAAcJ,EAAaC,GAGnC99C,IAAGwG,OAAOvE,MAENqyB,cAAeA,EAGf3V,eAAgB,SAAStB,EAAI2B,EAAWD,GAChCA,IAAc/e,GAAG2d,OAAOuC,UAAYnB,IAAc/e,GAAG2d,OAAOqC,SAC5DyN,EAASpQ,GAEJ0B,IAAc/e,GAAG2d,OAAOW,YAC7BigC,EAAMlhC,IAKd4X,qBAAsB,SAAS5X,EAAI+P,EAAQC,GACvCixB,EAAoBjhC,EAAI+P,EAAQC,GAChCuwB,EAAgBvgC,IAAO+P,OAAQA,EAAQC,MAAOA,IAIlD6J,UAAW,SAAS7Z,GAChBkhC,EAAMlhC,IAGVN,MAAO,WACH6gC,KACAC,EAAc,EACdC,EAAY,MCzHxB99C,GAAGoqB,aAAe,SAASnP,GACvB,YAYA,SAAS2jC,GAAQ1zC,GACb,MAAOA,GAAK9H,MACwB,IAAhC8H,EAAK9H,KAAKyG,QAAQ,UAG1B,QAASg1C,KACLC,EAAqB9+C,GAAGhB,EAAQqrB,eAAellB,OAAO,QAAS,SAASuxB,GACpE,GAAIqoB,GAAgBroB,EAAMqoB,aAEtBA,IACA/+C,GAAGY,KAAKm+C,EAAclxC,MAAO,SAASjM,EAAKsJ,GACvC,GAAI0zC,EAAQ1zC,GAAO,CACf,GAAI4D,GAAO5D,EAAK8zC,WAChBhgD,GAAQ2B,UAAU4pB,cAAczb,QAOpD,QAASmwC,KACDH,GACAA,IAhCR,GAAI9/C,GAAS8/C,CAEb9/C,IACIqrB,cAAe,KACf1pB,WACIyB,IAAK,SAASC,EAAS+H,KACvBmgB,cAAe,SAASzb,OA8BhC9O,GAAGwG,OAAOxH,EAASic,GACnB4jC,IAEA7+C,GAAGwG,OAAOvE,MACN8a,MAAO,WACHkiC,QCpCZj/C,GAAGyxB,YAAc,SAASzyB,EAASkgD,EAAa98C,GAC5C,YAgCA,SAAS+8C,GAAqBC,GACtBA,EAAO92C,aAAa,YACpBtE,EAAK8tB,YAAcstB,EAAO92C,aAAa,WAM/C,QAAS+2C,GAAaD,EAAQE,GAC1B,QAAIF,EAAOG,gBAAkBH,EAAOG,mBAChCn9C,EAAI,yDAA0D,aAC9Dk9C,MAQR,QAASE,GAAoBJ,GACzB,GAAIE,GAAeF,EAAOK,MAG1Bz/C,IAAGo/C,GAAQj6C,OAAO,SAAU,SAASuxB,GACjCA,EAAQA,GAASttB,OAAOstB,MAEpBA,EAAMtkB,eACNskB,EAAMtkB,iBAGNskB,EAAMpkB,aAAc,EAGxB+sC,EAAaD,EAAQE,IAAiBJ,MAK1CE,EAAOK,OAAS,WACZJ,EAAaD,EAAQE,IAAiBJ,KAM9C,QAASQ,GAAgBN,GAarB,MAZIA,KACIp/C,GAAGoL,SAASg0C,KACZA,EAASjyC,SAAS85B,eAAemY,IAGjCA,IACAh9C,EAAI,8BACJ+8C,EAAqBC,GACrB1kB,GAAmB8kB,EAAoBJ,KAIxCA,EAzFX,GAAIp7C,GAAQ/B,KACRy4B,EAAkB17B,EAAQ07B,gBAC1B0kB,EAASpgD,EAAQ0D,QACjBkvB,EAAa5yB,EAAQ4yB,UAGzB5xB,IAAGwG,OAAOvE,MAIN6vB,YAAa,KAIbD,cAAeD,EAGfF,gBAAgB,EAGhBC,sBAAuB,WAEnB,MAAc,OAAVytB,EACO,KAGJp7C,EAAK27C,UAAUP,MAkE9BA,EAASM,EAAgBN,GACzBn9C,KAAKyvB,iBAAmB0tB,GAG5Bp/C,GAAGwG,OAAOxG,GAAGyxB,YAAYjwB,WAGrBm+C,UAAW,SAAStrC,GAChB,YACA,IAAIf,MACAssC,EAAoB,SAASx8C,GACzB,GAAIy8C,IACA,SACA,QACA,QACA,SAGJ,OAAO7/C,IAAG6J,QAAQg2C,EAAiBz8C,EAAKrD,eAAiB,GAE7D+/C,EAAkB,SAAS18C,GACvB,MAAOpD,IAAG6J,SAAS,WAAY,SAAUzG,EAAKrD,gBAAkB,GAEpEggD,EAAc,SAAS37C,GACnB,SAAI07C,EAAgB17C,EAAGhB,OAAUgB,EAAG47C,UAI7B57C,EAAGiS,UAAsC,WAA1BjS,EAAGhB,KAAKrD,eAElCkgD,EAAc,SAASC,GACnB,GAAIv1C,GAAQ,IASZ,OAPA3K,IAAGY,KAAKZ,GAAGkgD,GAAQx4C,WAAY,SAAS9F,EAAK+F,GACzC,GAAoC,WAAhCA,EAAMmF,QAAQ/M,eAA8B4H,EAAMw4C,SAElD,MADAx1C,GAAQhD,EAAMgD,OACP,IAIRA,EAmBf,OAhBA3K,IAAGY,KAAKyT,EAAK+rC,SAAU,SAASx+C,EAAKwC,GACjC,IAAKpE,GAAGwM,QAAQpI,GAAI,IAAsC,aAA7BA,EAAG0I,QAAQ/M,gBACpC6/C,EAAkBx7C,EAAGhB,OACpB28C,EAAY37C,IAIZ,GAAiC,WAA7BA,EAAG0I,QAAQ/M,gBAA+BggD,EAAY37C,GAAK,CAChE,GAAIuG,GAAQs1C,EAAY77C,EAEV,QAAVuG,IACA2I,EAAIlP,EAAGpD,MAAQ2J,QANnB2I,GAAIlP,EAAGpD,MAAQoD,EAAGuG,QAWnB2I,KCzJftT,GAAGilC,YAAcjlC,GAAGilC,gBACpBjlC,GAAGilC,YAAYyB,kBAAoB,SAAS1nC,EAASkhC,GACjD,YAUA,SAASmgB,GAAqBhjC,EAAI2pB,GAG9B,GAAItT,GAAU4sB,EAAKC,CAGnB,KAEID,EAAMtZ,EAAOe,iBAAmBf,EAAOwZ,cAAcrzC,SACrDozC,EAAYD,EAAIhZ,KAAK50B,UAErBtQ,EAAI,yCACJA,EAAI,eAAiBm+C,GAEjBA,GAAaA,EAAUl9C,MAAM,YAC7Bk9C,EAAYD,EAAIhZ,KAAK1/B,WAAWA,WAAW64C,WAG/C/sB,EAAW3C,EAAQ2W,mBAAmB6Y,GAE1C,MAAOp+C,GACHC,EAAI,wDAA0DD,EAAME,QAAU,IAAK,SACnFqxB,GAAYpkB,SAAS,GAGzB,MAAOokB,GAMX,QAASgtB,GAAWrjC,EAAI2pB,GACpB,GAAIxnC,GAASR,EAAQ0qB,YAAY3E,IAAI1H,GACjC+L,EAA0C,QAAjCpqB,EAAQoqB,OAAOrpB,cAA0B,MAAQ,OAC1D+gB,EAAW9hB,EAAQ2qB,cAAc5E,IAAI1H,GACrCrc,EAAOmiB,EAAQ9F,EAKnB,OAHA7d,GAAOR,EAAQwqB,UAAY5D,EAAQvI,GACnC7d,EAAOR,EAAQu5B,eAAiBv3B,EAEzB+vB,EAAQkX,oBACX7e,OAAQA,EACRtI,SAAUA,EACVthB,OAAQA,EACRi5B,aAAcz5B,EAAQy5B,aACtByP,WAAYlB,EAAOhmC,OArD3B,GAAI+vB,GAAU9uB,KACVkhB,EAAU+c,EAAM/c,QAChByC,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,GAsDhBH,MAAK0iC,WAAa,SAAStnB,GACvB,GAGIhJ,GAHAnH,EAAQ6jB,EAAQtU,SAASY,GACzB2pB,EAASjW,EAAQiX,cAAc3qB,GAC/BlO,EAAU,GAAInP,IAAGoP,OA8BrB,OA3BAiF,GAAOqsC,EAAWrjC,EAAI2pB,GACtB3yB,EAAKE,YAAYrH,GAEjB6jB,EAAQ8W,iBAAiBb,EAAQ,SAAS2Z,GACtCv+C,EAAI,gBAEJ,IAAIsxB,GAAWitB,EAAsBA,EAAsBN,EAAqBhjC,EAAI2pB,EAEpFjW,GAAQ4W,iBAAiBtqB,GAGpBre,EAAQ4qB,KAAKoI,UACdhyB,GAAGgnC,GAAQjhC,SAGX2tB,EAASpkB,QACTH,EAAQG,QAAQokB,GAGhBvkB,EAAQK,QAAQkkB,KAIxBtxB,EAAI,8BAAgCib,GACpChJ,EAAKorC,SACLz/C,GAAGqU,GAAMtO,SAEFoJ,GAGXnP,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAG0mC,mBACnB1nC,SACI6nC,OAAQ7nC,EAAQ4qB,KAAKoI,SACrBtF,UAAW1tB,EAAQ0tB,WAGvBwT,OACIzS,SAAUzuB,EAAQyuB,SAClBtK,QAASA,EACTyC,QAASA,EACTxjB,IAAKA,OC5GjBpC,GAAGilC,YAAcjlC,GAAGilC,gBACpBjlC,GAAGilC,YAAYmD,iBAAmB,SAAS/pB,EAAM6hB,GAC7C,YAEA,IAAInP,GAAU9uB,KACVkhB,EAAU+c,EAAM/c,QAChBkC,EAAU6a,EAAM7a,QAChBO,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,IACZw+C,EAAYviC,EAAKma,gBAAkBna,EAAKoa,aAExCooB,EAA4B,SAASxjC,EAAI7d,EAAQyuB,GAC7C,GAAIzP,GAAO6G,EAAQhI,GACfrc,EAAOmiB,EAAQ9F,EAEnB7d,GAAO6e,EAAK5F,SAASshB,WAAWC,WAAa/L,EAAUqc,KACvD9qC,EAAO6e,EAAK5F,SAASshB,WAAWE,gBAAkBhM,EAAU5f,MAC5D7O,EAAO6e,EAAK5F,SAASshB,WAAWG,WAAajM,EAAUzP,KACvDhf,EAAO6e,EAAK5F,SAASshB,WAAWK,YAAcnM,EAAUsc,MACxD/qC,EAAO6e,EAAKqa,mBAAqBla,EAM7BoiC,IACAphD,EAAO6e,EAAKka,eAAiBv3B,IAIrC8/C,EAAyB,GAAI9gD,IAAGilC,YAAY8b,4BACxCn3B,KAAMvL,EAAKuL,KACX9I,SAAUzC,EAAK5F,SAASnJ,QAAQwR,SAChC1e,IAAKA,IAGT4+C,EAAiC,SAAS3jC,EAAI3G,GAC1C,GAAIvH,GAAU,GAAInP,IAAGoP,OAerB,OAbAsH,GAAI4mB,mBAAqB,WACrB,GAAuB,IAAnB5mB,EAAIsnB,WAAkB,CACtB,GAAI32B,GAAS45C,EAAwB5jC,EAAI3G,EAErCrP,GAAOiI,QACPH,EAAQG,QAAQjI,EAAOqsB,SAAUhd,GAGjCvH,EAAQK,QAAQnI,EAAOqsB,SAAUhd,KAKtCvH,GAGX+xC,EAA0B,SAAS7jC,GAC/B,GAAI7d,GAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9Brc,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,EAOnB,OALA7d,GAAO6e,EAAKmL,UAAY5D,EAAQvI,GAChC7d,EAAO6e,EAAKka,eAAiBv3B,EAC7BxB,EAAO6e,EAAKqa,mBAAqBla,EACjChf,EAAO6e,EAAK5F,SAASshB,WAAWK,YAAcrJ,EAAQgS,gBAAgB1lB,GAE/D7d,GAGX2hD,EAAwB,SAASzqC,EAAKgd,GAClC,MAAO1zB,IAAG6J,SAAS,IAAK,IAAK,IAAK,IAAK,KAAM6M,EAAIiH,QAAU,IACtD+V,EAASpkB,SACVokB,EAAS3W,OAGjBkkC,EAA0B,SAAS5jC,EAAI3G,GACnC,GAAIgd,EAOJ,OALAtxB,GAAI,sCAAwCib,GAC5Cjb,EAAI,kBAAoBsU,EAAIwhC,cAE5BxkB,EAAW0tB,GAAc,EAAM1qC,IAG3BpH,SAAU6xC,EAAsBzqC,EAAKgd,GACrCA,SAAUA,IAKlB0tB,EAAgB,SAAS5zC,EAAQkJ,GAC7B,GAAIgd,KAEJ,KACItxB,EAAIpC,GAAG0L,OAAO,4CAA6CgL,EAAIiH,OAAQjH,EAAIwhC,eAC3ExkB,EAAW1zB,GAAGwU,UAAUkC,EAAIwhC,cAEhC,MAAO/1C,GACHqL,GAAUpL,EAAI,qDAAuDD,EAAME,QAAU,IAAK,SAG9F,MAAOqxB,IAGX2tB,EAA4B,SAAShkC,GACjC,GAAIlO,GAAU,GAAInP,IAAGoP,OAcrB,OAZA0xC,GAAuBQ,SACfjkC,EACA0T,EAAQgZ,WAAW1sB,GACnB6jC,EAAwB7jC,GACxBgB,EAAKoL,cAAc1E,IAAI1H,IAE1BnD,KAAK,SAASxD,GACXvH,EAAQG,QAAQ8xC,GAAc,EAAO1qC,GAAMA,IAC5C,SAASA,GACRvH,EAAQK,QAAQ4xC,GAAc,EAAO1qC,GAAMA,KAG5CvH,GAGXoyC,EAA8B,SAAS/hD,EAAQkX,EAAKtI,EAAYiP,GAC5D,GAAInJ,GAAW,GAAI5G,UACf8b,EAAS/K,EAAK+K,OACdtI,EAAWzC,EAAKsL,cAAc5E,IAAI1H,GAClCrc,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,EAuBnB,OArBA7d,GAAO6e,EAAKmL,UAAY5D,EAAQvI,GAChC7d,EAAO6e,EAAKka,eAAiBv3B,EAEzB4/C,IACAphD,EAAO6e,EAAKqa,mBAAqBla,GAIhCH,EAAKoa,eACDmoB,IACDphD,EAAO6e,EAAKqO,WAAa1rB,GAE7B8f,EAAW9gB,GAAGqT,QAAQ7T,EAAQshB,IAGlCpK,EAAI+mB,KAAKrU,EAAQtI,GAAU,GAEvBzC,EAAKuL,KAAKoI,UAAY3T,EAAKuL,KAAK6Q,kBAChC/jB,EAAIC,iBAAkB,GAGtBiqC,GACIviC,EAAKoa,cACLz4B,GAAGiU,aAAazU,EAAQ0U,GAG5BA,EAASzK,OAAO4U,EAAKqO,UAAWte,GACzB8F,GAGJ9F,GAGXozC,EAAmB,SAASnkC,EAAI3G,GAC5B,GAAI+qC,GAAepjC,EAAKoL,cAAc1E,IAAI1H,GACtCjP,EAAa2iB,EAAQ1M,QAAQhH,EAEjC3G,GAAI4nB,iBAAiB,SAAU,oBAC/B5nB,EAAI4nB,iBAAiB,mBAAoB,kBACzC5nB,EAAI4nB,iBAAiB,gBAAiB,YAEjCsiB,IACDlqC,EAAI4nB,iBAAiB,eAAgB,4BAErC5nB,EAAI4nB,iBAAiB,cAAelwB,EAAWhL,OAGnDpD,GAAGY,KAAK6gD,EAAc,SAASzgD,EAAMZ,GACjCsW,EAAI4nB,iBAAiBt9B,EAAMZ,KAIvCJ,IAAGwG,OAAOvE,MACNmhC,YAAa,SAAS/lB,EAAI2jB,EAAUzG,GAChC,GAGIprB,GAASuyC,EAAQliD,EAHjByuB,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCtqB,EAAMqa,EAAQgZ,WAAW1sB,EAAI2jB,EACtB3b,GAAQhI,EAgBnB,OAbAlO,GAAU6xC,EAA+B3jC,EAAI3G,GAC7Cqa,EAAQqa,yBAAyB/tB,EAAI2jB,EAAU/S,EAAUzP,MACzDhf,EAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9BwjC,EAA0BxjC,EAAI7d,EAAQyuB,GAElCsM,IACA/6B,EAAO6e,EAAK9E,OAAOwgB,WAAWQ,WAAY,GAG9CmnB,EAASH,EAA4B/hD,EAAQkX,EAAKuX,EAAUnf,KAAMuO,GAClEmkC,EAAiBnkC,EAAI3G,GACrBA,EAAIinB,KAAK+jB,GAEFvyC,GAGXw1B,WAAY,SAAStnB,GACjB,GACIlO,GAASuH,EAAKlX,EAAQkiD,EADtBtzC,EAAa2iB,EAAQ1M,QAAQhH,EAWjC,OARA3G,GAAMqa,EAAQgZ,WAAW1sB,GACzB0T,EAAQqa,yBAAyB/tB,GACjClO,EAAU6xC,EAA+B3jC,EAAI3G,GAC7ClX,EAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9BqkC,EAASH,EAA4B/hD,EAAQkX,EAAKtI,EAAYiP,GAC9DmkC,EAAiBnkC,EAAI3G,GACrBA,EAAIinB,KAAK+jB,GAEFvyC,KAIfnP,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGooC,kBACnBppC,QAASgB,GAAGwG,QAAQ7G,UAAW,eAAgB0e,GAC/C6hB,MAAOlgC,GAAGwG,QAAQqe,YAAaxG,EAAKsL,cAAc5E,KAAMmb,MAG5DlgC,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OACIuxB,eAAgB,SAASjkB,GACrB,MAAIgB,GAAK5F,SAASnJ,QAAQwR,SACfugC,EAA0BhkC,GAG1BtN,EAAOuxB,eAAejkB,EAAIrd,GAAGgT,KAAKouC,EAAen/C,MAAM,SCvOlFjC,GAAGilC,YAAY8b,2BAA6B,SAAS9lC,GACjD,YAEA,IAAImxB,GACAhjB,EAAS,OACTpqB,GACI4qB,MACIqI,UAAU,EACVD,UAAU,EACVyI,iBAAiB,GAErB3Z,SAAU,KACV1e,IAAK,SAASuJ,EAAKvB,MAEvBu3C,KACAC,GACI78B,IAAK,SAAS1H,GACV,MAAOre,GAAQ8hB,UAI3B9gB,IAAGwG,OAAOxH,EAASic,GAEnBmxB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAevV,GACfA,OAAQA,EACRO,cAAei4B,EACfrjB,oCAAoC,EACpC3U,KAAM5qB,EAAQ4qB,KACdxnB,IAAKpD,EAAQoD,IACbmrB,WAAY,SAASlQ,EAAI3G,EAAKuT,GAC1B,GAAI9a,GAAUwyC,EAAStkC,SAEhBskC,GAAStkC,GAEZ4M,EACA9a,EAAQK,QAAQkH,GAGhBvH,EAAQG,QAAQoH,OAK5B1W,GAAGwG,OAAOvE,MACNq/C,SAAU,SAASjkC,EAAI3G,EAAKlX,EAAQ0nB,GAChC,GAAI/X,GAAU,GAAInP,IAAGoP,OAWrB,OATApQ,GAAQoD,IAAI,0CAA4Cib,GAExDskC,EAAStkC,GAAMlO,EAEfi9B,EAAUnN,cAAc5hB,GACnBiiB,WAAW9/B,GACXigC,YAAYvY,GACZyW,KAAKjnB,GAEHvH,MCjEnBnP,GAAGyE,YAAc,SAASwW,GACtB,YAoBA,SAAS4mC,GAAmBz/B,EAAO0/B,GAE/B,GAAIC,GAAexgD,MAAMC,UAAU1B,MAAM2B,KAAK2gB,EAE9CpjB,GAAQ2B,UAAUqhD,QAAQ,WAAa5/B,EAAM/d,OAAS,mBACtDy9C,EAAeG,cAAa,GAC5BjjD,EAAQ2B,UAAUuhD,+BAA+BH,EAAcD,EAAeK,cAGlF,QAASC,GAAiB7mB,GACtB,GAAI8mB,GAAoB,GAAIriD,IAAGoP,OAoD/B,OAlDImsB,GAAMvvB,OACNuvB,EAAMlZ,KAAK,SAASA,GAChB,GAAIrhB,GAAOu6B,EAAMv6B,KACbshD,EAAW/mB,EAAM+mB,SACjBC,EAAwBD,EAASz4C,QAAQ7I,EAG7CshD,GAAWA,EAASrtC,OAAO,EAAGstC,GAGH,MAAvBD,EAAS1iD,OAAO,KAChB0iD,EAAWA,EAASrtC,OAAO,IAG/BoN,EAAKmgC,OAASF,EACdG,EAAa3gD,KAAKugB,GAClBggC,EAAkB/yC,WAEtB,SAASozC,GACL1jD,EAAQ2B,UAAUqhD,QAAQ,oBAAsBzmB,EAAM+mB,SAAW,sBAAwBI,EAAUpwB,KAAO,IAAK,SAC/G+vB,EAAkB7yC,YAGjB+rB,EAAMonB,aACXC,EAAoBrnB,GAAOrhB,KACvB,SAAwBkD,GACpB,GAAIylC,GAAczlC,EAAQ/Y,MAE1BrE,IAAGY,KAAKwc,EAAS,SAASxb,EAAK25B,GAC3B6mB,EAAiB7mB,GAAO5gB,KAAK,WACzBkoC,GAAe,EAEK,IAAhBA,GACAR,EAAkB/yC,cAKzB8N,EAAQ/Y,QACTg+C,EAAkB/yC,WAI1B,SAAqBozC,GACjB1jD,EAAQ2B,UAAUqhD,QAAQ,oBAAsBzmB,EAAM+mB,SAAW,sBAAwBI,EAAUpwB,KAAO,IAAK,SAC/G+vB,EAAkB7yC,YAKvB6yC,EAIX,QAASO,GAAoBrnB,EAAO0f,EAAQ6H,EAAcC,GACtD,GAAI5zC,GAAU4zC,GAAmB,GAAI/iD,IAAGoP,QACpC4zC,EAAY/H,GAAU1f,EAAM0nB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqB9lC,GACjB,GAAI+lC,GAAaL,EAAeA,EAAa1vC,OAAOgK,GAAWA,CAE3DA,GAAQ/Y,OACRwnB,WAAW,WACP+2B,EAAoBrnB,EAAOynB,EAAWG,EAAYh0C,IACnD,GAGHA,EAAQG,QAAQ6zC,IAIxBh0C,EAAQK,SAGLL,EAGX,QAASi0C,GAAmBx1C,EAAck0C,GACtC,GAAIuB,MACAC,EAA4B,GAAItjD,IAAGoP,OA4CvC,OA1CApQ,GAAQ2B,UAAU4iD,yBAClBzB,EAAeG,cAAa,GAExBr0C,EAAawU,MAAM/d,OAAS,IAAMrF,EAAQwkD,oBAC1CxkD,EAAQ2B,UAAUuhD,mCAClBljD,EAAQ2B,UAAU8iD,UAAU,oBAAqB,IACjD3B,EAAeG,cAAa,GAC5BqB,EAA0B9zC,YAG1BizC,KAEIziD,GAAG2N,sBAAsBC,GACzB5N,GAAGY,KAAKgN,EAAaC,MAAO,SAASjM,EAAKsJ,GACtC,GAAIqwB,GAAQrwB,EAAK4C,kBAEbytB,KAEIA,EAAMvvB,OACNy2C,EAAa3gD,KAAKoJ,EAAK8zC,aAIvBqE,EAAsBvhD,KAAKsgD,EAAiB7mB,GAAO5gB,KAAK,WACpD0oC,EAAsB7e,MACe,IAAjC6e,EAAsBh/C,QACtBi/C,EAA0Bh0C,gBAQ9CmzC,EAAe70C,EAAawU,MAGK,IAAjCihC,EAAsBh/C,QACtBi/C,EAA0Bh0C,WAI3Bg0C,EAGX,QAASI,GAAcC,GACnB,GAAIC,GAAW,GAAI5jD,IAAG6jD,gBAClBC,sBAAuBA,EACvBphD,QAASihD,EACTI,QAAS,SAAS1xC,GACdrS,GAAG2jD,GAAU58C,SAAS/H,EAAQstB,QAAQ03B,YACtC3xC,EAAE4xC,mBAENC,sBAAuB,SAAS7xC,GAC5BrS,GAAG2jD,GAAU38C,YAAYhI,EAAQstB,QAAQ03B,aAE7CG,OAAQ,SAAS9xC,GACb+wC,EAAmB/wC,EAAEzE,aAAcg2C,GAAU1pC,KACzC,WACI2nC,EAAmBY,EAAcmB,IAErC,WACI5kD,EAAQ2B,UAAUqhD,QAAQ,sEAAuE,aAcjH,OARA9lC,GAAexG,YAAY,WACvBkuC,EAASruC,YAGbvV,GAAG2jD,GAAUx7C,aAAai8C,IAA2BpkD,GAAG2jD,GAAU3+C,OAElEq/C,EAAgBviD,KAAK8hD,GAEdA,EAGX,QAASU,GAAWC,GAChB,GAAIC,EASJ,OAPAxkD,IAAGY,KAAK2jD,EAAU32C,aAAa62C,MAAO,SAAStkD,EAAKC,GAChD,GAAY,UAARA,EAEA,MADAokD,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBryC,GACxB,MAAIrS,IAAGwR,WACKa,EAAEsyC,cAGV3kD,GAAGoR,SACIiB,EAAE4qC,EAAI,GAAK5qC,EAAEuyC,EAAI,EAGb,IAARvyC,EAAE4qC,GAAmB,IAAR5qC,EAAEuyC,EAG1B,QAASC,KACL,GAAIC,GAAY9lD,EAAQuF,iBAEpBwgD,EAAqB,WACjBl5B,WAAW,WACP7rB,GAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAC7B5jD,GAAG4jD,GAAUz7C,aAAai8C,IAA2BpkD,GAAG4jD,GAAU5+C,OAClEhF,GAAG4jD,GAAU58C,YAAYhI,EAAQstB,QAAQ03B,eAE9C,IAGXhkD,IAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAC7B,GAAI9B,GAAiB4B,EAAcE,EAG/BkB,GAAUzgD,QAAUrE,GAAGiW,kBAAkB8C,UACzCmD,EAAe/W,OAAOgI,SAAU,YAAa,SAASkF,IAC7CyvC,EAAeG,gBAAkBqC,EAAWjyC,IAC7CrS,GAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAGzBA,YAAoBoB,cACpBhlD,GAAG4jD,GAAUz7C,aAAai8C,IAE1BpkD,GAAG4jD,GAAU39C,KAAKf,QAAS,gBAQnDgX,EAAe/W,OAAOgI,SAAU,YAAa,SAASkF,GAC9CqyC,EAAmBryC,IACnB0yC,MAOR7oC,EAAe/W,OAAOnF,GAAGmN,UAAUzF,WAAW,GAAI,aAAc,SAAS2K,GACrE0yC,MAGJ7oC,EAAe/W,OAAOgI,SAAU,OAAQ,SAASkF,GAC7CA,EAAED,iBACF2yC,MAGJ7oC,EAAe/W,OAAOgI,SAAU22C,EAAuBiB,GAnR3D,GAAI/lD,GACA8kD,EAAwB,eACxBM,EAAyB,mBACzBC,KACA5B,KACAvmC,EAAiB,GAAIlc,IAAGqV,cAE5BrW,IACIuF,oBACAi/C,oBAAoB,EACpBl3B,SACI03B,WAAY,MAEhBrjD,UAAW,GAAIX,IAAGyE,YAAY9D,WAGlCX,GAAGwG,OAAOxH,EAASic,GAAG,GAsQtB4pC,IAEA7kD,GAAGwG,OAAOvE,MACNgjD,mBAAoB,SAASviD,GACzB1D,EAAQuF,iBAAiBzC,KAAKY,GAC9BghD,EAAchhD,IAGlBwiD,eAAgB,SAASxiD,GACrB,GAAImR,GACAsxC,EAAMnmD,EAAQuF,gBAElB,KAAKsP,IAAKsxC,GACN,GAAIA,EAAItxC,KAAOnR,EACX,MAAOyiD,GAAIjmC,OAAOrL,EAAG,IAKjC0B,QAAS,WACL2G,EAAe3G,UACfvV,GAAGY,KAAKyjD,EAAiB,SAASziD,EAAKgiD,GACnCA,EAASruC,gBAMzBvV,GAAGyE,YAAY9D,UAAY,WACvB,YAEA,QACI4iD,uBAAwB,aACxBrB,+BAAgC,SAAS9/B,EAAOgjC,KAChD3B,UAAW,SAASnxB,EAAM+yB,GACtBrlD,GAAGoC,IAAI,2BAA6BkwB,EAAO,2BAA6B+yB,EAAiB,IAAK,UAElGrD,QAAS,SAAS3/C,EAAS+H,GACvBpK,GAAGoC,IAAIC,EAAS+H,MAK5BpK,GAAG6jD,eAAiB,SAAS5oC,GACzB,YAiBA,SAASqqC,KACL,MAAOtlD,IAAGoR,UAAapR,GAAGwR,WAAaxR,GAAGyR,UAG9C,QAAS8zC,GAAmBlzC,GAEnBmzC,IAGGF,EACAppC,EAAe/W,OAAOgI,SAAU,WAAY,SAASkF,GACjDA,EAAED,mBAGN8J,EAAe/W,OAAOgI,SAAU,WAAY,SAASkF,GAC7CA,EAAEzE,eACFyE,EAAEzE,aAAa63C,WAAa,OAC5BpzC,EAAED,oBAKdozC,GAAsB,GAI9B,QAASE,GAAgBrzC,GAGrB,IAAKrS,GAAGiW,kBAAkB8C,SACtB,OAAO,CAGX,IAAI4sC,GAAYC,EAAKvzC,EAAEzE,aAEvBi4C,EAAW7lD,GAAGoR,QAQd,OADAu0C,MAAa3lD,GAAG4Q,OAAQ5Q,GAAGiW,kBAAkB8C,WAAuC,SAArB6sC,EAAGE,cAC3DF,GAAMD,IAAeC,EAAGxjC,QAAWyjC,GAAYD,EAAGnB,MAAMh/C,UAAYmgD,EAAGnB,MAAMh/C,SAAS,UAGjG,QAASsgD,GAAoBC,GAIzB,MAHmB1lD,UAAf0lD,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiBj5C,SAASk5C,YAAY,SACtCD,EAAeE,UAAUtnD,EAAQ8kD,uBAAuB,GAAM,GAJlE,GAAIsC,EAOJ,IAAIh9C,OAAOm9C,YACP,IACIH,EAAiB,GAAIG,aAAYvnD,EAAQ8kD,uBAE7C,MAAOlM,GACHuO,QAIJA,IAGJh5C,UAASq5C,cAAcJ,GAG3B,QAASK,KACLvqC,EAAe/W,OAAOzC,EAAS,WAAY,SAAS2P,GAChD,GAAKqzC,EAAgBrzC,GAArB,CAMA,GAAIq0C,GAAS1mD,GAAG4Q,MAAQ5Q,GAAGiW,kBAAkB8C,SAAW,KAAO1G,EAAEzE,aAAak4C,aAC/D,UAAXY,GAAgC,aAAXA,EACrBr0C,EAAEzE,aAAa63C,WAAa,OAE5BpzC,EAAEzE,aAAa63C,WAAa,OAGhCpzC,EAAE4xC,kBACF5xC,EAAED,oBAGN8J,EAAe/W,OAAOzC,EAAS,YAAa,SAAS2P,GACjD,IAAK0zC,IAAuB,CACxB,IAAKL,EAAgBrzC,GACjB,MAEJrT,GAAQ+kD,QAAQ1xC,MAIxB6J,EAAe/W,OAAOzC,EAAS,YAAa,SAAS2P,GACjD,GAAKqzC,EAAgBrzC,GAArB,CAIArT,EAAQ23B,QAAQtkB,EAEhB,IAAIsyC,GAAgBx3C,SAASw5C,iBAAiBt0C,EAAEu0C,QAASv0C,EAAEw0C,QAEvD7mD,IAAGiC,MAAMwD,SAASk/C,IAItB3lD,EAAQklD,sBAAsB7xC,MAGlC6J,EAAe/W,OAAOzC,EAAS,OAAQ,SAAS2P,GAC5C,IAAK0zC,IAAuB,CACxB,IAAKL,EAAgBrzC,GACjB,MAGJA,GAAED,iBACFC,EAAE4xC,kBACFjlD,EAAQmlD,OAAO9xC,GAEf6zC,OAjJZ,GACIlnD,GAAS0D,EAASujD,EAAaT,EAD/BtpC,EAAiB,GAAIlc,IAAGqV,cAG5BrW,IACI0D,QAAS,KACTqhD,QAAS,SAAS1xC,KAClBskB,QAAS,SAAStkB,KAElB6xC,sBAAuB,SAAS7xC,KAChC8xC,OAAQ,SAAS9xC,MAGrBrS,GAAGwG,OAAOxH,EAASic,GACnBvY,EAAU1D,EAAQ0D,QAyIlB6iD,IACAkB,IAEAzmD,GAAGwG,OAAOvE,MACNggD,aAAc,SAAS+D,GACnB,MAAOD,GAAoBC,IAG/BzwC,QAAS,WACL2G,EAAe3G,WAGnB4sC,WAAY,WACR,MAAOz/C,OCvelB,WACG,YAEA1C,IAAG8mD,aACC9lC,gBAAiB,SAASC,GACtBhf,KAAK8kD,QAAQvlD,UAAUwf,gBAAgBhf,MAAMC,KAAMP,WACnDO,KAAK+kD,YAAYC,iBAGrBnkC,iBAAkB,WACd7gB,KAAK8kD,QAAQvlD,UAAUshB,iBAAiB9gB,MAAMC,KAAMP,WACpDO,KAAK+kD,YAAYE,cAGrBC,iBAAkB,SAASzkD,GACvBT,KAAKmlD,MAAQnlD,KAAKmlD,KAAKnC,mBAAmBviD,IAG9C2kD,oBAAqB,SAAS3kD,GAC1B,GAAIT,KAAKmlD,KACL,MAAOnlD,MAAKmlD,KAAKlC,eAAexiD,IAIxC4kD,gBAAiB,SAASjqC,GACtB,IAAKpb,KAAK+kD,YAAYO,gBAAgBlqC,GAClC,MAAOpb,MAAK+kD,YAAYQ,iBAAiBnqC,IAIjDN,MAAO,WACH9a,KAAK8kD,QAAQvlD,UAAUub,MAAM/a,MAAMC,KAAMP,WACzCO,KAAK+kD,YAAYjqC,SAEZ9a,KAAKpB,SAASslB,QAAUlkB,KAAK+kD,YAAYtiC,cAC1CziB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAK+kD,YAAYtiC,YAC1BrJ,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGHza,KAAKmlD,OACLnlD,KAAKmlD,KAAK7xC,UACVtT,KAAKmlD,KAAOnlD,KAAKwlD,qBAGrBxlD,KAAKylD,mBAAqB,EAC1BzlD,KAAK0lD,uBAAyB,EAE9B1lD,KAAK2lD,mCAGT3/B,QAAS,SAAS5K,EAAIkC,GAClB,GAAIsoC,GAAoB5lD,KAAKpB,SAASkyB,eAAexT,EAErDtd,MAAK8kD,QAAQvlD,UAAUymB,QAAQjmB,MAAMC,KAAMP,WAC3CO,KAAK+kD,YAAYc,eAAezqC,EAAIwqC,IAGxC/hC,YAAa,SAASzI,GAClB,GAAIqsB,GAASznC,KAAK8kD,QAAQvlD,UAAUskB,YAAY9jB,MAAMC,KAAMP,UAG5D,OADAgoC,IAAUznC,KAAK+kD,YAAYe,aAAa1qC,GACjCqsB,GAGX3mB,eAAgB,SAAS1F,GACrB,GAAI2qC,GAAY/lD,KAAK8kD,QAAQvlD,UAAUuhB,eAAe/gB,MAAMC,KAAMP,UAGlE,OADAsmD,IAAa/lD,KAAK+kD,YAAYiB,gBAAgB5qC,GACvC2qC,GAGXE,MAAO,SAASC,GACZ,MAAOlmD,MAAK+kD,YAAYoB,UAAUD,IAGtCE,cAAe,SAAS1kC,GACpB,GAAItB,GAAOpgB,KAAKoiB,QAAQV,EAExB,OAAOtB,GAAKimC,eAOpBtoD,GAAGuoD,cACC5jC,WAAY,SAASvJ,GACjB,GAAI+K,GAASlkB,KAAK8kD,QAAQvlD,UAAUmjB,WAAW3iB,MAAMC,KAAMP,UAQ3D,OANKykB,IACG/K,IAAanZ,KAAKytB,mBAClBvJ,EAASlkB,KAAK+kD,YAAYtiC,aAI3ByB,GAGXqiC,gBAAiB,SAAS7kC,GACtB1hB,KAAK+kD,YAAYyB,WAAW9kC,IAGhCikC,gCAAiC,WAC7B3lD,KAAKymD,yBAA2B1oD,GAAG2oD,yBAA2B1mD,KAAK2mD,6BAInE3mD,KAAK4mD,wBAA0B7oD,GAAGwR,UAE9BvP,KAAK6mD,2BAEL7mD,KAAK8mD,sBAAwB9mD,KAAK+mD,0BAClC/mD,KAAKgnD,6BAA+BhnD,KAAKinD,iCACzCjnD,KAAKknD,2BAA6BlnD,KAAKmnD,iCAI/C3B,kBAAmB,WACf,GAAIzjD,GAAO/B,KACPsC,EAAmBtC,KAAKpB,SAASwoD,YAAYC,eAC7CC,EAAatnD,KAAK+kD,YAClBwC,EAAkBD,EAAWE,aAIjC,OAFAD,IAAmBjlD,EAAiBzC,KAAK0nD,GAElC,GAAIxpD,IAAGyE,aACVF,iBAAkBA,EAClBi/C,mBAAoBvhD,KAAKpB,SAASwM,SAClCif,SACI03B,WAAY/hD,KAAKpB,SAASyrB,QAAQ03B,YAEtCrjD,WACI4iD,uBAAwB,WACpBgG,EAAWG,sBAEfxH,+BAAgC,SAAS9/B,EAAOgjC,GAC5CmE,EAAWI,qBAEX3pD,GAAGY,KAAKwhB,EAAO,SAASxgB,EAAKygB,GACzBA,EAAKimC,aAAelD,IAGpBhjC,EAAM/d,QACNL,EAAK+c,SAASqB,EAAO,KAAM,OAGnCqhC,UAAW,SAASnxB,EAAMs3B,GACtB5lD,EAAKqkB,WAAWiK,EAAMs3B,IAE1B5H,QAAS,SAAS3/C,EAAS+H,GACvBpG,EAAK5B,IAAIC,EAAS+H,QAMlCw+C,2BAA4B,WACxB,GAAI5kD,GAAO/B,IAEX,OAAO,IAAIjC,IAAG2oD,yBACVY,WAAYtnD,KAAK+kD,YAEjB5kD,IAAK,SAASC,EAASwnD,GACnB7lD,EAAK5B,IAAIC,EAASwnD,IAGtBC,aAAc,SAASnmC,GACnB3f,EAAKqf,WAAWM,IAGpB8J,SAAU,SAAS9J,GACf3f,EAAKye,OAAOkB,IAGhBomC,QAAS,SAASpmC,GACd3f,EAAK4iB,MAAMjD,IAGfqmC,QAAS,SAASrmC,GACd3f,EAAK8hB,YAAYnC,IAGrBsmC,WAAY,SAAStmC,GACjB3f,EAAK+e,eAAeY,IAGxBumC,UAAW,SAASvmC,GAChB,MAAO3f,GAAKmf,QAAQQ,OAKhCmlC,uBAAwB,WAEpB,MAAO7mD,MAAK+kD,YAAYmD,2BAChBloD,KAAKpB,SAAS+wB,YACf5xB,GAAGoqD,sBACHpqD,GAAGqqD,2BACHrqD,GAAGqqD,2BAGdC,qBAAsB,WAClB,GAAItmD,GAAO/B,KACPsnD,EAAatnD,KAAK+kD,WAEtB,QACIuC,WAAYA,EACZnnD,IAAK,SAASC,EAASwnD,GACnB7lD,EAAK5B,IAAIC,EAASwnD,IAEtBU,kBAAmB,SAAS5mC,GACxB,MAAO3f,GAAKmhB,YAAY9H,GAAIsG,IAAShG,QAEzCusC,UAAW,SAASvmC,GAChB,MAAO3f,GAAKmf,QAAQQ,IAExB6mC,UAAW,SAASntC,EAAIkC,GACpBvb,EAAKikB,QAAQ5K,EAAIkC,IAErBkrC,sBAAuB,SAASptC,EAAIqtC,GAChC,GAAIC,GAAU3qD,GAAGupD,EAAWqB,aAAavtC,IACrCwtC,EAAkB7qD,GAAGupD,EAAW/B,iBAAiBnqC,GAEjDqtC,IACAC,EAAQ5jD,SAAS,cACjBwiD,EAAWuB,aAAaztC,GACxBksC,EAAWwB,aAAa1tC,KAGxBstC,EAAQ3jD,YAAY,cACpBuiD,EAAWyB,aAAa3tC,GACxBksC,EAAW0B,aAAa5tC,IAI5BwtC,EAAgB9jD,SAAS,WAAWC,YAAY,cAK5D2kB,sBAAuB,SAAStO,EAAI2B,EAAWD,GAC3C9c,KAAK8kD,QAAQvlD,UAAUmqB,sBAAsB3pB,MAAMC,KAAMP,WAErDO,KAAK6mD,0BAED7mD,KAAK+kD,YAAYQ,iBAAiBnqC,IAAO0B,IAAc/e,GAAG2d,OAAOoC,YACjE9d,KAAK+kD,YAAYkE,qBAAqB7tC,GACtCpb,KAAK+kD,YAAY+D,aAAa1tC,IAIlC2B,IAAchf,GAAG2d,OAAO0C,iBAAmBtB,IAAc/e,GAAG2d,OAAOyC,WACnEne,KAAK+kD,YAAYmE,UAAU9tC,GAC3Bpb,KAAK+kD,YAAYoE,cAAc/tC,GAC/Brd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKrW,YAAY/E,KAAKopD,SAASC,WAE/DvsC,IAAc/e,GAAG2d,OAAO4C,eAC7Bte,KAAK+kD,YAAYuE,UAAUluC,IAInC6rC,+BAAgC,WAC5B,GAAI7qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGwrD,4BAA4BntC,IAG9C+qC,6BAA8B,WAC1B,GAAI/qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGqqD,0BAA0BhsC,IAG5C2qC,wBAAyB,WACrB,GAAI3qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGoqD,qBAAqB/rC,IAGvCiX,eAAgB,SAASjY,GACrBpb,KAAK8kD,QAAQvlD,UAAU8zB,eAAetzB,MAAMC,KAAMP,WAClDO,KAAK+kD,YAAYyE,YAAYpuC,IAGjCgW,eAAgB,SAASe,EAAYC,GACjCpyB,KAAK8kD,QAAQvlD,UAAU6xB,eAAerxB,MAAMC,KAAMP,WAClDO,KAAK+kD,YAAY0E,sBAGrBx2B,UAAW,SAAS7X,EAAIrc,GACpB,GAAIqhB,GAAOpgB,KAAKoiB,QAAQhH,EAEpBgF,IAAQA,EAAKmgC,QAAUvgD,KAAKpB,SAASwoD,YAAYsC,sBACjD1pD,KAAKmkB,aAAaqF,YAAYpO,GAC1BuuC,OAAQvpC,EAAKmgC,SAIrBvgD,KAAK8kD,QAAQvlD,UAAU0zB,UAAUlzB,MAAMC,KAAMP,WAC7CO,KAAK4pD,WAAWxuC,EAAIrc,IAIxBo0B,aAAc,SAAS/X,GAEfpb,KAAK6mD,2BACL7mD,KAAK+kD,YAAYkE,qBAAqB7tC,GACtCpb,KAAK+kD,YAAYiE,aAAa5tC,GAGzBpb,KAAK4mD,wBACN5mD,KAAKknD,2BAA2B2C,WAAW7pD,KAAK+kD,YAAY4D,aAAavtC,MAMrFiQ,YAAa,SAASjQ,EAAIrc,EAAMosB,EAAQC,GACpCprB,KAAK8kD,QAAQvlD,UAAU8rB,YAAYtrB,MAAMC,KAAMP,WAE/CO,KAAK+kD,YAAY+E,eAAe1uC,EAAI+P,EAAQC,GAE9B,IAAVA,GAAoD,MAArC/mB,KAAKC,MAAM6mB,EAASC,EAAQ,MAC3CprB,KAAK+kD,YAAYgF,WAAW3uC,GAC5Bpb,KAAK+kD,YAAYuE,UAAUluC,GAC3Bpb,KAAK+kD,YAAYiF,aAAa5uC,GAC9Bpb,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASkH,KAAKmkD,oBAGtDjqD,KAAKkqD,iBAAiB9uC,IAItBpb,KAAKkqD,iBAAiB9uC,EAAI+P,EAAQC,IAI1CwI,iBAAkB,SAASzI,EAAQC,GAC/BprB,KAAK8kD,QAAQvlD,UAAUq0B,iBAAiB7zB,MAAMC,KAAMP,WACpDO,KAAK+kD,YAAY1I,oBAAoBlxB,EAAQC,IAGjDG,YAAa,SAASnQ,EAAIrc,EAAMqG,EAAQqP,GAMpC,QAAS01C,GAAe/kD,GAGfkb,IAILgnC,EAAW6B,cAAc/tC,GAEzBrd,GAAGuiB,GAAevb,YAAYhD,EAAKqnD,SAASC,UAC5C/B,EAAW0C,aAAa5uC,GAEpBrZ,EAAKmhB,YAAY9H,GAAIA,IAAKM,SAAW3d,GAAG2d,OAAO4C,eAC/CgpC,EAAWyC,WAAW3uC,GAE1BksC,EAAWkC,YAAYpuC,GAEnBhW,EAAOiI,QACPtL,EAAKqoD,sBAAsBhvC,IAG3Brd,GAAGuiB,GAAexb,SAAS/C,EAAKqnD,SAASiB,MACzC/C,EAAWgD,WAAWlvC,GAElBksC,EAAWiD,oBAAsBxoD,EAAKiiB,gBAAgB5I,KACtDrd,GAAGuiB,GAAexb,SAAS/C,EAAKqnD,SAASlN,WACzCoL,EAAWkD,UAAUpvC,IAEzBrZ,EAAK0oD,2BAA2BrvC,EAAIhW,KAjC5C,GAAIslD,GAAe1qD,KAAK8kD,QAAQvlD,UAAUgsB,YAAYxrB,MAAMC,KAAMP,WAC9D6nD,EAAatnD,KAAK+kD,YAClBzkC,EAAgBgnC,EAAW/B,iBAAiBnqC,GAC5CrZ,EAAO/B,IA6CX,OAVI0qD,aAAwB3sD,IAAGoP,QAC3Bu9C,EAAahyC,KAAK,SAASiyC,GACvBR,EAAeQ,KAKnBR,EAAe/kD,GAGZslD,GAGXN,sBAAuB,SAAShvC,GAC5B,GAAIksC,GAAatnD,KAAK+kD,WAElB/kD,MAAK8vB,qBACLw3B,EAAWsD,iBAAiBxvC,GAGhCrd,GAAGupD,EAAW/B,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAAS/7C,SAE3DrN,KAAK6qD,sBAAsBzvC,IAG/BwQ,cAAe,SAASxQ,GACpBpb,KAAK8kD,QAAQvlD,UAAUqsB,cAAc7rB,MAAMC,KAAMP,WACjDO,KAAK+kD,YAAY+F,YAAY1vC,IAGjC0Q,UAAW,SAAS1Q,EAAIrc,GACpB,GAAI2rD,GAAe1qD,KAAK8kD,QAAQvlD,UAAUusB,UAAU/rB,MAAMC,KAAMP,UAIhE,OAFAO,MAAK+kD,YAAY+F,YAAY1vC,GAEtBsvC,GAGXz+B,eAAgB,SAAS7Q,EAAI4Q,GACzBhsB,KAAK8kD,QAAQvlD,UAAU0sB,eAAelsB,MAAMC,KAAMP,WAI9CusB,EAAU+L,UAAY,GAAK/3B,KAAKygB,SAASyjB,YAAY9oB,IACrDpb,KAAK+kD,YAAYgG,WAAW3vC,IAIpCsQ,UAAW,SAAStQ,EAAIrc,GACpBiB,KAAK8kD,QAAQvlD,UAAUmsB,UAAU3rB,MAAMC,KAAMP,WAC7CO,KAAKumD,gBAAgBnrC,GAEU,IAA3Bpb,KAAK8tB,mBACL9tB,KAAK+kD,YAAY0E,sBAIzBh3B,mBAAoB,SAASrX,GACzB,GAAI4vC,GAAoBC,EAASC,CAEjClrD,MAAK8kD,QAAQvlD,UAAUkzB,mBAAmB1yB,MAAMC,KAAMP,WAEtDO,KAAKmrD,gBAAgB/vC,GAEjBpb,KAAKpB,SAAS+lB,MAAMymC,oBACpBJ,EAAqBhrD,KAAK8jB,aAAa1I,GACvC6vC,EAAUjrD,KAAKpB,SAAS+lB,MAAMwQ,gBAE9B+1B,EAAYlrD,KAAKpB,SAAS+lB,MAAM0mC,cAAcrmD,QAAQ,gBAAiBgmD,GACvEE,EAAYA,EAAUlmD,QAAQ,eAAgBimD,GAE9CjrD,KAAK+kD,YAAYoE,cAAc/tC,EAAI8vC,GACnCntD,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAASC,YAKzEn4B,qBAAsB,SAAS9V,GAC3B,MAAIpb,MAAK8kD,QAAQvlD,UAAU2xB,qBAAqBnxB,MAAMC,KAAMP,YACxDO,KAAK+kD,YAAYuG,cAAclwC,GAC/Brd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKrW,YAAY/E,KAAKopD,SAASiB,MACpErqD,KAAK+kD,YAAYoE,cAAc/tC,GAC/Bpb,KAAK+kD,YAAY+F,YAAY1vC,GAC7Bpb,KAAKmrD,gBAAgB/vC,IACd,IAGPrd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAASlN,WACjEl8C,KAAK+kD,YAAYyF,UAAUpvC,IACpB,IAIfiG,gBAAiB,SAASjG,GACtB,GAAIkY,GAAoBv1B,GAAGgT,KAAK/Q,KAAKurD,uBAAwBvrD,KAE7DA,MAAK8kD,QAAQvlD,UAAU8hB,gBAAgB7hB,KAAKQ,KAAMob,EAAIkY,IAG1Di4B,uBAAwB,SAASnwC,EAAIG,EAAMgY,GACnCvzB,KAAKpB,SAASwiB,WAAWoqC,aACzBxrD,KAAKyrD,mBAAmB1rD,MAAMC,KAAMP,WAGpCO,KAAK0rD,mBAAmB3rD,MAAMC,KAAMP,YAI5CwoB,kBAAmB,SAAS7M,EAAI3G,EAAKuT,GACjChoB,KAAK8kD,QAAQvlD,UAAU0oB,kBAAkBloB,MAAMC,KAAMP,WAErDO,KAAK+kD,YAAYyE,YAAYpuC,GAEzB4M,GACAhoB,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASwiB,WAAWuqC,oBAC5D3rD,KAAK+kD,YAAY6F,iBAAiBxvC,IAGlCpb,KAAKumD,gBAAgBnrC,IAI7BswC,mBAAoB,SAAStwC,EAAIG,EAAMgY,GACnCvzB,KAAK+kD,YAAY6G,iBAAiBxwC,GAClCpb,KAAK+kD,YAAY+F,YAAY1vC,GAC7Bpb,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASwiB,WAAWyqC,oBAC5D7rD,KAAK0zB,eAAeC,WAAW5zB,MAAMC,KAAMP,YAG/CgsD,mBAAoB,SAASrwC,EAAIG,EAAMqf,GAEnC,GAKIt5B,GALA6R,EAAWnT,KAAKkhB,QAAQ9F,GACxB0wC,EAAiB9rD,KAAKpB,SAASwiB,WAAW0qC,eAAe9mD,QAAQ,gBAAiBmO,GAElF44C,GADO/rD,KAAK2jB,QAAQvI,GACA3b,WACpBsC,EAAO/B,IAGXsB,GAAStB,KAAKpB,SAASotD,YAAYF,GAE/B/tD,GAAGga,iBAAiBzW,GACpBA,EAAO2W,KAAK,WACRlW,EAAK2pD,mBAAmB3rD,MAAMgC,EAAMgqD,KAGnCzqD,KAAW,GAChBS,EAAK2pD,mBAAmB3rD,MAAMgC,EAAMgqD,IAI5CnC,WAAY,SAASxuC,EAAIrc,EAAMktD,GAC3B,GAAIC,GAGA5U,EAFA6U,EAAe,EACfC,EAAcpsD,KAAKygB,SAASwjB,UAAU7oB,IAAOpb,KAAKpB,SAAS2Y,QAAQ80C,UAGnErsD,MAAKpB,SAASqE,QAAQqpD,eAClBtsD,KAAKylD,mBAAqB,GAAKzlD,KAAK0lD,uBAAyB,IAC7DyG,EAAensD,KAAK0lD,uBAAyB,GAGjDwG,GACIhqD,MAAOiqD,IAIVF,IACGjsD,KAAKpB,SAASy3B,8BAAgCt4B,GAAGiW,kBAAkBqC,eACnErW,KAAK+kD,YAAYwH,gBAMhBvsD,KAAKpB,SAASwM,WACfksC,EAASt3C,KAAKkjB,YAAY9H,GAAIA,IAE9Bpb,KAAKwsD,mBAAqBxsD,KAAKwsD,oBAAsBlV,EAAO76B,aAExD66B,EAAO76B,eAAiBzc,KAAKwsD,oBAAuBlV,EAAO76B,eAC3Dzc,KAAKygB,SAASC,YACd1gB,KAAKysD,aACLzsD,KAAKwsD,mBAAqB,QAKlCP,GACAjsD,KAAK+kD,YAAY2H,eAAetxC,EAAIpb,KAAKpB,SAASkyB,eAAe/xB,GAAOmtD,EAAaE,GACrFpsD,KAAK+kD,YAAY4H,gBAAgBvxC,EAAIpb,KAAKkiB,eAAe9G,IAAK,EAAMpb,KAAKpB,SAASguD,WAAWl0B,iBAG7F14B,KAAK+kD,YAAY5oC,QAAQf,EAAIpb,KAAKpB,SAASkyB,eAAe/xB,GAAOmtD,EAAaE,GAC9EpsD,KAAK+kD,YAAY8H,gBAAgBzxC,EAAIpb,KAAKoiB,QAAQhH,GAAKpb,KAAKpB,SAASguD,WAAWl0B,gBAGpF14B,KAAK0lD,wBAA0B,GAE3BuG,GACCjsD,KAAKpB,SAASqE,QAAQ6pD,kBAAoB/uD,GAAGiW,kBAAkBqC,gBAEhErW,KAAKkqD,iBAAiB9uC,IAI9BqxC,WAAY,WACRzsD,KAAK+kD,YAAYE,aACjBjlD,KAAK6gB,oBAGTqpC,iBAAkB,SAAS9uC,EAAI2xC,EAAYlR,GACvC,GAAIt/B,GAAOvc,KAAKojB,QAAQhI,GACpB4xC,EAAiBhtD,KAAK8sB,YAAYvQ,EAElCA,IAAQ,IACWle,SAAf0uD,GAA0C1uD,SAAdw9C,IAC5BmR,EAAiBhtD,KAAKitD,gBAAgBF,EAAYlR,IAGtD77C,KAAK+kD,YAAYxnC,WAAWnC,EAAI4xC,KAIxCC,gBAAiB,SAASC,EAAcrR,GAEpC,QAASrtC,GAAEzP,EAAMwxB,GAAenwB,EAAUA,EAAQ4E,QAAQjG,EAAMwxB,GADhE,GAAInwB,GAAUJ,KAAKpB,SAASkH,KAAKqnD,cAKjC,OAFA3+C,GAAE,YAAanK,KAAKC,MAAM4oD,EAAerR,EAAY,MACrDrtC,EAAE,eAAgBxO,KAAK8sB,YAAY+uB,IAC5Bz7C,GAGXqqD,2BAA4B,SAASrvC,EAAIqW,GACrC,GAAI27B,GAAMC,EAAkBC,CAE5BF,GAAOptD,KAAKpB,SAAS2uD,wBAAwBH,KAC7CC,EAAmBrtD,KAAKpB,SAAS2uD,wBAAwBF,iBAE5C,WAATD,GACAE,EAAgB77B,EAAS47B,GACpBC,IACDA,EAAgBttD,KAAKpB,SAASkH,KAAK0nD,YAGvCxtD,KAAK+kD,YAAYoE,cAAc/tC,EAAIkyC,GAE/BttD,KAAKpB,SAAS2uD,wBAAwBE,eACtCztD,KAAK0tD,aAAatyC,EAAIkyC,IAGZ,YAATF,EACLptD,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASkH,KAAK0nD,YAExC,SAATJ,GACLptD,KAAKG,IAAI,0CAA4CitD,EAAO,iBAAkB,SAItFM,aAAc,SAAStyC,EAAItV,GACvB9F,KAAK+kD,YAAYQ,iBAAiBnqC,GAAIhC,MAAQtT,GAGlDqlD,gBAAiB,SAAS/vC,GACjBpb,KAAKpB,SAASy3B,8BAA+Bt4B,GAAGiW,kBAAkBqC,eACnErW,KAAK+kD,YAAYuF,WAAWlvC,IAIpCgL,WAAY,SAASiK,EAAMtxB,EAAMkK,GAC7B,GAAI7I,GAAUJ,KAAK8kD,QAAQvlD,UAAU6mB,WAAWrmB,MAAMC,KAAMP,UAC5DO,MAAKpB,SAAS+uD,YAAYvtD,IAG9B2mB,YAAa,SAAS3mB,GAClBJ,KAAK8kD,QAAQvlD,UAAUwnB,YAAYhnB,MAAMC,KAAMP,WAC/CO,KAAKpB,SAAS+uD,YAAYvtD,IAG9BwtD,kBAAmB,WACf,GAAI7rD,GAAO/B,IAEXA,MAAKpB,SAASF,UAAU8pB,gBAAkB,WACtC,GAAIpoB,GAAU2B,EAAKnD,SAASypB,MAAMwlC,kBAC9BC,EAAa/rD,EAAKnD,SAASypB,MAAM5I,WAErC,OAAO1d,GAAKnD,SAASmvD,WAAW3tD,EAAS0tD,KAIjDjhC,oBAAqB,SAASzR,EAAIrc,GAC9BiB,KAAKylD,oBAAsB,EAC3BzlD,KAAK8kD,QAAQvlD,UAAUstB,oBAAoB9sB,MAAMC,KAAMP,YAG3D8gB,uBAAwB,SAAS3U,EAAOrO,EAAQshB,GAC5C7e,KAAKylD,mBAAqB75C,EAAMxJ,OAChCpC,KAAK0lD,uBAAyB,EAC9B1lD,KAAK8kD,QAAQvlD,UAAUghB,uBAAuBxgB,MAAMC,KAAMP,YAG9DorD,sBAAuB,SAASnpC,GAC5B,GAAIgF,GAAe1mB,KAAKkiB,eAAeR,GACnCssC,EAAahuD,KAAKkjB,YAAY9H,GAAIsG,IAAShG,MAE3CsyC,KAAejwD,GAAG2d,OAAO+C,UACxBiI,IACD1mB,KAAKpB,SAASguD,WAAWqB,aAAaC,mBACrCnwD,GAAGiW,kBAAkBiD,eAItBjX,KAAK+kD,YAAY4H,gBAAgBjrC,EAAQgF,EAAc1mB,KAAKpB,SAASguD,WAAWl0B,gBAIxFxZ,eAAgB,SAASqH,GACrB,GAAInL,GAAKpb,KAAK8kD,QAAQvlD,UAAU2f,eAAenf,MAAMC,KAAMP,UAO3D,OALAO,MAAK4pD,WAAWxuC,EAAIpb,KAAKkhB,QAAQ9F,IAAK,GACtCpb,KAAK+kD,YAAYyE,YAAYpuC,GAC7Bpb,KAAK+kD,YAAYgF,WAAW3uC,GAC5Bpb,KAAKoqD,sBAAsBhvC,GAEpBA,GAGXqR,SAAU,SAASrR,EAAIoC,GACnBxd,KAAK8kD,QAAQvlD,UAAUktB,SAAS1sB,MAAMC,KAAMP,WAE5CO,KAAK+kD,YAAYxnC,WAAWnC,EAAIpb,KAAK8sB,YAAYtP,KAGrDuX,wBAAyB,WACrB/0B,KAAK+kD,YAAYC,gBACjBhlD,KAAK8kD,QAAQvlD,UAAUw1B,wBAAwBh1B,MAAMC,KAAMP,gBC7sBvE1B,GAAGC,aAAe,SAASgb,EAAGtb,GAC1B,YAEA,IAAIqE,GAAO/B,IAKXA,MAAK8kD,QAAUpnD,EAAYK,GAAGL,GAAW04B,kBAAoBr4B,GAAGq4B,kBAChEp2B,KAAK8kD,QAAQ/kD,MAAMC,KAAMP,WAGzB1B,GAAGwG,OAAOvE,KAAKpB,UACX6B,QAAS,KAETyjB,OAAQ,KAERiqC,YAAa,KAEb/G,aACIC,kBACAqC,sBAAsB,GAG1B5jD,MACIqnD,eAAgB,6BAChBK,WAAY,gBACZvD,mBAAoB,gBACpBxiB,OAAQ,UAGZ2mB,SAAU,cAEV/jC,SACIg/B,SAAU,qBACVnN,UAAW,sBACX7uC,QAAS,oBACTg9C,KAAM,iBACNgE,SAAU,cACVtrD,KAAM,UACNg/C,WAAY,8BAGhBwL,yBACIH,KAAM,UACNC,iBAAkB,QAClBI,eAAe,GAGnB/8B,UACI49B,kBAAmB,6BACnBC,mBAAoB,kFAGxB5pC,OACIymC,mBAAmB,EACnBC,cAAe,oCAGnBjqC,YACIoqC,cAAc,EACdM,eAAgB,8CAChBD,mBAAoB,cACpBF,mBAAoB,iBAIxB1oD,SACI6pD,kBAAkB,EAClBR,cAAc,GAGlBjkC,OACImmC,eAAe,EACfX,kBAAmB,0BAGvBjB,YACIl0B,cAAe,KACf+1B,SAAU,EACVR,cACIC,mBAAmB,EACnBQ,iBAAkB,KAClBC,YAAa,MAEjBC,kBAAmB,KAGvBr3C,SACI80C,YAAY,GAGhBsB,YAAa,SAASvtD,GAClB,MAAI2B,GAAKgjD,YAAY8J,UAAU,SACpB9sD,EAAKgjD,YAAY+J,WAAW,QAAS1uD,OAG5CwpB,YAAW,WACPziB,OAAOmqB,MAAMlxB,IACd,IAIX4rD,YAAa,SAAS5rD,GAClB,MAAI2B,GAAKgjD,YAAY8J,UAAU,WACpB9sD,EAAKgjD,YAAY+J,WAAW,UAAW1uD,GAGvC+G,OAAO4nD,QAAQ3uD,IAI9B2tD,WAAY,SAAS3tD,EAAS4uD,GAC1B,MAAIjtD,GAAKgjD,YAAY8J,UAAU,UACpB9sD,EAAKgjD,YAAY+J,WAAW,SAAU1uD,EAAS4uD,GAG/C7nD,OAAO8nD,OAAO7uD,EAAS4uD,MAGvC,GAGHjxD,GAAGwG,OAAOvE,KAAKpB,SAAUoa,GAAG,GAE5BhZ,KAAK+kD,YAAc,GAAIhnD,IAAGmxD,YACtB/uD,IAAKpC,GAAGgT,KAAK/Q,KAAKG,IAAKH,MACvBmvD,eAAgBnvD,KAAKpB,SAASwvD,SAC9BgB,YAAapvD,KAAKpB,SAAS6B,QAC3B4uD,gBAAiBrvD,KAAKpB,SAASuvD,YAC/BjqC,OAAQlkB,KAAKpB,SAASslB,OACtBw0B,eAAgB14C,KAAKiiB,gBACrBoI,SACItnB,KAAM/C,KAAKpB,SAASyrB,QAAQtnB,KAC5BsrD,SAAUruD,KAAKpB,SAASyrB,QAAQgkC,UAEpC5Z,QACI6a,UAAWtvD,KAAKpB,SAASguD,WAAW6B,SACpCG,kBAAmB5uD,KAAKpB,SAASguD,WAAWgC,mBAEhDX,cACIsB,gBAAiBvvD,KAAKpB,SAASguD,WAAWqB,aAAaC,kBACvDsB,sBAAuBxvD,KAAKpB,SAASguD,WAAWqB,aAAaS,iBAC7De,oBAAqBzvD,KAAKpB,SAASguD,WAAWqB,aAAaU,aAE/D7oD,KAAM9F,KAAKpB,SAASkH,OAGpB9F,KAAKpB,SAASmrB,YAAYsH,mBAAqBtzB,GAAGgS,UAAYhS,GAAGkS,YACjEjQ,KAAK+kD,YAAY2K,cAAc1vD,KAAKpB,SAAS8xB,SAASa,+BAEhDxzB,GAAGiW,kBAAkB0D,WAAc1X,KAAKpB,SAAS+oB,KAAKoI,WAAahyB,GAAGiW,kBAAkB2D,WAC9F3X,KAAK+kD,YAAY2K,cAAc1vD,KAAKpB,SAAS8xB,SAAS69B,qBAGtDvuD,KAAK81B,iBAEL91B,KAAK+kD,YAAYzW,SAEjBtuC,KAAKopD,SAAWppD,KAAKpB,SAASyrB,SAEzBrqB,KAAKpB,SAASslB,QAAUlkB,KAAK+kD,YAAYtiC,cAC1CziB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAK+kD,YAAYtiC,YAC1BrJ,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGPza,KAAK2lD,kCAED5nD,GAAGyE,aAAezE,GAAGiW,kBAAkB8C,WACvC9W,KAAKmlD,KAAOnlD,KAAKwlD,qBAGjBxlD,KAAKpB,SAASypB,MAAMD,eAAiBpoB,KAAKpB,SAASypB,MAAMmmC,gBACrDzwD,GAAGoqB,aACHnoB,KAAK4tD,oBAGL5tD,KAAKG,IAAI,kCAAmC,UAIpDH,KAAKylD,mBAAqB,EAC1BzlD,KAAK0lD,uBAAyB,IAKtC3nD,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAG2gB,eACxC3gB,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAGuoB,gBAGxCvoB,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAG8mD,aACxC9mD,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAGuoD,cC5LxCvoD,GAAGmxD,WAAa,SAAS9yC,GACrB,YAEA,IA4EIjc,GACAwvD,EACAC,EACAC,EACAxtC,EACA8M,EACA2gC,EACAC,EAnFAC,EAAe,aACfC,EAAoB,cACpBC,EAA0B,cAC1BC,EAA8B,kBAE9BC,EAAqB,mBACrBC,EAAsB,oBACtBC,EAAoB,iBACpBC,EAAuB,oBACvBC,GACIC,QAASvlD,SAASwlD,yBAClBC,QAEJC,GAAmB,EACnBC,EAAsB,EACtBC,GAA+B,EAC/BC,KACAC,GAAmB,EACnBj0D,GACIoD,IAAK,KACLs0C,QACI6a,UAAW,EACXV,kBAAmB,KAEvBO,eAAgB,cAChBC,YAAa,KACbC,gBAAiB,KACjBnrC,OAAQ,KACRw0B,eAAgB;AAChBruB,SACItnB,KAAM,UACNsrD,SAAU,eAEdJ,cACIsB,iBAAiB,EACjBC,sBAAuB,KACvBC,oBAAqB,MAEzB3pD,MACI2hC,OAAQ,WAGhBwpB,GACI/sC,OAAQ,4BACRgtC,YAAa,2BACbC,mBAAoB,4BACpBC,cAAe,6BACfC,cAAe,6BACfC,eAAgB,wBAChBC,aAAc,4BACdn0D,SAAU,uBACVo0D,KAAM,+BACNC,KAAM,0BACNC,qBAAsB,qCACtBr6C,YAAa,2BACbs6C,0BAA2B,2CAC3BC,iBAAkB,iCAClBxxC,KAAM,0BACNyxC,QAAS,6BACTt1C,KAAM,0BACNiE,OAAQ,4BACRpJ,MAAO,2BACP06C,eAAgB,8BAChBC,aAAc,4BACdptC,MAAO,2BACPqtC,WAAY,iCACZC,kBAAmB,4BACnBC,aAAc,iCACdC,SAAU,oCACVC,eAAgB,8BAChBC,sBAAuB,sCACvBC,UAAW,yBAEfC,KACAC,EAAiC,GAAIz0D,IAAGoP,QACxCslD,EAA+B,GAAI10D,IAAGoP,QAatCulD,EAA6B,WACzB,GAAIC,GAAmB51D,EAAQkxD,aAAauB,sBACxCoD,EAAa71D,EAAQkxD,aAAawB,oBAClCrzC,GACIwF,QAASovC,EACT7uC,MAAO4tC,EAGXD,KACI6C,EACA51D,EAAQ27C,eAAep2B,SAASqwC,EAAiB,GAAI5kB,OAAS3xB,GAAMnE,KAChE,SAAS46C,GACLL,EAA+BnlD,QAAQwlD,IAE3C,WACIL,EAA+BjlD,UAC/BpN,EAAI,wDAA0DwyD,EAAiB,WAKvFH,EAA+BjlD,UAG/BqlD,EACA71D,EAAQ27C,eAAep2B,SAASswC,EAAY,GAAI7kB,OAAS3xB,GAAMnE,KAC3D,SAAS46C,GACLJ,EAA6BplD,QAAQwlD,IAEzC,WACIJ,EAA6BllD,UAC7BpN,EAAI,gEAAkEyyD,EAAY,WAK1FH,EAA6BllD,YAOzCulD,EAAoB,SAASR,GACzB,GAAIS,GAAsB,GAAIh1D,IAAGoP,OAwBjC,OAtBAslD,GAA6Bx6C,KAAK,SAASoyB,GACvC2oB,EAA4B3oB,EAAKioB,GAE5BA,EAAUnkB,IASX4kB,EAAoB1lD,WARpBilD,EAAUnkB,IAAM9D,EAAI8D,IACpBmkB,EAAUllD,OAAS,WACfklD,EAAUllD,OAAS,KACnB6lD,GAAKX,GACLS,EAAoB1lD,aAM7B,WAICtK,EAAKuvD,GACLS,EAAoB1lD,YAGjB0lD,GAGXG,EAAqB,SAAS93C,EAAIvO,EAAMuP,GACpC,GAAIk2C,GAAYa,EAAa/3C,EAK7B,OAHAjb,GAAI,gCAAkCib,GACtCvO,EAAKumD,cAAgBh4C,EAEdre,EAAQ27C,eAAep2B,SAASzV,EAAMylD,EAAWl2C,GAAMnE,KAC1D,WACI44C,IACAoC,GAAKX,GACLC,EAAkBn3C,GAAI/N,WAE1B,WACIklD,EAAkBn3C,GAAI7N,UAIjBxQ,EAAQkxD,aAAasB,iBACtB8D,EAA+Bj4C,EAAIk3C,MAKnDgB,EAA4B,WACxB,GAAIvC,EAAqB3uD,OAAQ,CAC7B0uD,GAA+B,CAE/B,IAAIyC,GAAqBxC,EAAqBv9C,OAE1C+/C,GAAmBC,OACnBC,EAAkCF,GAGlCG,EAA+BH,OAInCzC,IAA+B,GAIvC6C,EAAY,SAASv4C,GACjB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBzwC,SAGtDqzC,EAAc,SAASz4C,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBa,iBAGtDgC,EAAY,SAAS3yD,GACjB,MAAOyyD,GAAcvxC,EAAW4uC,EAAgB9vD,EAAO,YAG3D4yD,EAAY,SAAS34C,GACjB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBc,eAGtDiC,EAAoB,WAChB,MAAOJ,GAAcvxC,EAAW4uC,EAAgBmB,iBAGpD6B,EAAc,SAAS74C,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBiB,eAGtD9vC,EAAU,SAAShH,GACf,MAAOo1C,GAAUG,IAAIv1C,IAAOrd,GAAGoxB,GAAU3pB,gBAAgByqD,EAAoB70C,IAGjFnI,EAAc,SAASmI,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB7wC,OAGtD8zC,EAAW,SAAS94C,GAChB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB75C,QAGtD+8C,EAAc,SAAS/4C,GAGnB,MAAU,OAANA,EACOw4C,EAAcvxC,EAAW4uC,EAAgBU,4BAC5CiC,EAAcvxC,EAAW4uC,EAAgBW,kBAI1CgC,EAAcxxC,EAAQhH,GAAK61C,EAAgBS,uBAC9CkC,EAAcxxC,EAAQhH,GAAK61C,EAAgB55C,cAGnD+8C,EAAW,SAASh5C,GAChB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBtsC,QAGtDvB,EAAU,SAAShI,GACf,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB10C,OAGtD83C,EAAa,SAASj5C,GAClB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBY,UAGtD+B,EAAgB,SAAS3iD,EAASqjD,GAC9B,MAAOrjD,IAAWlT,GAAGkT,GAASzL,gBAAgB8uD,IAGlDnB,EAAe,SAAS/3C,GACpB,MAAO00C,IAAkB8D,EAAcxxC,EAAQhH,GAAK61C,EAAgBqB,YAGxEvvD,EAAO,SAASZ,GACZA,GAAMpE,GAAGoE,GAAI2C,SAAS/H,EAAQstB,QAAQtnB,OAM1CiwD,EAA8B,SAAS/hC,EAAaqhC,GAChD,GAAI37B,GAAW1F,EAAYjuB,MAAM2zB,SAC7BD,EAAYzF,EAAYjuB,MAAM0zB,SAE9BA,IAAaC,IAAa27B,EAAUtvD,MAAM2zB,WAAa27B,EAAUtvD,MAAM0zB,WACvE34B,GAAGu0D,GAAWtuD,KACV2yB,SAAUA,EACVD,UAAWA,KAQvB28B,EAAiC,SAASj4C,EAAIk3C,GAC1C,GAAIiC,GAAahC,EAAkBn3C,KAAO,GAAIrd,IAAGoP,SAAUI,UACvDinD,EAA2B,GAAIz2D,IAAGoP,OAqBtC,OAnBAqlD,GAA+Bv6C,KAAK,SAASoyB,GACzCkqB,EAAWt8C,KACP,WACIu8C,EAAyBnnD,WAE7B,WACI2lD,EAA4B3oB,EAAKioB,GAEjCA,EAAUllD,OAAS,WACfklD,EAAUllD,OAAS,KACnBonD,EAAyBnnD,WAG7BilD,EAAUnkB,IAAM9D,EAAI8D,IACpB8kB,GAAKX,OAKVkC,GAWXC,EAAsB,WAClB,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACArT,EACA4Q,EACAF,EACA4C,EACAC,CAKJ,IAHA90D,EAAI,oBAG0B,MAA1BpD,EAAQoyD,eACR,KAAM,IAAIjrD,OAAM,oDAIpB,IAAInG,GAAGoL,SAASpM,EAAQoyD,gBAAiB,CAGrC,GAFAuF,EAAWxpD,SAAS85B,eAAejoC,EAAQoyD,gBAE1B,OAAbuF,EACA,KAAM,IAAIxwD,OAAMnG,GAAG0L,OAAO,0CAA2C1M,EAAQoyD,gBAGjFwF,GAAaD,EAASjkD,cAErB,CACD,GAAyCpS,SAArCtB,EAAQoyD,eAAe1+C,UACvB,KAAM,IAAIvM,OAAM,gGAIpBywD,GAAa53D,EAAQoyD,eAAe1+C,UA4ExC,GAzEAkkD,EAAa52D,GAAGsL,QAAQsrD,GACxBE,EAAiB3pD,SAASC,cAAc,OACxC0pD,EAAeviD,YAAYvU,GAAGuS,UAAUqkD,IACxCM,EAAal3D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgB7zD,UAI5DL,EAAQmnB,SACR6wC,EAAgBh3D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgB/sC,QAC/D6wC,GACAh3D,GAAGg3D,GAAejxD,UASrB/F,GAAGyE,aAAgBzE,GAAGiW,kBAAkB8C,WACzCs7C,EAAiBr0D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBmB,gBAChEA,GACAr0D,GAAGq0D,GAAgBtuD,UAI3B49C,EAAW3jD,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBO,MAI1D9P,IAAa3jD,GAAGyE,cAChBrC,EAAI,0BAA2B,QAC/BpC,GAAG2jD,GAAU59C,UAGZ/F,GAAGiW,kBAAkB8C,SAajB/Y,GAAGk3D,GAAY/uD,aAAamqD,IAAwB3O,IACzDsT,EAAaj3D,GAAG2jD,GAAUl8C,gBAAgByrD,EAAgBkB,UAC1D6C,GAAcj3D,GAAGi3D,GAAYlxD,WAb7BmxD,EAAWr6C,gBAAgBy1C,GAEvB3O,GAAY3jD,GAAG2jD,GAAUx7C,aAAakqD,IAItCryD,GAAG2jD,GAAU19C,KACTf,QAAS,UAWrBqvD,EAAYv0D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBqB,WAC1DxC,EAGIwC,IACLtB,EAAmB3uB,SAASiwB,EAAUjsD,aAAa6pD,IAEnDc,EAAmBA,EAAmB,EAAIA,EAAmB,KAE7DjB,EAAchyD,GAAGu0D,GAAWpsD,aAAaiqD,IAPzCmC,GAAav0D,GAAGu0D,GAAWxuD,SAS/BgsD,EAAiBA,GAAkBwC,EAEnC3C,EAAsB5xD,GAAG82D,GAAgB5vD,WAAWgsD,EAAgBgB,mBAAmB7vD,OAAS,EAChGwtD,EAAsB7xD,GAAG82D,GAAgB5vD,WAAWgsD,EAAgBtsC,OAAOviB,OAAS,EAEpFwyD,EAAe72D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBQ,MAE9C,MAAhBmD,EACA,KAAM,IAAI1wD,OAAM,0DAapB,OAVA4wD,GAAeF,EAAankD,UAC5BmkD,EAAankD,UAAY,GAGrBokD,EAAetvD,qBAAqB,UAAUnD,QAC9C8I,SAASC,cAAc,UAG3BhL,EAAI,8BAGAiuD,SAAUrwD,GAAGsL,QAAQwrD,EAAepkD,WACpCykD,aAAcn3D,GAAGsL,QAAQyrD,KAIjCK,EAAc,SAAShzD,EAAID,EAAOitB,GAC9B,GAAIimC,GAAWjmC,EACXkmC,EAAWD,EAASzvD,UAEpBzD,GAAQ,IACRmzD,EAAWt3D,GAAGq3D,GAAU3vD,WAAWvD,GAAO0D,aAI9CwvD,EAASzxD,aAAaxB,EAAIkzD,IAG9B3B,EAAiC,SAASH,GACtC,GAAIn4C,GAAKm4C,EAAmBn4C,GACxBk6C,EAAgB/B,EAAmB+B,cACnCC,EAAqBD,GAAiBA,EAAclC,cACpDd,EAAYa,EAAa/3C,GACzBgB,GACI0F,qBAAsByxC,EAAmBzxC,qBACzCF,QAASovC,EACTp4B,QAAQ,EACRzW,OAAO,EAGXpkB,IAAGiW,kBAAkBiD,cACjBq7C,EACIv1D,EAAQ03C,OAAO6a,WAAavyD,EAAQ03C,OAAO6a,WAAauB,GACxDwC,EAA+Bj4C,EAAIk3C,GACnCgB,KAGAR,EAAkBR,GAAW55C,KAAK,WAC9B65C,EAAkBn3C,GAAM,GAAIrd,IAAGoP,QAE/BolD,EAAkBn3C,GAAI1C,KAAK,WACvBkR,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,qBAM/B,MAAtB2G,EACAC,GAAiBp6C,EAAIm6C,GAGrBrC,EAAmB93C,EAAIk6C,EAAel5C,KAOlDk3C,IAGChB,IACLQ,EAAkBR,GAClBgB,MAIRG,EAAoC,SAASF,GACzC,GAAIn4C,GAAKm4C,EAAmBn4C,GACxBsL,EAAe6sC,EAAmB7sC,aAClC+uC,EAAiBlC,EAAmBkC,eACpCnD,EAAYa,EAAa/3C,GACzBgB,GACI0F,qBAAsByxC,EAAmBzxC,qBACzCK,MAAO4tC,EACPnuC,QAASovC,EAGjB,IAAIsB,EACA,GAAI5rC,EAAc,CACd,KAAI3pB,EAAQ03C,OAAO6a,WAAavyD,EAAQ03C,OAAO6a,WAAauB,GASxD,MAJI4E,IACA3C,EAAkBR,GAGfv1D,EAAQ27C,eAAep2B,SAASoE,EAAc4rC,EAAWl2C,GAAMnE,KAClE,WACIg7C,GAAKX,GACLzB,IACAjnC,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,oBAGzD,WACIyE,EAA+Bj4C,EAAIk3C,GACnC1oC,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,oBAjB7DyE,GAA+Bj4C,EAAIk3C,GACnCgB,QAsBJD,GAA+Bj4C,EAAIk3C,GACnCgB,KAKZoC,GAAsB,SAASt6C,EAAIu6C,GAC/B,GAAIC,GAAMzB,EAAY/4C,GAElBy6C,EAA4B,MAANz6C,EAAa61C,EAAgBW,iBAAmBX,EAAgB55C,WAEtFu+C,KAAQ73D,GAAG63D,GAAKpxD,SAASqxD,KACzBD,EAAM73D,GAAG63D,GAAKpwD,gBAAgBqwD,IAG9BD,IACA73D,GAAG63D,GAAK5xD,KAAK2mC,MAAOgrB,EAAU,MAC9BC,EAAIvjD,aAAa,gBAAiBsjD,KAI1C1C,GAAO,SAAS9wD,GACZA,GAAMpE,GAAGoE,GAAI4C,YAAYhI,EAAQstB,QAAQtnB,OAG7CyyD,GAAmB,SAASM,EAAmBC,GAC3C,GAAIC,GAAkB7C,EAAa2C,GAC/BG,EAAkB9C,EAAa4C,EAEnC51D,GAAIpC,GAAG0L,OAAO,qFAAsFqsD,EAAmBC,EAAmBA,IAG1IxD,EAAkBwD,GAAmB99C,KAAK,WACtC44C,IACA0B,EAAkBuD,GAAmBzoD,UACrClN,EAAIpC,GAAG0L,OAAO,uEAAwEssD,EAAmBD,IACzGE,EAAgB7nB,IAAM8nB,EAAgB9nB,IACtC8kB,GAAK+C,IAET,WACIzD,EAAkBuD,GAAmBvoD,UAChCxQ,EAAQkxD,aAAasB,iBACtB8D,EAA+ByC,EAAmBE,KAKlEj4D,IAAGwG,OAAOxH,EAASqf,GACnBjc,EAAMpD,EAAQoD,IAITpC,GAAGiW,kBAAkBiD,gBACtBla,EAAQ03C,OAAOma,kBAAoB,EACnC7xD,EAAQ03C,OAAO6a,UAAY,GAG/BjtC,EAAYtlB,EAAQqyD,YACpBU,EAA4CzxD,SAA3BtB,EAAQ27C,eACzBmX,EAAe4E,IAEf/B,IAEA30D,GAAGwG,OAAOvE,MACNsuC,OAAQ,WACJnuC,EAAI,8BAEJ0wD,EAAsB,EAEtBxuC,EAAU5R,UAAYo/C,EAAazB,SACnCrrD,EAAKixD,KACLh0D,KAAKk2D,oBACL/mC,EAAWpyB,EAAQsyD,iBAAmBuE,EAAcvxC,EAAW4uC,EAAgBQ,MAE/EtxD,EAAI,gCAGRuvD,cAAe,SAAStvD,GACpB,GAAI+1D,GAAep4D,GAAGuS,UAAUlQ,EAChCiiB,GAAU5R,UAAY,GACtB4R,EAAU/P,YAAY6jD,IAG1Br7C,MAAO,WACH9a,KAAKsuC,UAGT2W,WAAY,WACR91B,EAAS1e,UAAY,IAGzB87C,cAAe,WACXqE,GAAmB,GAGvBz0C,QAAS,SAASf,EAAIrc,EAAMq3D,EAAaC,EAAaC,GAClD,GAIIC,GAJAC,EAASz4D,GAAGuS,UAAUu/C,EAAaqF,cACnCuB,EAAa7C,EAAc4C,EAAQvF,EAAgB7wC,MACnD60C,EAAarB,EAAcvxC,EAAW4uC,EAAgB7zD,UACtDkjB,EAAgBg2C,EAAQ9F,EAAUC,QAAUthC,CAG5CmnC,KACA9F,EAAUG,IAAIv1C,GAAMo7C,GAGxBz4D,GAAGy4D,GAAQ1xD,SAASmrD,EAAoB70C,GACxC65C,EAAWr6C,gBAAgBy1C,GAEvBoG,IACA14D,GAAG04D,GAAY5wD,QAAQ9G,GACvB03D,EAAWpkD,aAAa,QAAStT,IAGrCy3D,EAAOnkD,aAAa29C,EAAc50C,GAE9Bg7C,EACAjB,EAAYqB,EAAQJ,EAAYl0D,MAAOoe,GAGvCA,EAAchO,YAAYkkD,GAG1BH,GACAG,EAAOxzD,MAAMC,QAAU,OACvBlF,GAAGy4D,GAAQ1xD,SAASyrD,KAGpBxtD,EAAKoxD,EAAY/4C,IACjBrY,EAAKqgB,EAAQhI,IACbrY,EAAKgxD,EAAU34C,IACfrY,EAAKqxD,EAASh5C,IACdrY,EAAKmxD,EAAS94C,IACdrY,EAAK8wD,EAAYz4C,IAEbw1C,GACA5wD,KAAK+pD,WAAW3uC,GAGpBm7C,EAAQpD,EAAa/3C,GACjBm7C,IAAUA,EAAMpoB,KAChBskB,EAA6Bx6C,KAAK,SAASy+C,GACvCH,EAAMpoB,IAAMuoB,EAAWvoB,IACnBuoB,EAAW1zD,MAAM0zB,WAAaggC,EAAW1zD,MAAM2zB,UAC/C54B,GAAGw4D,GAAOvyD,KACN0yB,UAAWggC,EAAW1zD,MAAM0zB,UAC5BC,SAAU+/B,EAAW1zD,MAAM2zB,WAInCs8B,GAAKsD,OAMrB7J,eAAgB,SAAStxC,EAAIrc,EAAMq3D,EAAaC,GAC5Cr2D,KAAKmc,QAAQf,EAAIrc,EAAMq3D,EAAaC,GAAa,IAGrDrR,cAAe,WACX71B,EAAS7c,YAAYk+C,EAAUC,SAC/BD,EAAUC,QAAUvlD,SAASwlD,yBAC7BF,EAAUG,QAGdnK,WAAY,SAASprC,GACjBrd,GAAGqkB,EAAQhH,IAAKtX,UAGpBqiD,UAAW,SAAShkD,GAChB,GAAIw0D,GAAcx0D,CAElB,IAAIw0D,EAAa,CAEb,KAAiD,MAA1CA,EAAYtwD,aAAa2pD,IAC5B2G,EAAcA,EAAY9yD,UAG9B,OAAOw+B,UAASs0B,EAAYtwD,aAAa2pD,MAIjD4G,YAAa,WACT,MAAOznC,IAGX85B,qBAAsB,SAAS7tC,GAC3B,GAAIvI,GAAWI,EAAYmI,EAE3BvI,IAAY9U,GAAG8U,GAAU/N,SAAS/H,EAAQstB,QAAQgkC,WAGtDxI,eAAgB,SAASzqC,EAAIrc,GACzB,GAAI83D,GAAa5jD,EAAYmI,EAEzBy7C,KACA94D,GAAG84D,GAAYhxD,QAAQ9G,GACvB83D,EAAWxkD,aAAa,QAAStT,KAIzC8pD,aAAc,SAASztC,GACnBrY,EAAKkQ,EAAYmI,KAGrB2tC,aAAc,SAAS3tC,GACnB63C,GAAKhgD,EAAYmI,KAGrB07C,WAAY,SAAS30D,GACjB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgB7wC,OAG3CqC,UAAW,WACP,MAAO1lB,GAAQmnB,QAAU0vC,EAAcvxC,EAAW4uC,EAAgB/sC,SAGtEwjC,mBAAoB,WAChB3kD,EAAKixD,MAGTvM,mBAAoB,WAChBwL,GAAKe,MAGTxM,YAAa,WACT,MAAOoM,GAAcvxC,EAAW4uC,EAAgBO,OAGpDtJ,uBAAwB,WACpB,MAAOyH,IAGXzG,UAAW,SAAS9tC,GAChBrY,EAAKqxD,EAASh5C,KAGlBmvC,gBAAiB,WACb,MAAOqF,IAGXpF,UAAW,SAASpvC,GAChB63C,GAAKmB,EAASh5C,KAGlBmqC,iBAAkB,SAASnqC,GACvB,MAAOgH,GAAQhH,IAGnB4tC,aAAc,SAAS5tC,GACnB,GAAI27C,GAAO9C,EAAY74C,EAEvB27C,IAAQh5D,GAAGg5D,GAAMjyD,SAAS/H,EAAQstB,QAAQgkC,WAG9C/I,gBAAiB,SAASlqC,GACtB,MAAOrd,IAAGqkB,EAAQhH,IAAK5W,SAAS+rD,IAGpCzH,aAAc,SAAS1tC,GACnB,GAAI27C,GAAO9C,EAAY74C,EAEvB27C,IAAQh5D,GAAGg5D,GAAMhyD,YAAYhI,EAAQstB,QAAQgkC,WAGjD2I,WAAY,SAAS70D,GACjB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBiB,cAAc,IAGzDvJ,aAAc,SAASvtC,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBgB,oBAGtDgF,YAAa,SAAS90D,GAClB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBgB,mBAAmB,IAG9DnI,eAAgB,SAAS1uC,EAAI+P,EAAQC,GACjC,GACIuqC,GADAC,EAAMzB,EAAY/4C,EAGlBw6C,IAAOxqC,EAAQ,IACfuqC,EAAUtxD,KAAKC,MAAM6mB,EAASC,EAAQ,KAEtB,MAAZuqC,EACA5yD,EAAK6yD,GAGL3C,GAAK2C,GAGTF,GAAoBt6C,EAAIu6C,KAIhCtZ,oBAAqB,SAASlxB,EAAQC,GAClCprB,KAAK8pD,eAAe,KAAM3+B,EAAQC,IAGtC4+B,aAAc,SAAS5uC,GACnB,GAAIw6C,GAAMzB,EAAY/4C,EAEtBw6C,IAAO7yD,EAAK6yD,IAGhBM,kBAAmB,WACfl2D,KAAKgqD,gBAGTsB,cAAe,SAASlwC,GACpBs6C,GAAoBt6C,EAAI,GACxBpb,KAAKk2D,kBAAkB96C,IAG3BquC,mBAAoB,WAChBzpD,KAAKsrD,iBAGThB,WAAY,SAASlvC,GACjB,IAAKw1C,EAAkB,CACnB,GAAIpwC,GAASmzC,EAAUv4C,EAEvBoF,IAAUziB,GAAGyiB,GAAQzb,YAAYhI,EAAQstB,QAAQtnB,QAIzDgnD,WAAY,SAAS3uC,GACjBrY,EAAK4wD,EAAUv4C,KAGnB87C,SAAU,SAAS/0D,GACf,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBzwC,QAAQ,IAGnDuqC,WAAY,SAAS3vC,GACjB63C,GAAKiB,EAAS94C,IACdrY,EAAK8wD,EAAYz4C,KAGrB0qC,aAAc,SAAS1qC,GACnBpb,KAAKmpD,cAAc/tC,EAAIre,EAAQ+I,KAAK2hC,QACpCznC,KAAKm3D,oBAAoB/7C,GACzBrY,EAAKsxD,EAAWj5C,KAGpBkuC,UAAW,SAASluC,GAChBrY,EAAKmxD,EAAS94C,KAGlBg8C,QAAS,SAASj1D,GACd,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgB75C,OAAO,IAGlDigD,iBAAkB,SAASl1D,GACvB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBa,gBAAgB,IAG3DqF,oBAAqB,SAAS/7C,GAC1B63C,GAAKY,EAAYz4C,IACjBrY,EAAKmxD,EAAS94C,KAGlB4qC,gBAAiB,SAAS5qC,GACtBpb,KAAKmpD,cAAc/tC,EAAI,IACvBpb,KAAK+qD,WAAW3vC,GAChB63C,GAAKoB,EAAWj5C,KAGpBwvC,iBAAkB,SAASxvC,GACvB63C,GAAKc,EAAU34C,KAGnBwwC,iBAAkB,SAASxwC,GACvBrY,EAAKgxD,EAAU34C,KAGnBk8C,eAAgB,SAASn1D,GACrB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBc,cAAc,IAGzDwF,QAAS,SAASp1D,GACd,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBtsC,OAAO,IAGlDpH,WAAY,SAASnC,EAAItV,GACrB,GAAIyW,GAAO6G,EAAQhI,EAEfmB,KACA02C,GAAK12C,GACLxe,GAAGwe,GAAM1W,QAAQC,KAIzBqjD,cAAe,SAAS/tC,EAAItV,GACxB,GAAI0xD,GAAS5D,EAAcxxC,EAAQhH,GAAK61C,EAAgBe,WAEpDwF,KAEY,MAAR1xD,EACA/H,GAAGy5D,GAAQvxD,YAGXlI,GAAGy5D,GAAQ3xD,QAAQC,KAK/B0jD,YAAa,SAASpuC,GAClBrd,GAAGqkB,EAAQhH,IAAKrW,YAAYurD,GAC5BvtD,EAAKsxD,EAAWj5C,KAGpB0vC,YAAa,SAAS1vC,GAClBrd,GAAGqkB,EAAQhH,IAAKtW,SAASwrD,GACzB2C,GAAKoB,EAAWj5C,KAGpByxC,gBAAiB,SAASzxC,EAAIk6C,EAAexzC,GACpC9hB,KAAKslD,gBAAgBlqC,KACtB21C,EAAqBlxD,MAAMub,GAAIA,EAAI0G,qBAAsBA,EAAsBwzC,cAAeA,KAC7FxE,GAAgCwC,MAIzC3G,gBAAiB,SAASvxC,EAAIsL,EAAc+uC,EAAgB3zC,GACnD9hB,KAAKslD,gBAAgBlqC,KACtB21C,EAAqBlxD,MAAMiiB,qBAAsBA,EAAsB0xC,QAAQ,EAAMp4C,GAAIA,EAAIsL,aAAcA,EAAc+uC,eAAgBA,KACxI3E,GAAgCwC,MAIzCzE,UAAW,SAAS1tD,GAChB,MAAOpD,IAAGiW,kBAAkB4C,iBAAmBk9C,EAAU3yD,IAG7D2tD,WAAY,SAAS3tD,EAAMf,EAAS4uD,GAChC,GAAIyI,GAAS3D,EAAU3yD,GACnBu2D,EAAY9D,EAAc6D,EAAQxG,EAAgBI,eAClDsG,EAAUF,EAAOlyD,qBAAqB,SAAS,GAC/CqyD,EAAYhE,EAAc6D,EAAQxG,EAAgBE,oBAClD0G,EAAQjE,EAAc6D,EAAQxG,EAAgBK,gBAC9CpkD,EAAU,GAAInP,IAAGoP,QAEjB2qD,EAAe,WACXF,EAAUt0D,oBAAoB,QAASy0D,GACvCF,GAASA,EAAMv0D,oBAAoB,QAAS00D,GAC5C9qD,EAAQK,WAGZwqD,EAAqB,WACjBH,EAAUt0D,oBAAoB,QAASy0D,GACvCN,EAAOQ,SAGXD,EAAiB,WACbP,EAAOn0D,oBAAoB,QAASw0D,GACpCD,EAAMv0D,oBAAoB,QAAS00D,GACnCP,EAAOQ,QAEP/qD,EAAQG,QAAQsqD,GAAWA,EAAQjvD,OAc3C,OAXA+uD,GAAOt0D,iBAAiB,QAAS20D,GACjCF,EAAUz0D,iBAAiB,QAAS40D,GACpCF,GAASA,EAAM10D,iBAAiB,QAAS60D,GAErCL,IACAA,EAAQjvD,MAAQsmD,GAEpB0I,EAAU1xD,YAAc5F,EAExBq3D,EAAOS,YAEAhrD,MC/gCnBnP,GAAGo6D,eAAiB,SAASC,EAAGC,GAC5B,YAqBA,SAASxO,GAAWppD,GAChB8S,EAASrQ,OAAOzC,EAAS2b,EAAKk8C,UAAW,SAAS7jC,GAE9CA,EAAQA,GAASttB,OAAOstB,KAGxB,IAAI7mB,GAAS6mB,EAAM7mB,QAAU6mB,EAAM8jC,UAEnCn8C,GAAKo8C,UAAU5qD,EAAQ6mB,KA3B/B,GAAIlhB,GAAW,GAAIxV,IAAGqV,eAClBgJ,GACIk8C,UAAW,QACXG,SAAU,KACVD,UAAW,SAAS5qD,EAAQ6mB,KAKpC12B,IAAGwG,OAAOvE,MACN6pD,WAAY,SAASppD,GACjBopD,EAAWppD,IAGf6S,QAAS,WACLC,EAASD,aAiBjBvV,GAAGwG,OAAO8zD,GACNK,kBAAmB,SAASzvD,GACxB,MAAOA,GAAK0vD,UAGhBC,kBAAmB,WACf,MAAOrlD,MAIfxV,GAAGwG,OAAO6X,EAAMg8C,GAEZh8C,EAAKq8C,UACL5O,EAAWztC,EAAKq8C,WClDxB16D,GAAG2oD,wBAA0B,SAAS0R,GAClC,YAqBA,SAASS,GAAajrD,EAAQ6mB,GAC1B12B,GAAGY,KAAKm6D,EAAgB,SAASC,EAAYjqC,GACzC,GACIpN,GADAs3C,EAA2BD,EAAWp7D,OAAO,GAAGC,cAAgBm7D,EAAWl7D,MAAM,EAGrF,IAAIue,EAAKkrC,WAAW,KAAO0R,GAA0BprD,GAKjD,MAJA8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC7P,GAAGoS,eAAeskB,GAClBrY,EAAKjc,IAAIpC,GAAG0L,OAAO,+DAAgE2S,EAAK6rC,UAAUvmC,GAASA,IAC3GoN,EAAQpN,IACD,IA7BnB,GAAIu3C,MACA78C,GACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBC,aAAc,SAASnmC,KACvB8J,SAAU,SAAS9J,KACnBomC,QAAS,SAASpmC,KAClBqmC,QAAS,SAASrmC,KAClBsmC,WAAY,SAAStmC,KACrBumC,UAAW,SAASvmC,MAExBo3C,GACIt4C,OAAQ,SAASpF,GAAMgB,EAAKoP,SAASpQ,IACrCuJ,MAAQ,SAASvJ,GAAMgB,EAAK0rC,QAAQ1sC,IACpC22C,aAAc,SAAS32C,GAAMgB,EAAKyrC,aAAazsC,IAC/ChE,MAAO,SAASgE,GAAMgB,EAAK2rC,QAAQ3sC,IACnC02C,eAAgB,SAAS12C,GAAMgB,EAAK4rC,WAAW5sC,IAkBvDrd,IAAGwG,OAAO6X,EAAMg8C,GAEhBh8C,EAAKk8C,UAAY,QACjBl8C,EAAKo8C,UAAYK,EACjBz8C,EAAKq8C,SAAWr8C,EAAKkrC,WAAWsP,cAEhC74D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo6D,eAAe/7C,EAAM68C,KC1ChDl7D,GAAGoqD,qBAAuB,SAASiQ,GAC/B,YAiBA,SAASS,GAAajrD,EAAQ6mB,GAC1B,GAAIrY,EAAKkrC,WAAWwP,WAAWlpD,IAAWwO,EAAKkrC,WAAW0P,WAAWppD,GAAS,CAC1E,GAAI8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC8N,EAASU,EAAKksC,kBAAkB5mC,EAGhChG,KAAW3d,GAAG2d,OAAOoC,YACrB1B,EAAKjc,IAAIpC,GAAG0L,OAAO,4DAA6D2S,EAAK6rC,UAAUvmC,GAASA,IACxG3jB,GAAGoS,eAAeskB,GAElBwkC,EAAqBC,mBAAmBx3C,EAAQ9T,GAAQ,KAzBpE,GAAIqrD,MACA78C,GACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBv9B,SACIjK,KAAM,iBACN8xC,aAAc,yBAElB5J,kBAAmB,SAAS5mC,KAC5BumC,UAAW,SAASvmC,KAG5B3jB,IAAGwG,OAAO6X,EAAMg8C,GAkBhBh8C,EAAKk8C,UAAY,QACjBl8C,EAAKo8C,UAAYK,EAEjB96D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo7D,oBAAoB/8C,EAAM68C,KCpCrDl7D,GAAGwrD,4BAA8B,SAAS6O,EAAGa,GACzC,YAaA,SAASG,GAAiBxrD,EAAQ6mB,GAC9B,GAAIrY,EAAKkrC,WAAW2P,YAAYrpD,GAAS,CACrC,GAAI8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC8N,EAASU,EAAKksC,kBAAkB5mC,EAEhChG,KAAW3d,GAAG2d,OAAOoC,YACrB1B,EAAKjc,IAAIpC,GAAG0L,OAAO,kEAAmE2S,EAAK6rC,UAAUvmC,GAASA,IAC9Gu3C,EAAqBC,mBAAmBx3C,EAAQ9T,KAlB5D,GAAIwO,IACIkrC,WAAY,KACZgB,kBAAmB,SAAS5mC,KAC5BvhB,IAAK,SAASC,EAASwnD,KAG1BqR,KACDA,MAgBJ78C,EAAKk8C,UAAY,UACjBl8C,EAAKo8C,UAAYY,EAEjBr7D,GAAGwG,OAAO6X,EAAMg8C,GAChBr6D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo7D,oBAAoB/8C,EAAM68C,KCzBrDl7D,GAAGqqD,0BAA4B,SAAShsC,GACpC,YAEAA,GAAKk8C,UAAY,QACjBl8C,EAAKq8C,SAAW,KAEhB16D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGwrD,4BAA4BntC,QCVvDre,GAAGo7D,oBAAsB,SAASf,EAAGa,GACjC,YAWA,SAASI,GAAyB33C,GAC9B,GAAI43C,GAAkBl9C,EAAK6rC,UAAUvmC,GACjC5O,EAASwmD,EAAgBvmD,YAAY,IAMzC,OAJID,GAAS,IACTwmD,EAAkBA,EAAgBtmD,OAAO,EAAGF,IAGzCwmD,EAGX,QAASC,GAAqB73C,GAC1B,GAAI83C,GAAWp9C,EAAK6rC,UAAUvmC,EAC9B,OAAO3jB,IAAG6U,aAAa4mD,GAI3B,QAASC,GAAiBC,EAAoBh4C,GAC1C,GACIi4C,GADAr8C,EAAUo8C,EAAmBhxD,KAGjBrK,UAAZif,GAAyBvf,GAAGsL,QAAQiU,GAASlb,OAAS,IACtDu3D,EAAgBJ,EAAqB73C,GAEfrjB,SAAlBs7D,IACAr8C,EAAUA,EAAU,IAAMq8C,GAG9Bv9C,EAAKmsC,UAAU7mC,EAAQpE,IAG3BlB,EAAKosC,sBAAsB9mC,GAAQ,GAIvC,QAASk4C,GAAyBjC,EAASj2C,GACvCu3C,EAAqBL,oBAAoB11D,OAAOy0D,EAAS,OAAQ,WAC7D8B,EAAiB9B,EAASj2C,KAKlC,QAASm4C,GAA6BlC,EAASj2C,GAC3Cu3C,EAAqBL,oBAAoB11D,OAAOy0D,EAAS,QAAS,SAASljC,GAEvE,GAAIpE,GAAOoE,EAAMqlC,SAAWrlC,EAAMslC,KAErB,MAAT1pC,GACAopC,EAAiB9B,EAASj2C,KAzDtC,GAAItF,IACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBU,kBAAmB,SAAS5mC,KAC5BumC,UAAW,SAASvmC,KACpB6mC,UAAW,SAAS7mC,EAAQpE,KAC5BkrC,sBAAuB,SAAS9mC,EAAQ+mC,KAwDhD1qD,IAAGwG,OAAO6X,EAAMg8C,GAEhBh8C,EAAKq8C,SAAWr8C,EAAKkrC,WAAWsP,cAEhC74D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo6D,eAAe/7C,EAAM68C,IAE5Cl7D,GAAGwG,OAAO00D,GACNC,mBAAoB,SAAS99C,EAAIxN,EAAQosD,GACrC,GAAIN,GAAqBt9C,EAAKkrC,WAAWqB,aAAavtC,EAEtDgB,GAAKosC,sBAAsBptC,GAAI,GAE/Bs+C,EAAmBhxD,MAAQ2wD,EAAyBj+C,GAEhD4+C,GACAN,EAAmBO,QAGvBL,EAAyBF,EAAoBt+C,GAC7Cy+C,EAA6BH,EAAoBt+C,Q7CvF9BjU","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","$el","pluginOptions","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","originalArgs","Array","prototype","call","arguments","transformedArgs","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","xformedArgs","origArgs","retVal","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","rootDataKey","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","disposeSupport","acceptFiles","focusClass","folders","hoverClass","ios8BrowserCrashWorkaround","onChange","title","buttonId","createInput","BUTTON_ID_ATTR_NAME","setMultiple","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","byUuid","byStatus","byProxyGroupId","byBatchId","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","dataIndex","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","promiseToReturn","fileOrUrl","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","fileRecord","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","accept","validation","allowedExtensions","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","messages","names","validationBase","extensionsForMessage","placeholderMatch","replacement","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","shouldParamsBeInQueryString","queue","requestData","acceptHeader","validMethods","contentType","mandatedParams","allowXRequestedWithAndCacheControl","successfulResponseCodes","DELETE","PATCH","POST","PUT","GET","onSend","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","dequeue","nextId","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","optXhr","payload","url","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","setRequestHeader","responseCode","prepareToSend","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","controller","chunkingPossible","concurrentChunkingPossible","preventRetryResponse","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","responseToReport","inProgressIdx","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","onUploadChunkPromise","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","formHandlerInstanceId","onloadCallbacks","detachLoadEvents","postMessageCallbackTimers","isCors","corsMessageReceiver","expungeFile","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","_parseJsonResponse","onloadCallback","_detachLoadEvent","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","getChunkSize","chunkFiles","resumeEnabled","xhrId","ajaxRequester","_getAjaxRequester","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","formatVersion","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","requester","getMandatedParams","_method","detectSubsampling","img","iw","naturalWidth","ih","naturalHeight","ctx","width","getContext","drawImage","getImageData","detectVerticalSquash","sy","ey","py","alpha","ratio","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","d","tmpCanvas","vertSquashRatio","dw","dh","dy","tmpCtx","sx","dx","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","imgWidth","imgHeight","opt","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetAnchor","targetProtocol","targetHostname","targetPort","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","rendered","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","TAG_IDS","TAG_INFO","274","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","vals","idHex","tagsToFindIdx","tagValHex","tagValLength","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","output","chr1","chr2","chr3","enc1","enc2","enc3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","detachPasteHandler","isImage","registerPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","formEl","_form2Obj","determineNewEndpoint","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","allowMultipleItems","dropActive","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","fileError","fullPath","isDirectory","getFilesInDirectory","allEntriesRead","entriesLeft","readFailure","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","parentRetVal","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","fileEl","fileNameEl","thumb","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","attachTo","onHandled","srcElement","getFileIdFromItem","qqFileId","getDisposeSupport","inheritedInternalApi","buttonHandlers","examineEvent","buttonType","firstLetterCapButtonType","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA,SCCT,SAASC,GACN,YAIA,SAASC,GAAKC,GACV,GAAIC,GAAcC,EAAmBF,OACjCG,EAAsBC,EAAuBH,EAKjD,OAHAI,GAASF,GACTG,EAAaL,EAAaE,GAEnBI,EAGX,QAASH,GAAuBI,GAC5B,GAAIC,GAAeC,EAAa,gBAC5BC,EAAYD,EAAa,eAG7B,OAAID,IAGAA,EAAeA,EAAaG,OAAO,GAAGC,cAAgBJ,EAAaK,MAAM,GAAGC,cAExEJ,EACO,GAAIK,IAAGL,GAAW,eAAiBF,GAAcD,GAGrD,GAAIQ,IAAG,eAAiBP,GAAcD,IAGzCG,EACO,GAAIK,IAAGL,GAAWM,aAAaT,GAGnC,GAAIQ,IAAGC,aAAaT,GAInC,QAASU,GAAUC,EAAKC,GACpB,GAAIC,GAAOd,EAAIc,KAAK,eAEpB,OAAID,IACaE,SAATD,IACAA,MAEJA,EAAKF,GAAOC,EACZb,EAAIc,KAAK,eAAgBA,GAJzB,QAOaC,SAATD,EACO,KAEJA,EAAKF,GAMpB,QAASd,GAASkB,GACd,MAAOL,GAAU,WAAYK,GAGjC,QAASb,GAAac,EAAQC,GAC1B,MAAOP,GAAUM,EAAQC,GAK7B,QAASnB,GAAaoB,EAAiBvB,GACnC,GAAIwB,GAAYD,EAAgBC,YAEhC7B,GAAE8B,KAAKzB,EAAoB0B,SAASF,UAAW,SAASG,EAAMC,GAC1D,GAAIC,GAAMC,CAEVD,GAAO,WAAWE,KAAKJ,GAAM,GAC7BE,EAAOA,EAAKG,UAAU,EAAG,GAAGpB,cAAgBiB,EAAKG,UAAU,GAC3DF,EAAsB1B,EAEtBoB,EAAUG,GAAQ,WACd,GAEIM,GAAyBC,EAFzBC,EAAeC,MAAMC,UAAU1B,MAAM2B,KAAKC,WAC1CC,IAGJ7C,GAAE8B,KAAKU,EAAc,SAASM,EAAKC,GAC/BF,EAAgBG,KAAKC,EAAkBF,MAG3CT,EAA0BL,EAAkBiB,MAAMC,KAAMX,EAExD,KACID,EAA4BJ,EAAoBiB,eAAelB,EAAMW,GAEzE,MAAOQ,GACHnC,GAAGoC,IAAI,uDAAyDD,EAAME,QAAS,SAInF,MAA+B,OAA3BjB,EACOA,EAEJC,KAIflC,EAAoB0B,SAASF,UAAYA,EAI7C,QAASzB,GAAmBoD,EAAQC,GAChC,GAAIC,GAASC,CAgDb,IA5CQD,EAFKlC,SAATiC,EAC4B,UAAxBD,EAAO7C,cACKiD,QAASnD,EAAI,OAOnBgD,EAGdzD,EAAE8B,KAAK0B,EAAQ,SAASxB,EAAMV,GACtBtB,EAAE6D,QAAQ7B,EAAM8B,IAAkB,EAClClD,EAAaoB,EAAMV,GAEdA,YAAetB,GACpB0D,EAAQ1B,GAAQV,EAAI,GAEftB,EAAE+D,cAAczC,IACrBoC,EAAQ1B,MACR5B,EAAmBkB,EAAKoC,EAAQ1B,KAE3BhC,EAAEgE,QAAQ1C,IACfqC,KACA3D,EAAE8B,KAAKR,EAAK,SAASwB,EAAKmB,GACtB,GAAIC,KAEAD,aAAoBjE,GACpBA,EAAEmE,MAAMR,EAAWM,GAEdjE,EAAE+D,cAAcE,IACrB7D,EAAmB6D,EAAUC,GAC7BP,EAAUX,KAAKkB,IAGfP,EAAUX,KAAKiB,KAGvBP,EAAQ1B,GAAQ2B,GAGhBD,EAAQ1B,GAAQV,IAIXE,SAATiC,EACA,MAAOC,GAIf,QAASU,GAAeC,GACpB,MAA2B,WAApBrE,EAAEsE,KAAKD,KACTA,EAAQE,MAAM,OACS/C,SAAxBjB,IAAW8D,GAKnB,QAASG,GAAgBH,GACrB,GAEII,GAFAC,KACAC,EAAWlC,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAOrD,OAJAxC,GAAmBuE,EAAUD,GAE7BD,EAASlE,IAAW8D,GAASnB,MAAM3C,IAAYmE,GAExCzB,EAAkBwB,GAI7B,QAASxB,GAAkB3B,GACvB,GAAIsD,GAAiBtD,CAUrB,OANW,OAAPA,GAA8B,gBAARA,IACL,IAAjBA,EAAIuD,UAAmC,IAAjBvD,EAAIuD,WAAmBvD,EAAIwD,YAEjDF,EAAiB5E,EAAEsB,IAGhBsD,EAlMX,GAAInE,GACAqD,GAAiB,eAAgB,eAoMrC9D,GAAE+E,GAAGC,aAAe,SAASC,GACzB,GAAIC,GAAO/B,KAAMgC,EAAWvC,UAAWwC,IAoBvC,OAlBAjC,MAAKrB,KAAK,SAASuD,EAAOC,GAGtB,GAFA7E,EAAMT,EAAEsF,GAEJ/E,KAAc6D,EAAea,IAG7B,GAFAG,EAAQpC,KAAKwB,EAAgBtB,MAAMgC,EAAMC,IAErB,IAAhBD,EAAKK,OACL,OAAO,MAGsB,gBAArBN,IAAkCA,EAI9CjF,EAAEqD,MAAM,UAAa4B,EAAmB,0CAHxChF,EAAKiD,MAAMgC,EAAMC,KAOF,IAAnBC,EAAQG,OACDH,EAAQ,GAEVA,EAAQG,OAAS,EACfH,EAGJjC,OAGbqC,QCtOD,SAASxF,GACN,YAIA,SAASC,GAAKC,GACLA,IACDA,MAGJA,EAAQuF,kBAAoBhF,EAC5B,IAAIN,GAAcC,EAAmBF,EAIrC,OAHAM,GAAaL,GACbuF,EAAI,GAAIxE,IAAGyE,YAAYxF,IAEhBM,EAGX,QAASW,GAAUC,EAAKC,GACpB,GAAIC,GAAOd,EAAIc,KAAKqE,EAEpB,OAAItE,IACaE,SAATD,IACAA,MAEJA,EAAKF,GAAOC,EACZb,EAAIc,KAAKqE,EAAarE,GAJtB,QAOaC,SAATD,EACO,KAEJA,EAAKF,GAIpB,QAASqE,GAAIjE,GACT,MAAOL,GAAU,cAAeK,GAGpC,QAASjB,GAAaoB,GAClB,GAAIC,GAAYD,EAAgBC,YAEhC7B,GAAE8B,KAAK,GAAIZ,IAAGyE,YAAY9D,UAAa,SAASG,EAAM6D,GAClD,GACIC,GADA5D,EAAOF,CAGX8D,GAAcrF,EAEdoB,EAAUG,GAAQ,WACd,GAAI+D,GAAOtD,MAAMC,UAAU1B,MAAM2B,KAAKC,WAClCoD,EAAsBF,EAAY1C,eAAelB,EAAM6D,EAE3D,OAAOC,MAMnB,QAAS5F,GAAmBoD,EAAQC,GAChC,GAAIC,GAASC,CAkCb,IA/BID,EADSlC,SAATiC,KAIUA,EAGdzD,EAAE8B,KAAK0B,EAAQ,SAASxB,EAAMV,GACtBA,YAAetB,GACf0D,EAAQ1B,GAAQV,EAAI,GAEftB,EAAE+D,cAAczC,IACrBoC,EAAQ1B,MACR5B,EAAmBkB,EAAKoC,EAAQ1B,KAE3BhC,EAAEgE,QAAQ1C,IACfqC,KACA3D,EAAE8B,KAAKR,EAAK,SAASwB,EAAKmB,GAClBA,YAAoBjE,GACpBA,EAAEmE,MAAMR,EAAWM,GAGnBN,EAAUX,KAAKiB,KAGvBP,EAAQ1B,GAAQ2B,GAGhBD,EAAQ1B,GAAQV,IAIXE,SAATiC,EACA,MAAOC,GAIf,QAASU,GAAeC,GACpB,MAA2B,WAApBrE,EAAEsE,KAAKD,IACE,YAAZA,GACmB7C,SAAnBkE,IAAMrB,GAGd,QAASG,GAAgBH,GACrB,GAAIK,MAAkBC,EAAWlC,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAEvE,OADAxC,GAAmBuE,EAAUD,GACtBgB,IAAMrB,GAASnB,MAAMwC,IAAOhB,GA1GvC,GACIjE,GADAmF,EAAc,iBA6GlB5F,GAAE+E,GAAGkB,gBAAkB,SAAShB,GAC5B,GAAIC,GAAO/B,KAAMgC,EAAWvC,UAAWwC,IAoBvC,OAlBAjC,MAAKrB,KAAK,SAASuD,EAAOC,GAGtB,GAFA7E,EAAMT,EAAEsF,GAEJI,KAAStB,EAAea,IAGxB,GAFAG,EAAQpC,KAAKwB,EAAgBtB,MAAMgC,EAAMC,IAErB,IAAhBD,EAAKK,OACL,OAAO,MAGsB,gBAArBN,IAAkCA,EAI9CjF,EAAEqD,MAAM,UAAa4B,EAAmB,kDAHxChF,EAAKiD,MAAMgC,EAAMC,KAOF,IAAnBC,EAAQG,OACDH,EAAQ,GAEVA,EAAQG,OAAS,EACfH,EAGJjC,OAGbqC,OC7IF,IAAItE,IAAK,SAAS0C,GACd,YAEA,QACIsC,KAAM,WAEF,MADAtC,GAAQuC,MAAMC,QAAU,OACjBjD,MAIXkD,OAAQ,SAAS/B,EAAMS,GAMnB,MALInB,GAAQ0C,iBACR1C,EAAQ0C,iBAAiBhC,EAAMS,GAAI,GAC5BnB,EAAQ2C,aACf3C,EAAQ2C,YAAY,KAAOjC,EAAMS,GAE9B,WACH7D,GAAG0C,GAAS4C,OAAOlC,EAAMS,KAIjCyB,OAAQ,SAASlC,EAAMS,GAMnB,MALInB,GAAQ6C,oBACR7C,EAAQ6C,oBAAoBnC,EAAMS,GAAI,GAC/BnB,EAAQ2C,aACf3C,EAAQ8C,YAAY,KAAOpC,EAAMS,GAE9B5B,MAGXwD,SAAU,SAASC,GAKf,QAAKA,IAKDhD,IAAYgD,IAIZhD,EAAQ+C,SACD/C,EAAQ+C,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwBjD,OAOrDkD,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAalD,EAASmD,GACnC5D,MAGX8D,OAAQ,WAEJ,MADArD,GAAQoD,WAAWE,YAAYtD,GACxBT,MAOXgE,IAAK,SAASC,GAEV,GAAqB,MAAjBxD,EAAQuC,MACR,KAAM,IAAIjF,IAAGmG,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1B1D,GAAQuC,MAAMmB,SAAqD,mBAArB1D,GAAe,UACpEwD,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9EpG,GAAGwG,OAAO9D,EAAQuC,MAAOiB,GAElBjE,MAGXwE,SAAU,SAASzF,EAAM0F,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAU5F,EAAO,QACrC,OAAO2F,GAAGE,KAAKnE,EAAQoE,eAAiBJ,IAAkBC,EAAGE,KAAKnE,EAAQoD,WAAWgB,aAGzFC,SAAU,SAAS/F,GAIf,MAHKhB,IAAG0C,GAAS+D,SAASzF,KACtB0B,EAAQoE,WAAa,IAAM9F,GAExBiB,MAGX+E,YAAa,SAAShG,GAClB,GAAI2F,GAAK,GAAIC,QAAO,QAAU5F,EAAO,QAErC,OADA0B,GAAQoE,UAAYpE,EAAQoE,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtEhF,MAGXiF,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASzE,EAAQ4E,cACV5E,EAAQ4E,cAAc,IAAMR,GAE9BpE,EAAQ6E,iBACN7E,EAAQ6E,iBAAiB,IAAMT,IAG1CM,EAAa1E,EAAQ8E,qBAAqB,KAE1CxH,GAAGY,KAAKwG,EAAY,SAASxF,EAAKxB,GAC1BJ,GAAGI,GAAKqG,SAASK,IACjBO,EAAOvF,KAAK1B,KAGb+G,EAAQE,EAAO,GAAKA,IAG/BI,gBAAiB,SAASX,GACtB,MAAO9G,IAAG0C,GAASwE,WAAWJ,GAAW,IAG7CY,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQjF,EAAQkF,WAEbD,GACoB,IAAnBA,EAAMhE,UACN+D,EAAS5F,KAAK6F,GAElBA,EAAQA,EAAME,WAGlB,OAAOH,IAGXI,QAAS,SAASC,GAGd,MAFArF,GAAQsF,UAAYD,EACpBrF,EAAQuF,YAAcF,EACf9F,MAGXiG,UAAW,WACP,MAAOlI,IAAG0C,GAASoF,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAI3F,GAAQyF,eAEHzF,EAAQyF,aAAaC,IAKkC,MAArD,WAAalH,KAAKwB,EAAQ4F,aAAaF,KAG9CC,EAAU3F,EAAQ0F,GAEF9H,SAAZ+H,GAKiC,MAA9B,WAAanH,KAAKmH,QAMxC,WACG,YAEArI,IAAGuI,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAO1I,IAAG2I,cAAcH,EAAOI,UAAUH,EAAMC,KAGnD1I,GAAG2I,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAAS7I,EAAMoI,GACxB,GAAIU,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOpJ,GACZmJ,EAAYE,QAAQjB,IAGpB,GAAIkB,OAAMtJ,IAAQ+C,KAAMqF,IAyB3C,OAlBIM,GADAF,EAAQe,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKjB,EAAQe,MAAM,KAAK,IAGxBG,UAAUlB,EAAQe,MAAM,KAAK,IAI9CX,EAAaJ,EAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBd,EAAc,GAAIkB,aAAYjB,EAAW1E,QACzC2E,EAAW,GAAIiB,YAAWnB,GAC1B9I,GAAGY,KAAKmI,EAAY,SAASnH,EAAKsI,GAC9BlB,EAASpH,GAAOsI,EAAUC,WAAW,KAGlCjB,EAAWJ,EAAaG,IAGnCjJ,GAAGoC,IAAM,SAASC,EAAS+H,GACnBhB,OAAOiB,UACFD,GAAmB,SAAVA,EAKNhB,OAAOiB,QAAQD,GACfhB,OAAOiB,QAAQD,GAAO/H,GAGtB+G,OAAOiB,QAAQjI,IAAI,IAAMgI,EAAQ,KAAO/H,GAR5C+G,OAAOiB,QAAQjI,IAAIC,KAc/BrC,GAAGsK,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAAS5G,UAAyD,oBAA7C6G,OAAOhJ,UAAUiJ,SAAShJ,KAAK8I,IAG5EvK,GAAG0K,WAAa,SAASH,GACrB,MAA6B,kBAAf,IASlBvK,GAAG8C,QAAU,SAAS6H,GAClB,MAAiD,mBAA1CH,OAAOhJ,UAAUiJ,SAAShJ,KAAKkJ,IACjCA,GAASvB,OAAOY,aAAeW,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBb,aAIrFhK,GAAG8K,WAAa,SAASC,GACrB,MAAyD,kCAAlDP,OAAOhJ,UAAUiJ,SAAShJ,KAAKsJ,IAK1C/K,GAAGgL,WAAa,SAASC,GACrB,MAAyD,sBAAlDT,OAAOhJ,UAAUiJ,SAAShJ,KAAKwJ,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CnL,GAAGoL,SAAW,SAASC,GACnB,MAAuD,oBAAhDb,OAAOhJ,UAAUiJ,SAAShJ,KAAK4J,IAG1CrL,GAAGsL,QAAU,SAASC,GAClB,MAAIC,QAAOhK,UAAUiK,KACVF,EAAOE,OAGXF,EAAOtE,QAAQ,aAAc,KAOxCjH,GAAG0L,OAAS,SAASC,GAEjB,GAAI9G,GAAQtD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,GAC9CkK,EAASD,EACTE,EAAmBD,EAAO/B,QAAQ,KAetC,OAbA7J,IAAGY,KAAKiE,EAAM,SAASjD,EAAKxB,GACxB,GAAI0L,GAAYF,EAAOzK,UAAU,EAAG0K,GAChCE,EAAWH,EAAOzK,UAAU0K,EAAmB,EAMnD,IAJAD,EAASE,EAAY1L,EAAM2L,EAC3BF,EAAmBD,EAAO/B,QAAQ,KAAMgC,EAAmBzL,EAAIiE,QAG3DwH,EAAmB,EACnB,OAAO,IAIRD,GAGX5L,GAAGgM,OAAS,SAASC,GACjB,MAAO7C,QAAO8C,MAAsD,kBAA9C1B,OAAOhJ,UAAUiJ,SAAShJ,KAAKwK,IAGzDjM,GAAGmM,WAAa,SAASC,GACrB,MAAOhD,QAAOiD,UAA8D,sBAAlD7B,OAAOhJ,UAAUiJ,SAAShJ,KAAK2K,IAG7DpM,GAAGsM,cAAgB,SAASC,GACxB,MAAOvM,IAAGgM,OAAOO,IAAqBvM,GAAGwM,QAAQD,IAGrDvM,GAAGwM,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAASvJ,GACxB,GAAIwJ,GAAiBxJ,EAAKrD,aAE1B,OAAI2M,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAIxD,OAAOyD,kBAC4C,8BAA/CrC,OAAOhJ,UAAUiJ,SAAShJ,KAAKgL,IAC3BA,EAAWrJ,MAAQuJ,EAAaF,EAAWrJ,WAKnDqJ,EAAWK,SAC8B,UAArCL,EAAWK,QAAQ/M,eACf0M,EAAWrJ,MAAQuJ,EAAaF,EAAWrJ,QAS3DpD,GAAG+M,OAAS,SAASC,GACjB,GAAI5D,OAAOO,MAAsD,kBAA9Ca,OAAOhJ,UAAUiJ,SAAShJ,KAAKuL,GAC9C,OAAO,GAIfhN,GAAGiN,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAM9J,KAAO,OAGU9C,SAAnB4M,EAAMG,UACc,mBAATnB,OACa,mBAAboB,WACoC,mBAAnCtN,IAAGuN,oBAAqBC,QAI5CxN,GAAGuN,kBAAoB,WACnB,GAAInE,OAAOqE,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOvL,GAEH,MADAnC,IAAGoC,IAAI,wCAAyC,SACzC,OAIfpC,GAAG2N,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMxJ,OAAS,GAC5BuJ,EAAaC,MAAM,GAAGC,kBAG9B9N,GAAG+N,wBAA0B,WACzB,OAAQ/N,GAAGgO,gBACPhO,GAAGiN,yBACuB3M,SAAzB4L,KAAK1K,UAAU1B,OAAsDQ,SAA/B4L,KAAK1K,UAAUyM,aAAyD3N,SAA5B4L,KAAK1K,UAAU0M,WAG1GlO,GAAGmO,UAAY,SAASC,EAAYC,EAAOC,GACvC,GAAIC,GAASH,EAAWtO,OAASsO,EAAWF,UAAYE,EAAWH,WAEnE,OAAOM,GAAO9M,KAAK2M,EAAYC,EAAOC,IAG1CtO,GAAGwO,iBAAmB,SAAS5D,GAC3B,GAAI6D,GAAa,GACbC,EAAQ,GAAIzE,YAAWW,EAY3B,OAVA5K,IAAGY,KAAK8N,EAAO,SAAS9M,EAAK+M,GACzB,GAAIC,GAAeD,EAAIlE,SAAS,GAE5BmE,GAAavK,OAAS,IACtBuK,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXzO,GAAG6O,cAAgB,SAASC,EAAMC,EAAa1K,GAC3C,GAAI2K,GAAchP,GAAGmO,UAAUW,EAAMC,EAAaA,EAAc1K,GAC5D4K,EAAa,GAAIC,YACjBC,EAAU,GAAInP,IAAGoP,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQtP,GAAGwO,iBAAiBS,EAAW5H,UAGnD4H,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGXnP,GAAGwG,OAAS,SAASW,EAAOuI,EAAQC,GAahC,MAZA3P,IAAGY,KAAK8O,EAAQ,SAAS5O,EAAMV,GACvBuP,GAAgB3P,GAAGsK,SAASlK,IACRE,SAAhB6G,EAAMrG,KACNqG,EAAMrG,OAEVd,GAAGwG,OAAOW,EAAMrG,GAAOV,GAAK,IAG5B+G,EAAMrG,GAAQV,IAIf+G,GAaXnH,GAAG4P,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACAzN,EAASwN,EAASC,EAUtB,OARA/P,IAAGY,KAAK0B,EAAQ,SAAS0N,EAAaC,GACN3P,SAAxBuP,EAAOG,KACPD,EAAOC,GAAeH,EAAOG,IAGjCH,EAAOG,GAAeC,IAGnBJ,GAMX7P,GAAG6J,QAAU,SAASqG,EAAKC,EAAKC,GAC5B,GAAIF,EAAIrG,QACJ,MAAOqG,GAAIrG,QAAQsG,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAI7L,MAMd,KAJI+L,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIXpQ,GAAGuQ,YAAc,WACb,MAAO,uCAAuCtJ,QAAQ,QAAS,SAASuJ,GAEpE,GAAIC,GAAoB,GAAhBnK,KAAKoK,SAAgB,EAAGC,EAAS,KAALH,EAAWC,EAAS,EAAJA,EAAU,CAC9D,OAAOE,GAAElG,SAAS,OAM1BzK,GAAG4Q,GAAK,WACJ,MAAOC,WAAUC,UAAUjH,QAAQ,WAAY,GAC3CgH,UAAUC,UAAUjH,QAAQ,cAAe,GAGnD7J,GAAG+Q,IAAM,WACL,MAAOF,WAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGgR,IAAM,WACL,MAAOH,WAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGiR,KAAO,WACN,MAAOJ,WAAUC,UAAUjH,QAAQ,cAAe,GAGtD7J,GAAGkR,KAAO,WACN,MAAOlR,IAAG4Q,MAAQC,UAAUC,UAAUjH,QAAQ,YAAa,GAG/D7J,GAAGmR,KAAO,WACN,MAAON,WAAUC,UAAUjH,QAAQ,SAAW,GAGlD7J,GAAGoR,OAAS,WACR,MAA4B9Q,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,YAAa,GAGnF7J,GAAGsR,OAAS,WACR,MAA4BhR,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,aAAc,GAGpF7J,GAAGuR,MAAQ,WACP,MAA4BjR,UAArBuQ,UAAUQ,QAAwBR,UAAUQ,OAAOxH,QAAQ,YAAa,GAGnF7J,GAAGwR,QAAU,WACT,OAASxR,GAAGmR,SAAWnR,GAAGkR,QAAUL,UAAUC,UAAUjH,QAAQ,cAAe,GAA2BvJ,SAArBuQ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrIrR,GAAGyR,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrB1R,GAAG2R,QAAU,WACT,MAAOd,WAAUC,UAAU/Q,cAAc8J,QAAQ,cAAe,GAKpE7J,GAAGgO,aAAe,WACd,MAAOhO,IAAG2R,WAAad,UAAUC,UAAU/Q,cAAc8J,QAAQ,UAAY,GAGjF7J,GAAG4R,KAAO,WACN,MAAO5R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAGjE7J,GAAG8R,KAAO,WACN,MAAO9R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAGjE7J,GAAG+R,KAAO,WACN,MAAO/R,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,aAAc,GAIjE7J,GAAGgS,OAAS,WACR,MAAOhS,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,eAAgB,GAGnE7J,GAAG6R,IAAM,WAEL,MAAOhB,WAAUC,UAAUjH,QAAQ,WAAY,GACxCgH,UAAUC,UAAUjH,QAAQ,WAAY,GACxCgH,UAAUC,UAAUjH,QAAQ,aAAc,GAGrD7J,GAAGiS,UAAY,WACX,MAAOjS,IAAG6R,OAAShB,UAAUC,UAAUjH,QAAQ,YAAa,GAGhE7J,GAAGkS,UAAY,WACX,MAAOlS,IAAG6R,QAAU7R,GAAGiS,aAAepB,UAAUC,UAAUjH,QAAQ,aAAc,GAGpF7J,GAAGmS,iBAAmB,WAClB,MAAOnS,IAAG6R,QAAU7R,GAAGiS,cAAgBjS,GAAGkS,aAM9ClS,GAAGoS,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxBtS,GAAGuS,UAAa,WACZ,GAAIC,GAAMrF,SAASC,cAAc,MACjC,OAAO,UAASqF,GACZD,EAAIE,UAAYD,CAChB,IAAI/P,GAAU8P,EAAI5K,UAElB,OADA4K,GAAIxM,YAAYtD,GACTA,MAKf1C,GAAGY,KAAO,SAAS+R,EAAcC,GAC7B,GAAIC,GAAYtP,CAEhB,IAAIoP,EAEA,GAAIvJ,OAAO0J,SAAWH,EAAa9H,cAAgBzB,OAAO0J,QACtD,IAAKD,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASD,EAAaxS,IAAI0S,GAAaF,EAAaI,QAAQJ,EAAaxS,IAAI0S,KAClFtP,KAAW,GAFoCsP,SAStD,IAAI7S,GAAG8C,QAAQ6P,IAAiB3S,GAAG8K,WAAW6H,IAAiB3S,GAAGgL,WAAW2H,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASC,EAAYF,EAAaE,IACvCtP,KAAW,GAFoCsP,SAOtD,IAAI7S,GAAGoL,SAASuH,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAatO,SAC3Cd,EAASqP,EAASC,EAAYF,EAAa/S,OAAOiT,IAC9CtP,KAAW,GAFoCsP,SAQvD,KAAKA,IAAcF,GACf,GAAInI,OAAOhJ,UAAU8O,eAAe7O,KAAKkR,EAAcE,KACnDtP,EAASqP,EAASC,EAAYF,EAAaE,IACvCtP,KAAW,GACX,OASxBvD,GAAGgT,KAAO,SAASC,EAASC,GACxB,GAAIlT,GAAG0K,WAAWuI,GAAU,CACxB,GAAIpO,GAAQtD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAElD,OAAO,YACH,GAAIyR,GAAUnT,GAAGwG,UAAW3B,EAI5B,OAHInD,WAAU2C,SACV8O,EAAUA,EAAQC,OAAO7R,MAAMC,UAAU1B,MAAM2B,KAAKC,aAEjDuR,EAAQjR,MAAMkR,EAASC,IAItC,KAAM,IAAIhN,OAAM,wCAmBpBnG,GAAGqT,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQ1M,KAAK0M,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAW3R,KACa,gBAAZ8R,GACF5T,GAAGqT,QAAQO,EAASE,GAAU,GACe,sBAA5CtJ,OAAOhJ,UAAUiJ,SAAShJ,KAAKmS,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAK7M,KAAK0M,GAAU,MAAM1M,KAAK0M,GAAS,GAAK,IAAM,IAC7DE,EAAW3R,KAAKyR,GAChBE,EAAW3R,KAAK9B,GAAGqT,QAAQC,KACqB,mBAAxC9I,OAAOhJ,UAAUiJ,SAAShJ,KAAK6R,IAA8C,mBAARA,GAC7EtT,GAAGY,KAAK0S,EAAK,SAAS1R,EAAKxB,GACvBuT,EAAIvT,EAAKwB,KAEU,mBAAR0R,IAAiC,OAARA,GAAiC,gBAARA,GACjEtT,GAAGY,KAAK0S,EAAK,SAASxS,EAAMV,GACxBuT,EAAIvT,EAAKU,KAGb2S,EAAW3R,KAAKiS,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBzM,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7BjH,GAAGiU,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAI5G,WAGnBtN,GAAGY,KAAK0S,EAAK,SAASnT,EAAKC,GACvBD,EAAMgU,EAAeA,EAAe,IAAMhU,EAAM,IAAMA,EAElDH,GAAGsK,SAASlK,GACZJ,GAAGiU,aAAa7T,EAAK8T,EAAU/T,GAE1BH,GAAG0K,WAAWtK,GACnB8T,EAASzK,OAAOtJ,EAAKC,KAGrB8T,EAASzK,OAAOtJ,EAAKC,KAItB8T,GAGXlU,GAAGoU,WAAa,SAASd,EAAKe,GAC1B,GAAInH,EAeJ,OAbKmH,KACDA,EAAOlH,SAASC,cAAc,SAGlCpN,GAAGiU,aAAaX,GACZ7J,OAAQ,SAAStJ,EAAKC,GAClB8M,EAAQC,SAASC,cAAc,SAC/BF,EAAMoH,aAAa,OAAQnU,GAC3B+M,EAAMoH,aAAa,QAASlU,GAC5BiU,EAAKE,YAAYrH,MAIlBmH,GAOXrU,GAAGwU,UAAY,SAASC,MAEpB,MAAIrL,QAAOsL,MAAQ1U,GAAG0K,WAAWgK,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjCzU,GAAG6U,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAASzQ,OAAS0Q,IAIzD/U,GAAGkV,YAAc,SAASC,GAGtB,MAAInV,IAAGwM,QAAQ2I,GAEJA,EAAgBxK,MAAM1D,QAAQ,YAAa,IAE7CjH,GAAGgM,OAAOmJ,IACkB,OAA7BA,EAAgBC,UAAkD9U,SAA7B6U,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgBnU,MAM3BhB,GAAGqV,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIXrQ,OAAQ,WACJ,GAAIN,GAAOnD,SAEXO,MAAKyT,YAAY1V,GAAG6E,EAAK,IAAIM,OAAOnD,MAAMC,KAAMV,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,MAI1FgU,YAAa,SAASC,GAClBL,EAAUxT,KAAK6T,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAO5V,MAGY,mBAAX8V,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAU/V,GAGjBnB,OAAOmB,GAAKA,MCRnB,WACG,YAEAA,IAAGmG,MAAQ,SAAS9D,GAChBJ,KAAKI,QAAU,kBAAoBrC,GAAGgW,QAAU,KAAO3T,GAG3DrC,GAAGmG,MAAM3E,UAAY,GAAI2E,UCV7BnG,GAAGgW,QAAU,SCAbhW,GAAGiW,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAYhJ,SAASC,cAAc,SACnC+I,EAAU/S,KAAO,OACjBpD,GAAGmW,GAAWnR,OAEVmR,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQvW,GAAGsR,UAAYtR,GAAGuR,UAC+CjR,SAArEuQ,UAAUC,UAAUzN,MAAM,uCAIlC,QAASmT,KACL,OAAQxW,GAAGsR,UAAYtR,GAAGuR,UAC+CjR,SAArEuQ,UAAUC,UAAUzN,MAAM,uCAIlC,QAASoT,KACL,GAAIrN,OAAOqE,eAAgB,CACvB,GAAIiJ,GAAM1W,GAAGuN,mBAGb,OAA+BjN,UAAxBoW,EAAIC,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiCtW,UAA1B8I,OAAOyN,eAKlB,QAASC,KACL,QAAIL,KAIGG,IAGX,QAASG,KAEL,MAA2DzW,UAApD6M,SAASC,cAAc,SAAS4J,gBAG3C,QAASC,KACL,IACI,QAAS7N,OAAO8N,cAEZlX,GAAG0K,WAAWtB,OAAO8N,aAAaC,SAE1C,MAAOhV,GAEH,OAAO,GAIf,QAASiV,KACL,GAAIC,GAAOlK,SAASC,cAAc,OAElC,QAAQ,aAAeiK,IAAS,eAAiBA,IAAQ,UAAYA,MAChErX,GAAG2R,YAAc3R,GAAG6R,MAhG7B,GAAIyF,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAnCAd,GAAoBpB,IAEpBuB,EAA4BH,GAAqBtX,GAAGiN,uBAEpDsK,EAAyBE,IAA8BzX,GAAGgO,eAE1DwJ,EAAmBC,GAA6BL,IAEhDM,EAAqBF,GAAoBjB,IAEzCoB,EAAmBF,GAA6BzX,GAAG+N,0BAEnD6J,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BjB,IAEtDsB,EAAqBR,IAA6ChX,SAAvB8I,OAAOiP,aAA6BZ,GAE/EO,EAA4BvB,IAE5BsB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmDnX,SAAtB8I,OAAO8F,WAE5DkJ,EAA0B,WACtB,QAAIX,KACQzX,GAAGgO,iBAAmBhO,GAAGiS,iBAMrCqG,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiBzP,OAAO0P,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAczZ,GAAGoR,SACjBsI,0BAA2B1Z,GAAG6R,MAC9B8H,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxB7X,GAAGga,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQla,GAAG0K,WAAWuP,EAAaC,QAG9Ela,GAAGoP,QAAU,WACT,YAEA,IAAI+K,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZxa,IAAGwG,OAAOvE,MACNiY,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiBvY,KAAK2Y,GAEtBC,GACAJ,EAAiBxY,KAAK4Y,IAGrBF,KAAU,EACfE,GAAaA,EAAU1Y,MAAM,KAAMoY,GAE9BK,GACLA,EAAUzY,MAAM,KAAMmY,GAGnBlY,MAGX0Y,KAAM,SAAS/H,GAQX,MAPc,KAAV4H,EACAD,EAAczY,KAAK8Q,GAGnBA,EAAS5Q,MAAM,KAAsB1B,SAAhB8Z,EAA4BD,EAAcC,GAG5DnY,MAGXqN,QAAS,WAgBL,MAfAkL,GAAQ,EACRL,EAAczY,UAEV2Y,EAAiBhW,QACjBrE,GAAGY,KAAKyZ,EAAkB,SAASzY,EAAKgR,GACpCA,EAAS5Q,MAAM,KAAMmY,KAIzBI,EAAclW,QACdrE,GAAGY,KAAK2Z,EAAe,SAAS3Y,EAAKgR,GACjCA,EAAS5Q,MAAM,KAAMmY,KAItBlY,MAGXuN,QAAS,WAgBL,MAfAgL,IAAQ,EACRJ,EAAc1Y,UAEV4Y,EAAiBjW,QACjBrE,GAAGY,KAAK0Z,EAAkB,SAAS1Y,EAAKgR,GACpCA,EAAS5Q,MAAM,KAAMoY,KAIzBG,EAAclW,QACdrE,GAAGY,KAAK2Z,EAAe,SAAS3Y,EAAKgR,GACjCA,EAAS5Q,MAAM,KAAMoY,KAItBnY,SC3EnBjC,GAAG4a,UAAY,SAASC,EAAeC,GACnC,YAEA9a,IAAGwG,OAAOvE,MACN4Y,cAAeA,EAEfE,OAAQ,WACJ,MAAOD,GAASD,OCF5B7a,GAAGgb,aAAe,SAASC,GACvB,YA0CA,SAASC,KACL,GAAIhO,GAAQC,SAASC,cAAc,QAmEnC,OAjEAF,GAAMoH,aAAatU,GAAGgb,aAAaG,oBAAqBC,GACxDlO,EAAMoH,aAAa,QAAStV,EAAQqc,OAEpCrX,EAAKsX,YAAYtc,EAAQqO,SAAUH,GAE/BlO,EAAQuc,SAAWvb,GAAGiW,kBAAkBgD,iBAExC/L,EAAMoH,aAAa,kBAAmB,IAGtCtV,EAAQwc,aACRtO,EAAMoH,aAAa,SAAUtV,EAAQwc,aAGzCtO,EAAMoH,aAAa,OAAQ,QAC3BpH,EAAMoH,aAAa,OAAQtV,EAAQgC,MAEnChB,GAAGkN,GAAOjH,KACNwV,SAAU,WAIVC,MAAO,EACPC,IAAK,EACLC,WAAY,QASZC,SAAU7b,GAAG4Q,OAAS5Q,GAAGgR,MAAQ,SAAW,QAC5C8K,OAAQ,EACRC,QAAS,EACTC,OAAQ,UACR5V,QAAS,KAKZpG,GAAG+Q,OAAS/Q,GAAGkN,GAAOjH,KAAKgW,OAAQ,SAEpCjd,EAAQ0D,QAAQ6R,YAAYrH,GAE5BgP,EAAe/W,OAAO+H,EAAO,SAAU,WACnClO,EAAQmd,SAASjP,KAIrBgP,EAAe/W,OAAO+H,EAAO,YAAa,WACtClN,GAAGhB,EAAQ0D,SAASqE,SAAS/H,EAAQod,cAEzCF,EAAe/W,OAAO+H,EAAO,WAAY,WACrClN,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQod,cAG5CF,EAAe/W,OAAO+H,EAAO,QAAS,WAClClN,GAAGhB,EAAQ0D,SAASqE,SAAS/H,EAAQqd,cAEzCH,EAAe/W,OAAO+H,EAAO,OAAQ,WACjClN,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQqd,cAGrCnP,EA5GX,GAgCIA,GAAOkO,EAhCPpX,EAAO/B,KAEPia,EAAiB,GAAIlc,IAAGqV,eAExBrW,GAEIwc,YAAa,KAGb9Y,QAAS,KAET2Z,WAAY,yBAGZd,SAAS,EAGTa,WAAY,yBAEZE,4BAA4B,EAG5BjP,UAAU,EAGVrM,KAAM,SAGNmb,SAAU,SAASjP,KAEnBmO,MAAO,KAKfrb,IAAGwG,OAAOxH,EAASic,GAEnBG,EAAWpb,GAAGuQ,cA2EdvQ,GAAGhB,EAAQ0D,SAASuD,KAChBwV,SAAU,WACVc,SAAU,SAEVC,UAAW,QAIfxc,GAAGwG,OAAOvE,MACNwa,SAAU,WACN,MAAOvP,IAGXwP,YAAa,WACT,MAAOtB,IAGXE,YAAa,SAASqB,EAAYC,GAC9B,GAAI1P,GAAQ0P,GAAY3a,KAAKwa,UAKzBzd,GAAQsd,4BAA8Btc,GAAG+R,SAAW/R,GAAGiS,aAAejS,GAAGmS,oBACzEjF,EAAMoH,aAAa,WAAY,IAI3BqI,EACAzP,EAAMoH,aAAa,WAAY,IAG/BpH,EAAM2P,gBAAgB,aAKlCC,eAAgB,SAAStB,GACjBA,IAAgBxc,EAAQwc,aACxBtO,EAAMoH,aAAa,SAAUkH,IAIrCuB,MAAO,WACC7P,EAAMpH,YACN9F,GAAGkN,GAAOnH,SAGd/F,GAAGhB,EAAQ0D,SAASsE,YAAYhI,EAAQqd,YACxCnP,EAAQ,KACRA,EAAQgO,OAIhBhO,EAAQgO,KAGZlb,GAAGgb,aAAaG,oBAAsB,eCxLtCnb,GAAGgd,WAAa,SAASC,GACrB,YAQA,SAASC,GAAaC,GAClB,GAAInd,GAAG8C,QAAQqa,GAAU,CACrB,GAAIC,KAMJ,OAJApd,IAAGY,KAAKuc,EAAS,SAASvb,EAAKyb,GAC3BD,EAAQtb,KAAKzB,EAAKgd,MAGfD,EAGX,MAAO/c,GAAK8c,GAGhB,QAASG,GAAeC,GACpB,GAAIvd,GAAG8C,QAAQya,GAAQ,CACnB,GAAIH,KAMJ,OAJApd,IAAGY,KAAK2c,EAAO,SAAS3b,EAAK4b,GACzBJ,EAAQtb,KAAKzB,EAAKod,EAAOD,OAGtBJ,EAGX,MAAO/c,GAAKod,EAAOF,IAGvB,QAASG,GAAgBC,GACrB,GAAIC,MACAC,KAAczK,OAAOuK,EAYzB,OAVA3d,IAAGY,KAAKid,EAAU,SAAS1Z,EAAO2Z,GAC9B,GAAIC,GAAsBC,EAASF,EAEPxd,UAAxByd,GACA/d,GAAGY,KAAKmd,EAAqB,SAASlK,EAAGoK,GACrCL,EAAc9b,KAAKzB,EAAK4d,QAK7BL,EAhDX,GAAIvd,MACAod,KACAO,KACAE,KACAC,IA+CJne,IAAGwG,OAAOvE,MAeNmc,QAAS,SAASC,GACd,GAAIV,GAASU,EAAKV,QAAU3d,GAAG2d,OAAOW,WAClCjB,EAAKhd,EAAKyB,MACNd,KAAMqd,EAAKrd,KACXud,aAAcF,EAAKrd,KACnBwc,KAAMa,EAAKb,KACXgB,KAAmB,MAAbH,EAAKG,MAAe,EAAKH,EAAKG,KACpCb,OAAQA,IACP,CA8BT,OA5BIU,GAAKI,UACLpe,EAAKgd,GAAIoB,QAAUJ,EAAKI,QAEQne,SAA5B6d,EAAUE,EAAKI,WACfN,EAAUE,EAAKI,aAEnBN,EAAUE,EAAKI,SAAS3c,KAAKub,IAG7BgB,EAAKK,eACLre,EAAKgd,GAAIqB,aAAeL,EAAKK,aAEape,SAAtC4d,EAAeG,EAAKK,gBACpBR,EAAeG,EAAKK,kBAExBR,EAAeG,EAAKK,cAAc5c,KAAKub,IAG3Chd,EAAKgd,GAAIA,GAAKA,EACdI,EAAOY,EAAKb,MAAQH,EAEK/c,SAArB0d,EAASL,KACTK,EAASL,OAEbK,EAASL,GAAQ7b,KAAKub,GAEtBJ,EAAc0B,eAAetB,EAAI,KAAMM,GAEhCN,GAGXuB,SAAU,SAASC,GACf,MAAI7e,IAAGsK,SAASuU,IAAmBxe,EAAKgE,OACV/D,SAAtBue,EAAexB,GACRH,EAAa2B,EAAexB,IAGN/c,SAAxBue,EAAerB,KACbF,EAAeuB,EAAerB,MAGhCqB,EAAelB,OACbD,EAAgBmB,EAAelB,QADrC,OAKE3d,GAAGwG,UAAWnG,GAAM,IAInC0c,MAAO,WACH1c,KACAod,KACAO,KACAG,MAGJW,UAAW,SAASzB,EAAI0B,GACpB,GAAIC,GAAY3e,EAAKgd,GAAIM,OACrBsB,EAAyBjf,GAAG6J,QAAQmU,EAASgB,GAAY3B,EAE7DW,GAASgB,GAAWE,OAAOD,EAAwB,GAEnD5e,EAAKgd,GAAIM,OAASoB,EAEUze,SAAxB0d,EAASe,KACTf,EAASe,OAEbf,EAASe,GAAWjd,KAAKub,GAEzBJ,EAAc0B,eAAetB,EAAI2B,EAAWD,IAGhDI,YAAa,SAAS9B,EAAI+B,GACtB,GAAIC,GAAUhf,EAAKgd,GAAIG,IAEvBnd,GAAKgd,GAAIG,KAAO4B,EAChB3B,EAAO2B,GAAW/B,QACXI,GAAO4B,IAGlBC,WAAY,SAASjC,EAAIkC,GACrBlf,EAAKgd,GAAIrc,KAAOue,GAGpBC,WAAY,SAASnC,EAAIoC,GACrBpf,EAAKgd,GAAImB,KAAOiB,GAIpBC,YAAa,SAASC,EAAUC,GAC5Bvf,EAAKsf,GAAUC,SAAWA,GAG9BC,mBAAoB,SAASxC,GACzB,GAAIqB,GAAere,EAAKgd,GAAIqB,YAE5B,OAAIA,GACOR,EAAeQ,OAK9BoB,cAAe,SAASzC,GACpB,GAAIoB,GAAUpe,EAAKgd,GAAIoB,OAEvB,OAAON,GAAUM,OAK7Bze,GAAG2d,QACCW,WAAY,aACZyB,UAAW,YACXC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,UAAW,YACXC,gBAAiB,kBACjBC,kBAAmB,oBACnBC,cAAe,gBACfC,cAAe,gBACfC,SAAU,WACVC,QAAS,WCxMZ,WACG,YAEA1gB,IAAG2gB,eAECC,SAAU,SAASC,EAAiBrhB,EAAQshB,GACxC7e,KAAK8e,SAASF,EAAiBrhB,EAAQshB,IAG3CE,gBAAiB,SAASC,GACtB,GAAIjd,GAAO/B,IAEXjC,IAAGY,KAAKqgB,EAAgB,SAAS9c,EAAO+c,GACpCld,EAAKmd,eAAeD,MAI5BH,SAAU,SAAS1gB,EAAMb,EAAQshB,GAC7B7e,KAAKmf,kCAEL,IAAI3C,GAAqC,IAA3Bxc,KAAKof,WAAWhd,OAAerE,GAAGuQ,cAAgBtO,KAAKqf,gBAEjEC,EAAcvhB,GAAGgT,KAAK,SAASlE,GAC3B7M,KAAKuf,gBACD1S,KAAMA,EACN9N,KAAMiB,KAAKpB,SAAS4gB,MAAMC,aAC3BjD,EAASkD,IACb1f,MAEH2f,EAAkB5hB,GAAGgT,KAAK,SAAS6O,GAC/B5f,KAAKuf,eAAeK,EAAUpD,EAASkD,IACxC1f,MAEH6f,EAAgB9hB,GAAGgT,KAAK,SAASxK,GAC7B,GAAIsG,GAAO9O,GAAGuI,aAAaC,EAE3BvG,MAAKuf,gBACD1S,KAAMA,EACN9N,KAAMiB,KAAKpB,SAAS4gB,MAAMC,YAAc,QACzCjD,EAASkD,IACb1f,MAEH8f,EAAoB/hB,GAAGgT,KAAK,SAASgP,GACjC,GAAIC,GAAoBD,EAAWtZ,SAAWsZ,EAAWtZ,QAAU,IAC/DoG,EAAO9O,GAAGuI,aAAayZ,EAAWxZ,OAAQwZ,EAAW5e,KAAM6e,EAE/DhgB,MAAKuf,gBACD1S,KAAMA,EACN9N,KAAMghB,EAAWhhB,MAClByd,EAASkD,IACb1f,MAEHigB,EAAqBliB,GAAGgT,KAAK,SAASmP,GAClC,GAAIniB,GAAGwM,QAAQ2V,IAAgBniB,GAAGiW,kBAAkBqC,cAAe,CAC/D,GAAI8J,GAAQ7gB,MAAMC,UAAU1B,MAAM2B,KAAK0gB,EAAYC,OAC/Cpe,EAAO/B,IAEXjC,IAAGY,KAAKwhB,EAAO,SAASxgB,EAAKygB,GACzBre,EAAKwd,eAAea,EAAM5D,EAASkD,SAIvC1f,MAAKuf,eAAeW,EAAa1D,EAASkD,IAE/C1f,MAEHqgB,EAAgB,WACRtiB,GAAGmM,WAAW9L,KACdA,EAAOkB,MAAMC,UAAU1B,MAAM2B,KAAKpB,IAEtCA,KAAU+S,OAAO/S,IAGrB2D,EAAO/B,KACP0f,IAEJ1f,MAAKqf,gBAAkB7C,EAEnBpe,IACAiiB,IAEAtiB,GAAGY,KAAKP,EAAM,SAASuB,EAAK2gB,GACpBviB,GAAGsM,cAAciW,GACjBL,EAAmBK,GAEdviB,GAAG+M,OAAOwV,GACfhB,EAAYgB,GAEPviB,GAAGsK,SAASiY,GACbA,EAAczT,MAAQyT,EAAcvhB,KACpC4gB,EAAgBW,GAEXA,EAAc/Z,QAAU+Z,EAAcvhB,MAC3C+gB,EAAkBQ,GAGjBA,EAAczV,SAAmD,WAAxCyV,EAAczV,QAAQ/M,cACpD+hB,EAAcS,GAGdve,EAAK5B,IAAImgB,EAAgB,6CAA8C,UAI/EtgB,KAAKG,IAAI,YAAcuf,EAActd,OAAS,WAC9CpC,KAAKugB,uBAAuBb,EAAeniB,EAAQshB,KAI3D2B,OAAQ,SAASpF,GACbpb,KAAKygB,SAASD,OAAOpF,IAGzBsF,UAAW,WACP,GAAIC,MACA5e,EAAO/B,IAEXjC,IAAGwG,OAAOoc,EAAe3gB,KAAKof,YAC9BrhB,GAAGY,KAAKgiB,EAAe,SAAShhB,EAAKihB,GACjC7e,EAAKye,OAAOI,KAGhB5gB,KAAKygB,SAASC,aAGlBG,iBAAkB,WACd7gB,KAAKof,eAGT0B,eAAgB,SAAS1F,GACrB,GAAI2F,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAEhD,UAAKrd,GAAGiW,kBAAkBoD,QAAUpX,KAAKpB,SAAS4X,SAASyK,WAIvDF,EAAWrF,SAAW3d,GAAG2d,OAAOwC,QAChCle,KAAKG,IAAIpC,GAAG0L,OAAO,yDAA0D2R,EAAIpb,KAAKkhB,QAAQ9F,KAC9Fpb,KAAKmhB,YAAY/F,IACV,IAGPpb,KAAKG,IAAIpC,GAAG0L,OAAO,sDAAuD2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,UAG9F,KAGXgG,WAAY,SAAShG,GACjB,MAAOpb,MAAKqhB,gBAAgBjG,IAIhCkG,UAAW,SAASC,GAChB,MAAOvhB,MAAKygB,SAASe,QAAQD,IAOjCE,cAAe,SAASC,EAAQC,EAAaC,EAASC,EAAYC,GAC9D,GACIC,GAAWhlB,EADXilB,EAAkB,GAAIjkB,IAAGoP,OAqC7B,OAlCInN,MAAKiiB,iBACLF,EAAY/hB,KAAKkiB,eAAeR,GAChC3kB,GACI+kB,qBAAsBA,EACtBF,QAASA,EAAU,EAAIA,EAAU,KACjCO,MAAOP,EAAU,IAKhBC,GAAc9jB,GAAGiW,kBAAkBiD,gBACpC8K,EAAY/hB,KAAKoiB,QAAQV,IAIZ,MAAbK,EACAC,EAAgBzU,SAAS8U,UAAWV,EAAazhB,MAAO,2BAGxDF,KAAKiiB,gBAAgBK,SAASP,EAAWJ,EAAa5kB,GAASkb,KAC3D,SAAiBsK,GACbP,EAAgB3U,QAAQkV,IAG5B,SAAiBF,EAAWG,GACxBR,EAAgBzU,SAAS8U,UAAWA,EAAWniB,MAAOsiB,GAAU,oCAM5ER,EAAgBzU,SAAS8U,UAAWV,EAAazhB,MAAO,mCAGrD8hB,GAGXS,UAAW,SAASf,GAChB,MAAO1hB,MAAK0iB,WAAW1iB,KAAK2iB,qBAAqBjB,KAGrDkB,YAAa,SAASlB,GAClB,MAAO1hB,MAAK6iB,eAAeC,IAAIpB,IAGnCU,QAAS,SAASb,GACd,MAAOvhB,MAAKygB,SAAS2B,QAAQb,IAAiB,MAGlDwB,cAAe,WACX,MAAO/iB,MAAKghB,YAAYrE,UACpBjB,QACI3d,GAAG2d,OAAOyC,UACVpgB,GAAG2d,OAAO0C,gBACVrgB,GAAG2d,OAAOsC,UAEf5b,QAGP8e,QAAS,SAAS9F,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKrc,MAI/CikB,YAAa,SAAS5H,GAClB,GAAI6H,GAAkBjjB,KAAKkjB,YAAY9H,GAAIA,IACvCuC,EAAW,IAQf,OANIsF,IACiC5kB,SAA7B4kB,EAAgBtF,WAChBA,EAAWsF,EAAgBtF,UAI5BA,GAGXwF,sBAAuB,WACnB,MAAOnjB,MAAKygB,SAAS0C,yBAGzBC,QAAS,SAAShI,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKmB,MAG/C8G,cAAe,WACX,MAAOrjB,MAAKsjB,cAGhBC,yBAA0B,WACtB,GAAIC,GAAexjB,KAAKyjB,iBAExB,OAAID,GAAe,EACRA,EAAexjB,KAAK0jB,qBAGxB,MAGXR,WAAY,SAAStG,GACjB,MAAO5c,MAAKghB,YAAYrE,SAASC,IAGrC+G,QAAS,SAASvI,GACd,MAAOpb,MAAKghB,YAAYrE,UAAUvB,GAAIA,IAAKG,MAG/Cpb,IAAK,SAASuJ,EAAKvB,IACXnI,KAAKpB,SAASglB,OAAWzb,GAAmB,SAAVA,EAG7BA,GAAmB,SAAVA,GACdpK,GAAGoC,IAAI,kBAAoBpC,GAAGgW,QAAU,KAAOrK,EAAKvB,GAHpDpK,GAAGoC,IAAI,kBAAoBpC,GAAGgW,QAAU,KAAOrK,IAQvDma,YAAa,SAASzI,GAClB,GAAI2F,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAEhD,KAAKrd,GAAGiW,kBAAkBoD,QAAUpX,KAAKpB,SAAS4X,SAASyK,QACvD,OAAO,CAIX,IAAIljB,GAAG6J,SAAS7J,GAAG2d,OAAOyC,UAAWpgB,GAAG2d,OAAO0C,iBAAkB2C,EAAWrF,SAAW,EAAG,CACtF,GAAI1b,KAAKygB,SAASrJ,MAAMgE,GAEpB,MADApb,MAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOwC,SAClC,CAGPle,MAAKG,IAAIpC,GAAG0L,OAAO,mCAAoC2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,aAIlFpb,MAAKG,IAAIpC,GAAG0L,OAAO,wDAAyD2R,EAAIpb,KAAKkhB,QAAQ9F,IAAM,QAGvG,QAAO,GAGXN,MAAO,WACH9a,KAAKG,IAAI,yBAETH,KAAKygB,SAAS3F,QACd9a,KAAKof,cACLpf,KAAK8jB,gBACL9jB,KAAK+jB,kBACL/jB,KAAKgkB,mBACLhkB,KAAKkiB,kBAELnkB,GAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjCA,EAAOpJ,UAGX9a,KAAKmkB,aAAarJ,QAClB9a,KAAK6iB,eAAe/H,QACpB9a,KAAK0jB,qBAAuB,EAC5B1jB,KAAKsjB,aAAe,EACpBtjB,KAAKghB,YAAYlG,QACjB9a,KAAK2iB,wBAEL3iB,KAAKokB,eAAiBpkB,KAAKokB,cAActJ,QACzC9a,KAAKpB,SAASylB,QAAQC,gBAAkBtkB,KAAKukB,sBAE7CvkB,KAAKwkB,kCACLxkB,KAAKykB,+BAELzkB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAe5J,SAG/C6J,MAAO,SAASvJ,GACZ,MAAOpb,MAAK4kB,aAAaxJ,IAG7ByJ,WAAY,SAASzJ,EAAI0J,GACrB,GAAI/iB,GAAO/B,IAEX,OAAOjC,IAAGgnB,OAAOxlB,UAAUslB,WAAWzJ,EAAI0J,GACtC3kB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBqgB,QAASrkB,GAAGgT,KAAKhP,EAAKqgB,QAASrgB,GAC/Bgf,WAAYhf,EAAKif,eAIzBgE,iBAAkB,SAASC,EAAS7J,GAChCpb,KAAKklB,oBAAoBC,IAAIF,EAAS7J,IAG1CgK,2BAA4B,SAASH,EAAS7J,GAC1Cpb,KAAKqlB,8BAA8BF,IAAIF,EAAS7J,IAGpDkK,sBAAuB,SAASzG,EAAUzD,GACtCpb,KAAKulB,yBAAyBJ,IAAItG,EAAUzD,IAGhDoK,oBAAqB,SAASjoB,EAAQ6d,GAClCpb,KAAKylB,uBAAuBN,IAAI5nB,EAAQ6d,IAI5CsK,YAAa,SAAS7G,EAAUzD,GAC5Bpb,KAAK6iB,eAAesC,IAAItG,EAAUzD,IAGtCuK,QAAS,SAASC,GACd5lB,KAAK6lB,4BAA4BD,IAGrCE,aAAc,SAASC,GACnB/lB,KAAKyjB,kBAAoBsC,GAG7BC,QAAS,SAAS5K,EAAIkC,GAClBtd,KAAKghB,YAAY3D,WAAWjC,EAAIkC,IAGpC2I,UAAW,SAAS1oB,EAAQ6d,GACxBpb,KAAKmkB,aAAagB,IAAI5nB,EAAQ6d,IAGlC8K,QAAS,SAAS9K,EAAI+B,GAClB,MAAOnd,MAAKghB,YAAY9D,YAAY9B,EAAI+B,IAG5CgJ,kBAAmB,WACgB,IAA3BnmB,KAAKof,WAAWhd,OAChBpC,KAAKomB,WAAW,gBAGhBpmB,KAAKqmB,uBAQjBtoB,GAAGuoB,gBAECpH,eAAgB,SAASqH,GACrB,GAAInL,GAAKpb,KAAKghB,YAAY7E,SACtBZ,KAAMgL,EAAYhL,KAClBxc,KAAMwnB,EAAYxnB,KAClBwd,KAAMgK,EAAYhK,KAClBb,OAAQ3d,GAAG2d,OAAO2C,mBAatB,OAVAkI,GAAYC,oBAAsBxmB,KAAKslB,sBAAsBiB,EAAYC,mBAAoBpL,GAC7FmL,EAAYE,kBAAoBzmB,KAAKwlB,oBAAoBe,EAAYE,iBAAkBrL,GAEnFmL,EAAYG,eACZ1mB,KAAKkiB,eAAe9G,GAAMmL,EAAYG,cAG1C1mB,KAAKsjB,eACLtjB,KAAK0jB,uBAEEtI,GAGXuL,sBAAuB,SAASvG,EAAMwG,GAC9B7oB,GAAGgM,OAAOqW,KACVA,EAAKyG,WAAa7mB,KAAK8mB,aAAaF,KAI5CG,YAAa,SAAS3mB,GAClBJ,KAAKpB,SAASF,UAAUsoB,QAAQ,KAAM,KAAM5mB,EAAS/B,SAGzD4oB,qBAAsB,WAClB,GAAIllB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGmpB,yBACVC,OAAQnnB,KAAKpB,SAASwiB,WAAW+F,OAAOvpB,cACxCwpB,eAAgBpnB,KAAKpB,SAASwoB,eAC9BC,cAAernB,KAAKpB,SAAS0oB,QAAQC,SACrCC,cAAexnB,KAAKqlB,8BACpBoC,YAAaznB,KAAKylB,uBAClBiC,cAAe1nB,KAAKulB,yBACpBoC,KAAM3nB,KAAKpB,SAAS+oB,KACpBxnB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvB6lB,SAAU,SAASxM,GACfrZ,EAAK8lB,UAAUzM,GACfrZ,EAAKnD,SAASF,UAAUkpB,SAASxM,IAErC0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,GACrCjmB,EAAKkmB,kBAAkB7M,EAAI2M,EAAUC,GACrCjmB,EAAKnD,SAASF,UAAUopB,iBAAiB1M,EAAI2M,EAAUC,OAMnEE,oBAAqB,WACjB,GAAInmB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGoqB,cACVC,cAAepoB,KAAKpB,SAASypB,MAAMD,cACnC1pB,WACIyB,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBumB,cAAe,SAASzb,GACpB9K,EAAKwmB,wBACDxpB,KAAM,kBACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAU8pB,gBAAiBzmB,EAAM8K,GACjE2L,UAAWza,GAAGgT,KAAKhP,EAAK0mB,oBAAqB1mB,EAAM8K,GACnD6b,WAAY,sBAOhCC,aAAc,SAASC,EAAcC,GACjC,GAAIC,MACAC,EAAWH,EACXI,KACAC,EAAiBJ,EACjBK,EAAO,SAASC,GACZ,MAAIprB,IAAGsK,SAAS8gB,GACLprB,GAAGwG,UAAW4kB,GAElBA,GAEXC,EAAoB,WAChB,MAAIrrB,IAAG0K,WAAWwgB,GACPA,IAEJA,GAEXI,EAAwB,SAASjO,EAAIkO,GAC7BL,GAAkBlrB,GAAGsK,SAASihB,IAC9BvrB,GAAGwG,OAAO+kB,EAAUF,KAGpBJ,EAAoB5N,IACpBrd,GAAGwG,OAAO+kB,EAAUN,EAAoB5N,IAIpD,QACI+J,IAAK,SAAShnB,EAAKid,GAEL,MAANA,GACA0N,KACAC,EAAWG,EAAK/qB,IAGhB2qB,EAAM1N,GAAM8N,EAAK/qB,IAIzB2kB,IAAK,SAAS1H,GACV,GAAImO,EAYJ,OARIA,GADM,MAANnO,GAAc0N,EAAM1N,GACX0N,EAAM1N,GAGN8N,EAAKH,GAGlBM,EAAsBjO,EAAImO,GAEnBL,EAAKK,IAGhBC,YAAa,SAASpO,EAAImO,GAElBxrB,GAAGsK,SAASygB,KAED,OAAP1N,EACIrd,GAAG0K,WAAW8gB,GACdN,EAAiBM,GAGjBN,EAAiBA,MACjBlrB,GAAGwG,OAAO0kB,EAAgBM,KAI9BP,EAAoB5N,GAAM4N,EAAoB5N,OAC9Crd,GAAGwG,OAAOykB,EAAoB5N,GAAKmO,MAK/CzlB,OAAQ,SAAS4d,GACb,aAAcoH,GAAMpH,IAGxB5G,MAAO,WACHgO,KACAE,KACAD,EAAWH,KAKvBa,yBAA0B,WACtB,GAAI1nB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGgd,YACVmG,QAAS,SAAS9F,GACd,MAAOrZ,GAAKmf,QAAQ9F,IAExBuI,QAAS,SAASvI,GACd,MAAOrZ,GAAK4hB,QAAQvI,IAExBgI,QAAS,SAAShI,GACd,MAAOrZ,GAAKqhB,QAAQhI,IAExBsB,eAAgB,SAAStB,EAAI2B,EAAWD,GACpC/a,EAAK2nB,sBAAsBtO,EAAI2B,EAAWD,GAC1C/a,EAAKnD,SAASF,UAAUge,eAAetB,EAAI2B,EAAWD,GACtD/a,EAAK4nB,kBAAkBvO,EAAI0B,GAEvB/a,EAAK2iB,gBACLkF,WAAW,WACP7nB,EAAK2iB,eAAehI,eAAetB,EAAI2B,EAAWD,IACnD,OAcnB+M,oBAAqB,SAASzN,GAM1B,QAAS0N,KACL,QAAI/rB,GAAGiW,kBAAkBqC,kBAEjBtU,EAAKnD,SAASmrB,YAAYC,gBAC1BjsB,GAAG6R,QACF7R,GAAG4R,QACJ5N,EAAKkoB,oBAAoBC,EAAmB,WAK1B7rB,SAAlB+d,EAAKhR,SACErJ,EAAKnD,SAASwM,SAGlBgR,EAAKhR,WApBpB,GAGI8Y,GAHAniB,EAAO/B,KACPuZ,EAAc6C,EAAK+N,QAAUnqB,KAAKpB,SAASwrB,WAAW7Q,YACtD2Q,EAAoB9N,EAAK8N,mBAAqBlqB,KAAKpB,SAASwrB,WAAWF,iBA6C3E,OArBAhG,GAAS,GAAInmB,IAAGgb,cACZQ,YAAaA,EACb9Y,QAAS2b,EAAK3b,QACd2Z,WAAYpa,KAAKpB,SAASyrB,QAAQC,YAClChR,QAAS8C,EAAK9C,QACda,WAAYna,KAAKpB,SAASyrB,QAAQE,YAClClQ,2BAA4Bra,KAAKpB,SAASmrB,YAAYS,iBACtDpf,SAAU0e,IACV/qB,KAAMiB,KAAKpB,SAAS0oB,QAAQmD,UAC5BvQ,SAAU,SAASjP,GACflJ,EAAK2oB,eAAezf,IAExBmO,MAAqB,MAAdgD,EAAKhD,MAAgBpZ,KAAKpB,SAASkH,KAAK6kB,eAAiBvO,EAAKhD,QAGzEpZ,KAAK4qB,gBAAgBnX,YAAY,WAC7ByQ,EAAO5Q,YAGXvR,EAAKkiB,SAASpkB,KAAKqkB,GAEZA,GAGX2G,qBAAsB,SAASC,EAAmBptB,GAC9C,GAAIqE,GAAO/B,KACP+qB,KACAhuB,GACI6mB,MAAO5jB,KAAKpB,SAASglB,MACrBwD,eAAgBpnB,KAAKpB,SAASwoB,eAC9BO,KAAM3nB,KAAKpB,SAAS+oB,KACpBF,YAAaznB,KAAKmkB,aAClBuD,cAAe1nB,KAAK6iB,eACpBrM,SAAUxW,KAAKpB,SAAS4X,SACxBc,OAAQtX,KAAKpB,SAAS0Y,OACtBkI,MAAOxf,KAAKpB,SAAS4gB,MACrBrf,IAAKpC,GAAGgT,KAAKhP,EAAK5B,IAAK4B,GACvBipB,kBAAmBhrB,KAAKpB,SAAS+lB,MAAMsG,6BACvCC,WAAY,SAAS9P,EAAIrc,EAAMosB,EAAQC,GAC/BD,EAAS,GAAKC,EAAQ,IAItBL,EAAe3P,GACX2P,EAAe3P,GAAI+P,SAAWA,GAAUJ,EAAe3P,GAAIgQ,QAAUA,IACrErpB,EAAKspB,YAAYjQ,EAAIrc,EAAMosB,EAAQC,GACnCrpB,EAAKnD,SAASF,UAAUwsB,WAAW9P,EAAIrc,EAAMosB,EAAQC,KAIzDrpB,EAAKspB,YAAYjQ,EAAIrc,EAAMosB,EAAQC,GACnCrpB,EAAKnD,SAASF,UAAUwsB,WAAW9P,EAAIrc,EAAMosB,EAAQC,IAGzDL,EAAe3P,IAAO+P,OAAQA,EAAQC,MAAOA,KAGjDE,WAAY,SAASlQ,EAAIrc,EAAMqG,EAAQqP,SAC5BsW,GAAe3P,EAEtB,IACI9Z,GADAoa,EAAS3Z,EAAKmhB,YAAY9H,GAAIA,IAAKM,MAOnCA,KAAW3d,GAAG2d,OAAO2C,mBAAqB3C,IAAW3d,GAAG2d,OAAO4C,gBAInEhd,EAASS,EAAKwpB,YAAYnQ,EAAIrc,EAAMqG,EAAQqP,GAIxCnT,YAAmBvD,IAAGoP,QACtB7L,EAAOoX,KAAK,WACR3W,EAAKnD,SAASF,UAAU4sB,WAAWlQ,EAAIrc,EAAMqG,EAAQqP,KAIzD1S,EAAKnD,SAASF,UAAU4sB,WAAWlQ,EAAIrc,EAAMqG,EAAQqP,KAG7D+W,SAAU,SAASpQ,EAAIrc,EAAM0sB,GACzB,GAAIve,GAAU,GAAInP,IAAGoP,OAgBrB,OAdApL,GAAKwmB,wBACDxpB,KAAM,WACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAU8sB,SAAUzpB,EAAMqZ,EAAIrc,GAC9D0Z,UAAWvL,EAAQK,QACnBiL,UAAW,WACPiT,EAAyBxT,KAAK,WAC1BlW,EAAK2pB,UAAUtQ,EAAIrc,KAGvBmO,EAAQG,WAEZqb,WAAYtN,IAGTlO,GAEXye,aAAc5tB,GAAGgT,KAAK/Q,KAAK4rB,cAAe5rB,MAC1C6rB,SAAU,SAASzQ,EAAIrc,GACnBgD,EAAK+pB,UAAU1Q,EAAIrc,GACnBgD,EAAKnD,SAASF,UAAUmtB,SAASzQ,EAAIrc,IAEzCgtB,cAAe,SAAS3Q,EAAIrc,EAAMitB,GAC9BjqB,EAAKkqB,eAAe7Q,EAAI4Q,GACxBjqB,EAAKnD,SAASF,UAAUqtB,cAAc3Q,EAAIrc,EAAMitB,IAEpDE,qBAAsB,SAAS9Q,EAAI4Q,EAAW5mB,EAAQqP,GAClD1S,EAAKnD,SAASF,UAAUwtB,qBAAqBnsB,MAAMgC,EAAMtC,YAE7D0sB,SAAU,SAAS/Q,EAAIrc,EAAMitB,GACzB,MAAOjqB,GAAKnD,SAASF,UAAUytB,SAAS/Q,EAAIrc,EAAMitB,IAEtDI,YAAa,SAAShR,EAAIrc,EAAMstB,EAAc5X,GAC1C,MAAO1S,GAAKuqB,aAAavsB,MAAMgC,EAAMtC,YAEzC8sB,cAAe,SAASnR,EAAI+B,GACxBpb,EAAK5B,IAAI,sCAAwC4B,EAAK4hB,QAAQvI,GAAM,SAAW+B,EAAU,KACzFpb,EAAKmkB,QAAQ9K,EAAI+B,IAErB+D,QAASnjB,GAAGgT,KAAKhP,EAAKmf,QAASnf,GAC/B4hB,QAAS5lB,GAAGgT,KAAKhP,EAAK4hB,QAAS5hB,GAC/BqhB,QAASrlB,GAAGgT,KAAKhP,EAAKqhB,QAASrhB,GAC/ByqB,QAASzuB,GAAGgT,KAAKhP,EAAK0qB,SAAU1qB,GAChC2qB,cAAe,SAASnR,GACpB,MAAOxZ,GAAKmhB,YAAY3H,KAAMA,KAElCoR,SAAU,SAASvR,GACf,GAAIM,GAAS3Z,EAAKmhB,YAAY9H,GAAIA,IAAKM,MACvC,OAAOA,KAAW3d,GAAG2d,OAAOsC,QACxBtC,IAAW3d,GAAG2d,OAAOoC,WACrBpC,IAAW3d,GAAG2d,OAAO0C,iBACrB1C,IAAW3d,GAAG2d,OAAOwC,QAE7BN,mBAAoB7b,EAAKif,YAAYpD,mBACrCC,cAAe9b,EAAKif,YAAYnD,cAexC,OAZA9f,IAAGY,KAAKqB,KAAKpB,SAAS0oB,QAAS,SAASzoB,EAAMV,GAC1CpB,EAAQ8B,GAAQV,IAGpBpB,EAAQyqB,cAAgBxnB,KAAKklB,oBAEzB4F,GACA/sB,GAAGY,KAAKmsB,EAAmB,SAAS5sB,EAAKC,GACrCpB,EAAQmB,GAAOC,IAIhB,GAAIJ,IAAG6uB,wBAAwB7vB,EAASW,IAGnDmvB,oBAAqB,SAASzR,GAC1Bpb,KAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOqC,WAG7C+O,YAAa,SAASrgB,GAClB,GAAc,IAAVA,EACA,MAAOA,GAAQzM,KAAKpB,SAASkH,KAAKinB,YAAY,EAElD,IAAInb,IAAI,CACR,GACInF,IAAgB,IAChBmF,UACKnF,EAAQ;AAEjB,MAAOpI,MAAK2oB,IAAIvgB,EAAO,IAAKwgB,QAAQ,GAAKjtB,KAAKpB,SAASkH,KAAKinB,YAAYnb,IAK5Esb,0BAA2B,WACvB,GAAInrB,GAAO/B,IAEXA,MAAKmtB,qBAELpvB,GAAGY,KAAKqB,KAAKpB,SAASwuB,aAAc,SAASztB,EAAK0tB,GAC9C,GAAIjiB,GAAWiiB,EAAuBjiB,SAClCgf,EAAarsB,GAAGwG,UAAWxC,EAAKnD,SAASwrB,YAAY,GACrDkD,EAAkBvvB,GAAGwG,UAAW8oB,EAEnBhvB,UAAb+M,IACAA,EAAWrJ,EAAKnD,SAASwM,UAGzBkiB,EAAgBlD,YAChBrsB,GAAGwG,OAAO6lB,EAAYiD,EAAuBjD,YAAY,GAG7DrsB,GAAGwG,OAAO+oB,GACNliB,SAAUA,EACVgf,WAAYA,IACb,GAEHroB,EAAKwrB,iBAAiBD,MAI9B5K,WAAY,SAASvJ,GACjB,GAAIqU,GAAmBxtB,KAAKmtB,kBAAkBhU,EAE9C,OAAIqU,GACOA,EAAiB/sB,QAEnB0Y,IAAanZ,KAAKytB,iBAChBztB,KAAKpB,SAASslB,OADpB,QAYT4C,aAAc,SAAS4G,GACnB,GAAIC,GAAQC,EACRC,EAAkBH,CAQtB,IALIG,YAA2B9vB,IAAG4a,YAC9BkV,EAAkBA,EAAgBjV,eAIlCiV,IAAoB9vB,GAAG+M,OAAO+iB,GAAkB,CAChD,GAAI9vB,GAAGgM,OAAO8jB,GACV,MAAOA,GAAgBhH,UAEtB,IAA8C,UAA1CgH,EAAgBhjB,QAAQ/M,eACU,SAAvC+vB,EAAgB1sB,KAAKrD,cAErB,MAAO+vB,GAAgBxnB,aAAatI,GAAGgb,aAAaG,oBAYxD,IATAyU,EAASE,EAAgBtoB,qBAAqB,SAE9CxH,GAAGY,KAAKgvB,EAAQ,SAAShuB,EAAKsL,GAC1B,GAAmC,SAA/BA,EAAM5E,aAAa,QAEnB,MADAunB,GAAY3iB,GACL,IAIX2iB,EACA,MAAOA,GAAUvnB,aAAatI,GAAGgb,aAAaG,uBAK1D4U,gBAAiB,WACb,MAAO9tB,MAAKghB,YAAYrE,UACpBjB,QACI3d,GAAG2d,OAAOyC,UACVpgB,GAAG2d,OAAO0C,gBACVrgB,GAAG2d,OAAOsC,OACVjgB,GAAG2d,OAAOW,WACVte,GAAG2d,OAAOoC,UACV/f,GAAG2d,OAAOwC,UAEf9b,QAKP2rB,mBAAoB,SAAS5U,GACzB,GAAImU,GAAkBttB,KAAKmtB,kBAAkBhU,EAE7C,OAAOmU,GAAkBA,EAAgBlD,WAAapqB,KAAKpB,SAASwrB,YAGxE4D,yBAA0B,SAASC,GAC/B,MAAIA,GAAY7N,eAAgBriB,IAAG4a,WAE3B5Z,KAAMhB,GAAGkV,YAAYgb,EAAY7N,KAAKxH,eACtC2D,KAAM0R,EAAY7N,KAAKxH,cAAc2D,OAKzCxd,KAAMiB,KAAKkjB,YAAY9H,GAAI6S,EAAY7S,KAAKrc,KAC5Cwd,KAAMvc,KAAKkjB,YAAY9H,GAAI6S,EAAY7S,KAAKmB,OAIpD2R,0BAA2B,SAASC,GAChC,GAAIpsB,GAAO/B,KACPouB,IAMJ,OAJArwB,IAAGY,KAAKwvB,EAAc,SAASxuB,EAAKsuB,GAChCG,EAAgBvuB,KAAKkC,EAAKisB,yBAAyBC,MAGhDG,GAIXC,oBAAqB,WACjB,GAAIruB,KAAKpB,SAAS0vB,OAAO1e,KAAO7R,GAAG6R,MAAO,CACtC,GAAI2e,GAAkB,yBAClBrK,EAASlkB,KAAKpB,SAAS0vB,OAAOpK,OAC9B/K,EAAW+K,EAASlkB,KAAK8mB,aAAa5C,GAAUlkB,KAAKytB,iBACrDe,EAAaxuB,KAAKpB,QAGlBua,IAAYA,IAAanZ,KAAKytB,mBAC9Be,EAAaxuB,KAAKmtB,kBAAkBhU,IAIxCqV,EAAWpjB,UAAW,EAGoB,OAAtCojB,EAAWpE,WAAW7Q,YACtBiV,EAAWpE,WAAW7Q,YAAcgV,EAGpCC,EAAWpE,WAAW7Q,aAAe,IAAMgV,EAI/CxwB,GAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjC,GAAIA,EAAOzJ,gBAAkBtB,EAIzB,MAHA+K,GAAO7K,YAAYmV,EAAWpjB,UAC9B8Y,EAAOrJ,eAAe2T,EAAWjV,cAE1B,MAMvBgP,uBAAwB,SAASkG,GAC7B,GAAI1sB,GAAO/B,KACP0uB,EAAiBD,EAAQ9d,UAE7B,OAAI5S,IAAGga,iBAAiB2W,IACpB1uB,KAAKG,IAAIsuB,EAAQ1vB,KAAO,kBAAoB0vB,EAAQ1vB,KAAO,gCAAkC0vB,EAAQ/F,YAC9FgG,EAAezW,KAClB,SAAS0W,GACL5sB,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,YAC1D+F,EAAQjW,UAAUmW,IAEtB,WACQF,EAAQhW,WACR1W,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,YAC1D+F,EAAQhW,aAGR1W,EAAK5B,IAAIsuB,EAAQ1vB,KAAO,wBAA0B0vB,EAAQ/F,gBAKtEgG,KAAmB,EACnBD,EAAQjW,UAAUkW,GAGdD,EAAQhW,WACRzY,KAAKG,IAAIsuB,EAAQ1vB,KAAO,mCAAqC0vB,EAAQ/F,WAAa,iCAClF+F,EAAQhW,aAGRzY,KAAKG,IAAIsuB,EAAQ1vB,KAAO,mCAAqC0vB,EAAQ/F,WAAa,wBAInFgG,IAIXnP,eAAgB,SAASa,EAAM5D,EAASoS,GACpC,GAAI7sB,GAAO/B,KACPub,EAAOxd,GAAGuQ,cACViO,GAAO,EACPxd,EAAOhB,GAAGkV,YAAYmN,GACtByO,EAAazO,EAAKvT,MAAQuT,EAC1B0O,EAAU9uB,KAAK+uB,sBACX/uB,KAAK+uB,sBACLhxB,GAAGgT,KAAKhP,EAAKitB,sBAAuBjtB,IAEvChE,GAAGwM,QAAQskB,IAAeA,EAAWtS,MAAQ,IAC9CA,EAAOsS,EAAWtS,MAGtBuS,EAAQD,EAAY9vB,EAAMwc,EAAMgB,EAAMqS,EAAoBpS,EAASxc,KAAKpB,SAAS0oB,QAAQC,UACrFxG,WAAYhf,EAAKif,YACjByG,YAAa1lB,EAAKoiB,aAClB8K,iBAAkB,SAAS7T,EAAIgF,GAC3Bre,EAAK0e,SAAS/O,IAAI0J,EAAIgF,GACtBre,EAAK2hB,uBACL3hB,EAAKmtB,aAAa9T,OAK9B4T,sBAAuB,SAAS5O,EAAMrhB,EAAMwc,EAAMgB,EAAM4S,EAAU3S,GAC9D,GAAIpB,GAAKpb,KAAKghB,YAAY7E,SAASZ,KAAMA,EAAMxc,KAAMA,EAAMwd,KAAMA,EAAMC,QAASA,GAEhFxc,MAAKygB,SAAS/O,IAAI0J,EAAIgF,GACtBpgB,KAAKkvB,aAAa9T,GAElBpb,KAAK0jB,uBAELyL,EAAStvB,MAAMub,GAAIA,EAAIgF,KAAMA,KAGjCqI,oBAAqB,SAAS5b,EAAMuiB,GAChC,GAAIC,GAAYxiB,EAAK1L,KAAKwG,MAAM,KAAK,GACjC5I,EAAOqwB,CAGC,OAARrwB,IACAA,EAAOiB,KAAKpB,SAASypB,MAAM5I,aAG/B1gB,GAAQ,IAAMswB,EAEdrvB,KAAK8e,UACD/f,KAAMA,EACN8N,KAAMA,KAKd0gB,iBAAkB,SAASnR,GACvB,GAAI8H,GAASlkB,KAAK6pB,qBACdM,OAAQ/N,EAAKgO,WAAW7Q,YACxB2Q,kBAAmB9N,EAAKgO,WAAWF,kBACnCzpB,QAAS2b,EAAK3b,QACd6Y,QAAS8C,EAAK9C,QACdlO,SAAUgR,EAAKhR,SACfgO,MAAOgD,EAAKuO,gBAGhB3qB,MAAKmtB,kBAAkBjJ,EAAOzJ,eAAiB2B,GAGnDkT,0BAA2B,WACvBtvB,KAAKuvB,aAAexxB,GAAGyxB,aAAe,GAAIzxB,IAAGyxB,YACzCxvB,KAAKpB,SAASwT,KAAMrU,GAAGgT,KAAK/Q,KAAKmmB,kBAAmBnmB,MAAOjC,GAAGgT,KAAK/Q,KAAKG,IAAKH,OAG7EA,KAAKuvB,cAAgBvvB,KAAKuvB,aAAaE,gBACvCzvB,KAAKmkB,aAAenkB,KAAK2oB,aACrB3oB,KAAKpB,SAAS0oB,QAAQ/pB,OAASyC,KAAKuvB,aAAaG,uBAGrD1vB,KAAKpB,SAAS+wB,WAAa3vB,KAAKuvB,aAAaK,cACzC5vB,KAAKuvB,aAAaM,cAClB7vB,KAAKpB,SAAS0oB,QAAQzI,SAAW7e,KAAKuvB,aAAaM,cAIvD7vB,KAAKmkB,aAAenkB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQ/pB,SAIpEuyB,kBAAmB,WACf,SAAK/xB,GAAGmpB,0BAA4BlnB,KAAKpB,SAASwiB,WAAWH,YAIzDjhB,KAAKpB,SAAS+oB,KAAKoI,aACfhyB,GAAGiW,kBAAkB2C,sBAIrB5Y,GAAGiW,kBAAkB0C,oBAAqB1W,KAAKpB,SAAS+oB,KAAKqI,aAUzE/F,oBAAqB,SAASgG,EAAS9c,GACnC,GAAI+c,IAAQ,CAEZ,QAAKD,EAAQ7tB,SAIbrE,GAAGY,KAAKsxB,EAAS,SAAStwB,EAAKwwB,GAK3B,GAAIpyB,GAAGoL,SAASgnB,GAAa,CAEzB,GAAIC,GAAW,GAAIzrB,QAAO,MAAQwrB,EAAa,IAAK,IAEpD,IAAgC,MAA5Bhd,EAAS/R,MAAMgvB,GAEf,MADAF,IAAQ,GACD,KAKZA,IAWX9J,WAAY,SAASiK,EAAMC,EAAkBrnB,GASzC,QAASuF,GAAEzP,EAAMwxB,GAAenwB,EAAUA,EAAQ4E,QAAQjG,EAAMwxB,GARhE,GAMIC,GAAsBC,EANtBrwB,EAAUJ,KAAKpB,SAAS8xB,SAASL,GACjCnG,KACAyG,KAAWxf,OAAOmf,GAClBvxB,EAAO4xB,EAAM,GACbxX,EAAWnZ,KAAK8mB,aAAa7d,GAC7B2nB,EAAiB5wB,KAAK+tB,mBAAmB5U,EA+B7C,OA1BApb,IAAGY,KAAKiyB,EAAe1G,kBAAmB,SAASvqB,EAAKkxB,GAKhD9yB,GAAGoL,SAAS0nB,IACZ3G,EAAkBrqB,KAAKgxB,KAI/BL,EAAuBtG,EAAkBnY,KAAK,MAAMjU,cAEpD0Q,EAAE,SAAUxO,KAAKpB,SAASkyB,eAAe/xB,IACzCyP,EAAE,eAAgBgiB,GAClBhiB,EAAE,cAAexO,KAAK8sB,YAAY8D,EAAeG,YACjDviB,EAAE,iBAAkBxO,KAAK8sB,YAAY8D,EAAeI,eAEpDP,EAAmBrwB,EAAQgB,MAAM,cACR,OAArBqvB,GACA1yB,GAAGY,KAAK8xB,EAAkB,SAAS9wB,EAAKsxB,GACpCziB,EAAEyiB,EAAaN,EAAMhxB,MAI7BK,KAAKpB,SAASF,UAAUsoB,QAAQ,KAAMjoB,EAAMqB,EAAS/B,QAE9C+B,GAYXwkB,aAAc,SAASxJ,EAAIzK,GACvB,GAAI3Q,KAAKkxB,qBAAqB9V,GAW1B,MAVApb,MAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO0C,iBAErCzN,EACAA,EAASyK,GAGTpb,KAAKygB,SAASkE,MAAMvJ,IAGjB,GAIfuO,kBAAmB,SAASvO,EAAIM,GAC5B,GAAI3Z,GAAO/B,KACPmxB,EAAcnxB,KAAK8tB,iBAEnBpS,KAAW3d,GAAG2d,OAAO2C,kBACrBre,KAAKwkB,+BAA+B3kB,KAAKub,GAEpCM,IAAW3d,GAAG2d,OAAO4C,eAC1Bte,KAAKykB,4BAA4B5kB,KAAKub,GAGtB,IAAhB+V,IACCnxB,KAAKwkB,+BAA+BpiB,QAAUpC,KAAKykB,4BAA4BriB,SAEhFwnB,WAAW,WACP7nB,EAAKqvB,eAAervB,EAAKyiB,+BAAgCziB,EAAK0iB,8BAC/D,IAIXtF,iCAAkC,WAC9B,GAAIpd,GAAO/B,IAEX,IAAIA,KAAKpB,SAASmrB,YAAYsH,mBAAqBtzB,GAAGgS,UAAYhS,GAAGkS,YAIjE,KAHA2Z,YAAW,WACPziB,OAAOmqB,MAAMvvB,EAAKnD,SAAS8xB,SAASa,+BACrC,GACG,GAAIxzB,IAAGmG,MAAMlE,KAAKpB,SAAS8xB,SAASa,+BAIlDC,8BAA+B,SAASpW,EAAIrc,EAAM0yB,EAAUhd,GAGxD,IAAKgd,EAASpkB,QACV,GAAIoH,GAAsB,MAAfA,EAAIiH,SAAmB+V,EAASvxB,MACvCF,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,8BAAgC0V,EAAIiH,OAAQjH,OAErF,CACD,GAAIid,GAAcD,EAASvxB,MAAQuxB,EAASvxB,MAAQF,KAAKpB,SAASkH,KAAK6rB,oBACvE3xB,MAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM2yB,EAAajd,KAKnEmd,6CAA8C,SAASC,EAAWjmB,EAAO1J,EAAO3E,EAAQshB,GACpF,GAAI9c,GAAO/B,IAEX,IAAI4L,EAAMxJ,OAASF,EACf,GAAI2vB,IAAc7xB,KAAKpB,SAASwrB,WAAW0H,uBAEvClI,WAAW,WACP,GAAImI,GAAuBhwB,EAAKisB,yBAAyBpiB,EAAM1J,IAC3DiX,EAAWpX,EAAK+kB,aAAalb,EAAM1J,GAAOke,MAC1C8D,EAASniB,EAAK2gB,WAAWvJ,EAE7BpX,GAAKwmB,wBACDxpB,KAAM,aACN4R,SAAU5S,GAAGgT,KAAKhP,EAAKnD,SAASF,UAAUszB,WAAYjwB,EAAMgwB,EAAsB7N,GAClF1L,UAAWza,GAAGgT,KAAKhP,EAAKkwB,2BAA4BlwB,EAAM6J,EAAO1J,EAAO3E,EAAQshB,GAChFpG,UAAW1a,GAAGgT,KAAKhP,EAAKmwB,2BAA4BnwB,EAAM6J,EAAO1J,EAAO3E,EAAQshB,GAChF6J,WAAY,SAAWqJ,EAAqBhzB,KAAO,YAAcgzB,EAAqBxV,QAE3F,OAEF,KAAKsV,EACN,KAAO3vB,EAAQ0J,EAAMxJ,OAAQF,IACzBH,EAAK8qB,oBAAoBjhB,EAAM1J,GAAOkZ,KAMtDgW,eAAgB,SAASe,EAAYC,GACjCpyB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAe2N,cAAcF,EAAYC,EAAQpyB,KAAKgkB,iBAElFhkB,KAAKpB,SAASF,UAAU2zB,cAAct0B,GAAGwG,UAAW4tB,GAAap0B,GAAGwG,UAAW6tB,IAE/EpyB,KAAKwkB,kCACLxkB,KAAKykB,gCAeT6H,aAAc,SAASlR,EAAIrc,EAAMstB,EAAc5X,EAAK9D,GAChD,GAAI5O,GAAO/B,IAIX,IAFA+B,EAAKiiB,gBAAgB5I,GAAMiR,EAAatqB,EAAKnD,SAAS+lB,MAAMsG,8BAExDlpB,EAAKuwB,iBAAiBlX,EAAIrc,EAAMstB,GAAe,CAC/C,GAAIkG,GAAyD,IAAvCxwB,EAAKnD,SAAS+lB,MAAM6N,gBAkB1C,OAhBAzwB,GAAKyvB,8BAA8BzxB,MAAMgC,EAAMtC,WAC/CsC,EAAKnD,SAASF,UAAU0tB,YAAYhR,EAAIrc,EAAMgD,EAAK+hB,aAAa1I,IAChErZ,EAAK0wB,mBAAmBrX,EAAIrc,GAE5BgD,EAAKif,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO0C,iBACzCrc,EAAKgiB,eAAe3I,GAAMwO,WAAW,WACjC7nB,EAAK5B,IAAI,sBAAwBpB,EAAO,OAEpC4R,EACAA,EAASyK,GAGTrZ,EAAK0e,SAASkE,MAAMvJ,IAEzBmX,IAEI,IAIfE,mBAAoB,SAASrX,EAAIrc,GAC7BiB,KAAKG,IAAI,WAAaH,KAAKpB,SAAS+lB,MAAM6N,iBAAmB,4BAA8BzzB,EAAO,QAItGmyB,qBAAsB,SAAS9V,GAC3B,GACIjI,GADAuf,EAAY1yB,KAAKyjB,iBAGrB,OAAIzjB,MAAKgkB,gBAAgB5I,IACrBpb,KAAKG,IAAI,gCAAkCib,EAAI,SACxC,GAEFpb,KAAKygB,SAASe,QAAQpG,IAC3BjI,EAAWnT,KAAKkhB,QAAQ9F,GAEpBpb,KAAKpB,SAASF,UAAUi0B,cAAcvX,EAAIjI,MAAc,IAIxDuf,EAAY,GAAK1yB,KAAK0jB,qBAAuB,EAAIgP,GACjD1yB,KAAKomB,WAAW,0BACT,IAGXpmB,KAAKG,IAAI,wBAA0BgT,EAAW,UAAYiI,EAAK,SACxD,MAGPpb,KAAKG,IAAI,IAAMib,EAAK,2BAA4B,UACzC,IAIfsQ,UAAW,SAAStQ,EAAIrc,GACpBiB,KAAK0jB,uBAELkP,aAAa5yB,KAAK+jB,eAAe3I,GAEjC,IAAIyX,GAAkB90B,GAAG6J,QAAQ5H,KAAKof,WAAYhE,IAC7Cpb,KAAKpB,SAAS+wB,YAAckD,GAAmB,GAChD7yB,KAAKof,WAAWnC,OAAO4V,EAAiB,GAG5C7yB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOuC,WAG7CsN,YAAa,SAASnQ,EAAIrc,EAAMqG,EAAQqP,GAoBpC,MAnBKrP,GAAOiI,SASJjI,EAAOshB,eACP1mB,KAAKkiB,eAAe9G,GAAMhW,EAAOshB,cAGrC1mB,KAAKsjB,eACLtjB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO2C,qBAbzCre,KAAK0jB,uBACL1jB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO4C,eAErClZ,EAAOpF,KAAKpB,SAAS+lB,MAAMsG,iCAAkC,IAC7DjrB,KAAKgkB,gBAAgB5I,IAAM,IAYnCpb,KAAKwxB,8BAA8BpW,EAAIrc,EAAMqG,EAAQqP,KAE9CrP,EAAOiI,SAGlBwa,UAAW,SAASzM,GAChBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO8C,WAG7CyJ,kBAAmB,SAAS7M,EAAI2M,EAAUC,GACtC,GAAIjpB,GAAOiB,KAAKkhB,QAAQ9F,EAEpB4M,IACAhoB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO6C,eACzCve,KAAKG,IAAI,uBAAyBpB,EAAO,gBAAiB,SAIzBV,SAA7B0pB,EAASrT,gBACT1U,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,wBAAyBgpB,GAGnE/nB,KAAKpB,SAASF,UAAUsoB,QAAQ5L,EAAIrc,EAAM,4CAA8CgpB,EAASrM,OAAQqM,KAI7G/nB,KAAK0jB,uBACL1jB,KAAKsjB,eACLtjB,KAAKygB,SAASqS,QAAQ1X,GACtBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAO+C,SACzCze,KAAKG,IAAI,uBAAyBpB,EAAO,sBAIjD2rB,eAAgB,SAASzf,GACrB,GAAI8nB,EAEJ,IAAIh1B,GAAGiW,kBAAkBqC,cAAe,CACpC,IAAK0c,EAAY,EAAGA,EAAY9nB,EAAMkV,MAAM/d,OAAQ2wB,IAChD/yB,KAAK2mB,sBAAsB1b,EAAMkV,MAAM4S,GAAY9nB,EAGvDjL,MAAK8e,SAAS7T,EAAMkV,WAGflV,GAAMvC,MAAMtG,OAAS,GAC1BpC,KAAK8e,SAAS7T,EAGlBlN,IAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjCA,EAAOpJ,WAIfuQ,YAAa,SAASjQ,EAAIrc,EAAMosB,EAAQC,GACpCprB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAesO,qBAAqB5X,EAAI+P,EAAQC,IAGhF6H,UAAW,SAAS7X,EAAIrc,KAIxBm0B,yBAA0B,SAAS9X,EAAIrc,GACnCiB,KAAKizB,UAAUlzB,MAAMC,KAAMP,WAC3BO,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOoC,WACzC9d,KAAKmzB,aAAapzB,MAAMC,KAAMP,WAE1BO,KAAKpB,SAAS+wB,YACd3vB,KAAKpB,SAASF,UAAU00B,YAAYrzB,MAAMC,KAAMP,WAChDO,KAAKmhB,YAAY/F,KAGjBpb,KAAKqzB,eAAejY,GACpBpb,KAAKpB,SAASF,UAAU00B,YAAYrzB,MAAMC,KAAMP,aAIxD4hB,gBAAiB,SAASjG,EAAIkY,EAAmBC,GAC7C,GACIC,GADAjY,EAAOvb,KAAK2jB,QAAQvI,EAOxB,OAJIkY,KACAE,EAA4Bz1B,GAAGgT,KAAKuiB,EAAmBtzB,KAAMob,EAAIG,EAAMgY,IAGvEvzB,KAAK8vB,qBACL9vB,KAAKuoB,wBACDxpB,KAAM,iBACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU+0B,eAAgBzzB,KAAMob,GAChE5C,UAAWgb,GACPz1B,GAAGgT,KAAK/Q,KAAK0zB,eAAeC,WAAY3zB,KAAMob,EAAIG,EAAMgY,GAC5D7K,WAAYtN,KAET,IAGPpb,KAAKG,IAAI,iCAAmCib,EAAK,wHACuB,SACjE,IAIf+X,aAAc,SAAS/X,KAIvBwY,iBAAkB,SAASzI,EAAQC,GAC/BprB,KAAKpB,SAASF,UAAUm1B,gBAAgB1I,EAAQC,IAGpDQ,cAAe,SAASxQ,KAIxB0Q,UAAW,SAAS1Q,EAAIrc,GACpBiB,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOyC,YAG7C8N,eAAgB,SAAS7Q,EAAI4Q,KAI7BtC,sBAAuB,SAAStO,EAAI2B,EAAWD,GAEvCA,IAAc/e,GAAG2d,OAAOwC,QACxB0U,aAAa5yB,KAAK+jB,eAAe3I,KAIzC0Y,gCAAiC,SAAS3F,GACtC,GAAIpsB,GAAO/B,IAEXjC,IAAGY,KAAKwvB,EAAc,SAASxuB,EAAKsuB,GAChClsB,EAAK8qB,oBAAoBoB,EAAY7S,OAI7C2Y,gCAAiC,SAASC,EAAuBpoB,EAAOrO,EAAQshB,EAAUqF,GACtF,GAAI+P,GACAvB,EAAY1yB,KAAKyjB,kBACjByQ,EAAmCl0B,KAAK0jB,oBAE1B,KAAdgP,GAAmBwB,GAAoCxB,EACnD9mB,EAAMxJ,OAAS,EACfpC,KAAKuoB,wBACDxpB,KAAM,aACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAUszB,WAAYhyB,KAAMg0B,EAAsB,GAAI9P,GACtF1L,UAAWza,GAAGgT,KAAK/Q,KAAKiyB,2BAA4BjyB,KAAM4L,EAAO,EAAGrO,EAAQshB,GAC5EpG,UAAW1a,GAAGgT,KAAK/Q,KAAKkyB,2BAA4BlyB,KAAM4L,EAAO,EAAGrO,EAAQshB,GAC5E6J,WAAY,SAAW9c,EAAM,GAAGwU,KAAKrhB,KAAO,YAAc6M,EAAM,GAAGwU,KAAK7D,OAI5Evc,KAAKomB,WAAW,iBAIpBpmB,KAAK8zB,gCAAgCloB,GACrCqoB,EAAej0B,KAAKpB,SAAS8xB,SAASyD,kBACjCnvB,QAAQ,gBAAiBkvB,GACzBlvB,QAAQ,iBAAkB0tB,GAC/B1yB,KAAK+mB,YAAYkN,KAIzB/B,2BAA4B,SAAStmB,EAAO1J,EAAO3E,EAAQshB,GACvD,GAAIuV,GAAYlyB,EAAQ,CAExBlC,MAAK6sB,oBAAoBjhB,EAAM1J,GAAOkZ,GAAIxP,EAAM1J,GAAOke,KAAKrhB,MAE5DiB,KAAK4xB,8CAA6C,EAAOhmB,EAAOwoB,EAAW72B,EAAQshB,IAGvFoT,2BAA4B,SAASrmB,EAAO1J,EAAO3E,EAAQshB,GACvD,GAAI9c,GAAO/B,KACPo0B,EAAYlyB,EAAQ,EACpB6vB,EAAuB/xB,KAAKguB,yBAAyBpiB,EAAM1J,GAE/DlC,MAAKq0B,wBAAwBzoB,EAAM1J,GAAQ6vB,GACtC9Z,KACD,WACIlW,EAAKuyB,QAAQ1oB,EAAM1J,GAAOkZ,GAAI7d,EAAQshB,GACtC9c,EAAK6vB,8CAA6C,EAAMhmB,EAAOwoB,EAAW72B,EAAQshB,IAEtF,WACI9c,EAAK6vB,8CAA6C,EAAOhmB,EAAOwoB,EAAW72B,EAAQshB,MAK/F0B,uBAAwB,SAAS3U,EAAOrO,EAAQshB,GAC5C,GAAqB,IAAjBjT,EAAMxJ,OAEN,WADApC,MAAKomB,WAAW,eAIpB,IAAI4N,GAAwBh0B,KAAKkuB,0BAA0BtiB,GACvDuN,EAAWnZ,KAAK8mB,aAAalb,EAAM,GAAGwU,MACtC8D,EAASlkB,KAAK0iB,WAAWvJ,EAE7BnZ,MAAKuoB,wBACDxpB,KAAM,kBACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU61B,gBAAiBv0B,KAAMg0B,EAAuB9P,GACxF1L,UAAWza,GAAGgT,KAAK/Q,KAAK+zB,gCAAiC/zB,KAAMg0B,EAAuBpoB,EAAOrO,EAAQshB,EAAUqF,GAC/GzL,UAAW1a,GAAGgT,KAAK/Q,KAAK8zB,gCAAiC9zB,KAAM4L,GAC/D8c,WAAY,sBAIpB8L,wBAAyB,WACrB,GAAIzyB,GAAO/B,IAEXA,MAAK4qB,gBAAgB1nB,OAAOiE,OAAQ,eAAgB,SAASiJ,GACzD,GAAIrO,EAAKghB,gBAKL,MAJA3S,GAAIA,GAAKjJ,OAAOstB,MAEhBrkB,EAAEC,YAActO,EAAKnD,SAAS8xB,SAASgE,QAEhC3yB,EAAKnD,SAAS8xB,SAASgE,WAQ1CnQ,oBAAqB,WACjB,GAAIxiB,GAAO/B,KACPjD,EAAUiD,KAAKpB,SAASylB,OAGxBtmB,IAAG42B,SAA6C,MAAlC30B,KAAKpB,SAASylB,QAAQxF,WAC/B7e,KAAK40B,WACN72B,GAAGwG,OAAOxH,GAAU4qB,KAAM3nB,KAAKpB,SAAS+oB,OAExC5qB,EAAQoD,IAAMpC,GAAGgT,KAAK/Q,KAAKG,IAAKH,MAChCjD,EAAQ83B,cAAgB92B,GAAGgT,KAAK/Q,KAAKkf,eAAgBlf,MAErDA,KAAK40B,SAAW,GAAI72B,IAAG42B,QAAQ53B,IAGnC6sB,WAAW,WACP7nB,EAAK6yB,SAASE,UAAU7c,KAAK,SAASwZ,EAAU1J,GAC5ChmB,EAAKgzB,0BACLhzB,EAAKnD,SAASF,UAAUs2B,yBAAyBvD,GAAU,EAAM1J,IAElE,SAAS0J,EAAU1J,GAElBhmB,EAAKnD,SAASF,UAAUs2B,yBAAyBvD,GAAU,EAAO1J,MAEvE,KAIXgN,wBAAyB,aAEzBtI,SAAU,SAASrR,EAAIoC,GACnBxd,KAAKghB,YAAYzD,WAAWnC,EAAIoC,GAChCxd,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAeuQ,UAAU7Z,IAGzDkX,iBAAkB,SAASlX,EAAIrc,EAAMstB,GACjC,GAAItL,GAAa/gB,KAAKghB,YAAYrE,UAAUvB,GAAIA,GAGhD,WAAKpb,KAAKgkB,gBAAgB5I,IACnBpb,KAAKpB,SAAS+lB,MAAMuQ,YACpBnU,EAAWrF,SAAW3d,GAAG2d,OAAOwC,SAEL7f,SAA1B2B,KAAK8jB,aAAa1I,KAClBpb,KAAK8jB,aAAa1I,GAAM,GAGxBpb,KAAK8jB,aAAa1I,GAAMpb,KAAKpB,SAAS+lB,MAAMwQ,oBAC5Cn1B,KAAK8jB,aAAa1I,IAAO,GAClB,IAOnBiY,eAAgB,SAASjY,GACrBpb,KAAKof,WAAWvf,KAAKub,IAIzB8T,aAAc,SAAS9T,GACnB,GAAIjC,EAGAA,GADApb,GAAGiW,kBAAkBqC,cACVrW,KAAKygB,SAAS2B,QAAQhH,GAAIyL,WAG1B7mB,KAAK8mB,aAAa9mB,KAAKygB,SAASjG,SAASY,IAGpDjC,IACAnZ,KAAK2iB,qBAAqBvH,GAAMjC,IAIxC0M,4BAA6B,SAASuP,GAClCp1B,KAAKpB,SAASwT,KAAK3R,QAAU20B,EAE7Bp1B,KAAKuvB,aAAexxB,GAAGyxB,aAAe,GAAIzxB,IAAGyxB,YACrCxvB,KAAKpB,SAASwT,KAAMrU,GAAGgT,KAAK/Q,KAAKmmB,kBAAmBnmB,MAAOjC,GAAGgT,KAAK/Q,KAAKG,IAAKH,OAGjFA,KAAKuvB,cAAgBvvB,KAAKuvB,aAAaE,iBACvCzvB,KAAKmkB,aAAaqF,YAAY,KAAMxpB,KAAKuvB,aAAaG,uBAEtD1vB,KAAKpB,SAAS+wB,WAAa3vB,KAAKuvB,aAAaK,cACzC5vB,KAAKuvB,aAAaM,aAClB7vB,KAAK0lB,YAAY1lB,KAAKuvB,aAAaM,eAK/CyE,QAAS,SAASlZ,EAAI7d,EAAQshB,GAC1B,GAAI9f,GAAOiB,KAAKkhB,QAAQ9F,EAEpB7d,IACAyC,KAAKimB,UAAU1oB,EAAQ6d,GAGvByD,GACA7e,KAAK0lB,YAAY7G,EAAUzD,GAG/Bpb,KAAKuoB,wBACDxpB,KAAM,WACN4R,SAAU5S,GAAGgT,KAAK/Q,KAAKpB,SAASF,UAAU22B,SAAUr1B,KAAMob,EAAIrc,GAC9DyZ,UAAWza,GAAGgT,KAAK/Q,KAAKkzB,yBAA0BlzB,KAAMob,EAAIrc,GAC5D0Z,UAAW1a,GAAGgT,KAAK/Q,KAAK6sB,oBAAqB7sB,KAAMob,EAAIrc,GACvD2pB,WAAYtN,KAIpB+F,YAAa,SAAS/F,GACbpb,KAAKygB,SAASlV,OAAO6P,IACtBpb,KAAKghB,YAAYnE,UAAUzB,EAAIrd,GAAG2d,OAAOsC,SAIjDqI,mBAAoB,WAIhB,IAHA,GAAIiP,GAAYC,EACZxzB,EAAO/B,KAEJA,KAAKof,WAAWhd,QACnBkzB,EAAat1B,KAAKof,WAAW5L,QAC7BxT,KAAKmhB,YAAYmU,EAIrBC,GAAkBv1B,KAAKkjB,YAAYxH,OAAQ3d,GAAG2d,OAAOW,aAAaja,OAC9DmzB,IACAx3B,GAAGoC,IAAI,qBAAuBo1B,EAAkB,yEAChD3L,WAAW,WACP7nB,EAAKskB,sBACN,OAYXgO,wBAAyB,SAASpG,EAAa8D,GAC3C,GAAIhwB,GAAO/B,KACPogB,EAAQ,WACJ,MAAI6N,GAAY7N,eAAgBriB,IAAG4a,UACxBsV,EAAY7N,KAAKxH,cAErBqV,EAAY7N,QAEvBrhB,EAAOgzB,EAAqBhzB,KAC5Bwd,EAAOwV,EAAqBxV,KAC5BpD,EAAWnZ,KAAK8mB,aAAamH,EAAY7N,MACzCwQ,EAAiB5wB,KAAK+tB,mBAAmB5U,GACzCqc,EAAkB,GAAIz3B,IAAGoP,OAQ7B,OANAqoB,GAAgBvd,KACZ,aACA,WACIlW,EAAK8qB,oBAAoBoB,EAAY7S,GAAIrc,KAG7ChB,GAAGsM,cAAc+V,KAAUpgB,KAAKiqB,oBAAoB2G,EAAe1G,kBAAmBnrB,IACtFiB,KAAKomB,WAAW,YAAarnB,EAAMqhB,GAC5BoV,EAAgBjoB,WAGtBvN,KAAKpB,SAASwrB,WAAWqL,YAAuB,IAATlZ,EAKxCA,EAAO,GAAKqU,EAAeG,WAAaxU,EAAOqU,EAAeG,WAC9D/wB,KAAKomB,WAAW,YAAarnB,EAAMqhB,GAC5BoV,EAAgBjoB,WAGvBgP,EAAO,GAAKA,EAAOqU,EAAeI,cAClChxB,KAAKomB,WAAW,eAAgBrnB,EAAMqhB,GAC/BoV,EAAgBjoB,YAGvBxP,GAAG23B,iBAAmB33B,GAAGiW,kBAAkBiD,eAAiBlZ,GAAGgM,OAAOqW,GACtE,GAAIriB,IAAG23B,gBAAgBtV,EAAMriB,GAAGgT,KAAKhP,EAAK5B,IAAK4B,IAAO4zB,SAAS/E,EAAegF,OAAO3d,KACjFud,EAAgBnoB,QAChB,SAASwoB,GACL9zB,EAAKqkB,WAAWyP,EAAY,aAAc92B,EAAMqhB,GAChDoV,EAAgBjoB,YAKxBioB,EAAgBnoB,UAGbmoB,IA3BHx1B,KAAKomB,WAAW,aAAcrnB,EAAMqhB,GAC7BoV,EAAgBjoB,YA6B/BuoB,eAAgB,WACZ,GAAI/zB,GAAMg0B,EAAcl3B,CAExBkD,GAAO/B,KAEP+1B,EAAe,SAASh3B,EAAM4R,EAAU/N,GACpC,GAAIozB,EAEJ,KACI,MAAOrlB,GAAS5Q,MAAMgC,EAAMa,GAEhC,MAAOqzB,GACHD,EAAWC,EAAU71B,SAAW61B,EAAUztB,WAC1CzG,EAAK5B,IAAI,wBAA0BpB,EAAO,gBAAkBi3B,EAAU,UAK9E,KAAKn3B,IAAQmB,MAAKpB,SAASF,WACtB,WACG,GAAIw3B,GAAcC,CAClBD,GAAer3B,EACfs3B,EAAep0B,EAAKnD,SAASF,UAAUw3B,GACvCn0B,EAAKnD,SAASF,UAAUw3B,GAAgB,WACpC,MAAOH,GAAaG,EAAcC,EAAc12B,oBCh0DvE,WACG,YAEA1B,IAAGq4B,kBAAoB,SAASpd,GAC5B,GAAIjX,GAAO/B,IAGXA,MAAKpB,UACDglB,OAAO,EACPM,OAAQ,KACR9Y,UAAU,EACVgc,eAAgB,EAChBiP,6BAA6B,EAC7B1G,YAAY,EAEZrI,SACIE,iBACA3I,SAAU,iBACVyX,cAAe,aACfC,gBAAgB,EAChB9L,UAAW,SACXtD,OAAQ,OACR5pB,UACAi5B,cAAc,EACdC,kBAAmB,kBACnBlP,SAAU,UAGd6C,YACIF,qBACA6G,UAAW,EACXC,aAAc,EACd0B,UAAW,EACXZ,wBAAwB,EACxBvY,YAAa,KACbqc,OACIc,UAAW,EACXC,SAAU,EACVC,UAAW,EACXC,SAAU,GAEdpB,YAAY,GAGhB/2B,WACI22B,SAAU,SAASja,EAAIrc,KACvBq0B,YAAa,SAAShY,EAAIrc,KAC1BusB,WAAY,SAASlQ,EAAIrc,EAAMstB,EAAcyK,KAC7CzE,cAAe,SAASF,EAAYC,KACpC5G,SAAU,SAASpQ,EAAIrc,KACvB8sB,SAAU,SAASzQ,EAAIrc,KACvBgtB,cAAe,SAAS3Q,EAAIrc,EAAMitB,KAClCE,qBAAsB,SAAS9Q,EAAI4Q,EAAWK,EAAc5X,KAC5D0X,SAAU,SAAS/Q,EAAIjI,EAAU6Y,KACjCd,WAAY,SAAS9P,EAAIrc,EAAMosB,EAAQC,KACvCyI,gBAAiB,SAAS1I,EAAQC,KAClCpE,QAAS,SAAS5L,EAAIrc,EAAMyjB,EAAQuU,KACpC3K,YAAa,SAAShR,EAAIrc,EAAMi4B,KAChCrE,cAAe,SAASvX,EAAIrc,KAC5Bw1B,gBAAiB,SAAS0C,KAC1BjF,WAAY,SAASiF,KACrBxD,eAAgB,SAASrY,KACzBwM,SAAU,SAASxM,KACnB0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,KACzCQ,gBAAiB,SAAS3b,KAC1B6P,eAAgB,SAAStB,EAAI2B,EAAWD,KACxCkY,yBAA0B,SAASvD,EAAUpkB,EAAS0a,MAG1D2I,UACIwG,UAAW,qEACXC,UAAW,yDACXC,aAAc,4DACdC,WAAY,yDACZC,aAAc,sBACdnD,kBAAmB,6EACnBoD,oBAAqB,qBACrBC,mBAAoB,qBACpBC,oBAAqB,4BACrBC,mBAAoB,4BACpBC,sBAAuB,mDACvBjD,QAAS,8EACTnD,6BAA8B,6KAGlC5M,OACIuQ,YAAY,EACZC,gBAAiB,EACjB3C,iBAAkB,EAClBvH,6BAA8B,gBAGlCZ,SACIE,YAAa,yBACbD,YAAa,0BAGjB9T,UACIyK,SAAS,EACT2W,YACI3W,SAAS,GAEb4W,WAAW,EACXC,YACIC,UAAW,cACXC,eAAgB,mBAChBC,UAAW,cACXC,cAAe,kBACfC,WAAY,gBAEhBC,SAAU,IAEV/qB,SACIwR,SAAU,OAIlBvH,QACI2J,SAAS,EACToX,gBAAiB,EACjBP,YACIQ,SAAU,aAIlBxH,eAAgB,SAASyH,GACrB,MAAOA,IAGXzyB,MACI6rB,qBAAsB,gCACtBhH,eAAgB,aAChBoC,aAAc,KAAM,KAAM,KAAM,KAAM,KAAM,OAGhD3L,YACIH,SAAS,EACTkG,OAAQ,SACRtI,SAAU,iBACV2I,iBACAjqB,WAGJoqB,MACIoI,UAAU,EACVyI,iBAAiB,EACjBxI,UAAU,GAGdxQ,OACIC,YAAa,aAGjB4I,OACID,cAAe,KACf3I,YAAa,gBAGjB6O,QACI1e,KAAK,EAGLsU,OAAQ,MASZkJ,gBAIA/I,SACIxF,SAAU,KACVthB,UACAiqB,iBACAlD,gBAAgB,GAIpBlS,MAEI3R,QAAS,UAGTkvB,YAAY,EAGZ8I,iBAAiB,GAIrBlhB,SACImhB,cAAe,KAGfC,cAAc,EAGdC,QAAQ,EAIRC,YAAa,KAEbC,eAAgB,GAEhBC,YAAa,kBAEbC,aAAa,EAGbC,UAGJlP,aACIC,gBAAgB,EAChBqH,mBAAmB,EACnB7G,kBAAkB,IAK1BzsB,GAAGwG,OAAOvE,KAAKpB,SAAUoa,GAAG,GAE5BhZ,KAAKikB,YACLjkB,KAAKmtB,qBACLntB,KAAK2iB,wBAEL3iB,KAAK81B,iBACL91B,KAAK4qB,gBAAmB,GAAI7sB,IAAGqV,eAE/BpT,KAAKof,cACLpf,KAAK8jB,gBACL9jB,KAAK+jB,kBACL/jB,KAAKgkB,mBACLhkB,KAAKkiB,kBAELliB,KAAK0jB,qBAAuB,EAC5B1jB,KAAKsjB,aAAe,EACpBtjB,KAAKghB,YAAchhB,KAAKypB,2BAExBzpB,KAAKsvB,4BAELtvB,KAAKklB,oBAAsBllB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQE,eACnExnB,KAAKqlB,8BAAgCrlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAWoG,eAEhFxnB,KAAKylB,uBAAyBzlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAW7jB,QAEzEyC,KAAK6iB,eAAiB7iB,KAAK2oB,aAAa3oB,KAAKpB,SAAS0oB,QAAQzI,UAC9D7e,KAAKulB,yBAA2BvlB,KAAK2oB,aAAa3oB,KAAKpB,SAASwiB,WAAWvC,UAE3E7e,KAAKygB,SAAWzgB,KAAK6qB,uBAErB7qB,KAAK0zB,eAAiB31B,GAAGmpB,yBAA2BlnB,KAAKinB,uBAErDjnB,KAAKpB,SAASslB,SACdlkB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAKpB,SAASslB,OACvB9K,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGPza,KAAKktB,4BAELltB,KAAKquB,sBAEDruB,KAAKpB,SAASypB,MAAMD,gBAChBrqB,GAAGoqB,aACHnoB,KAAKokB,cAAgBpkB,KAAKkoB,sBAG1BloB,KAAKG,IAAI,iCAAkC,UAInDH,KAAKw0B,0BAELx0B,KAAKiiB,gBAAkBlkB,GAAGm7B,gBAAkB,GAAIn7B,IAAGm7B,eAAen7B,GAAGgT,KAAK/Q,KAAKG,IAAKH,OACpFA,KAAKukB,sBAELvkB,KAAKwkB,kCACLxkB,KAAKykB,+BAELzkB,KAAKm5B,QAAWp7B,GAAGgnB,QAAU,GAAIhnB,IAAGgnB,OAAO/kB,KAAKpB,SAAS2Y,QAASxZ,GAAGgT,KAAK/Q,KAAKG,IAAKH,WAChFA,KAAKm5B,QAAQlY,UACbjhB,KAAK+uB,sBAAwBhxB,GAAGgT,KAAK/Q,KAAKm5B,QAAQC,cAAep5B,KAAKm5B,UAGtEp7B,GAAGs7B,eAAiBt7B,GAAGiW,kBAAkBqD,cACzCrX,KAAK0kB,eAAiB,GAAI3mB,IAAGs7B,cACzBt7B,GAAGgT,KAAK/Q,KAAK4zB,iBAAkB5zB,MAE/B,SAASob,GACL,GAAIke,GAAQv3B,EAAKif,YAAYrE,UAAUvB,GAAIA,GAC3C,OAAQke,IAASA,EAAM/c,MAAS,KAK5Cvc,KAAKyjB,kBAAoBzjB,KAAKpB,SAASwrB,WAAWsI,WAItD30B,GAAGq4B,kBAAkB72B,UAAYxB,GAAG2gB,cACpC3gB,GAAGwG,OAAOxG,GAAGq4B,kBAAkB72B,UAAWxB,GAAGuoB,mBCnTjDvoB,GAAGw7B,cAAgB,SAASvgB,GACxB,YA2CA,SAASwgB,KACL,MAAOz7B,IAAG6J,SAAS,MAAO,OAAQ,QAAS7K,EAAQoqB,SAAW,EAMlE,QAASsS,GAAyBxU,GAC9B,GAAIyU,IAAoB,CASxB,OAPA37B,IAAGY,KAAK+6B,EAAmB,SAAS/5B,EAAKg6B,GACrC,GAAI57B,GAAG6J,SAAS,SAAU,kBAAmB,mBAAoB,gBAAiB+xB,GAAU,EAExF,MADAD,IAAoB,GACb,IAIRA,EAGX,QAASE,GAAMnlB,GAEX,MAAO1X,GAAQ4qB,KAAKoI,UAAoC1xB,SAAxBoW,EAAIC,gBAIxC,QAASmlB,KACL,GAAI9R,EAeJ,QAbI5gB,OAAOqE,gBAAkBrE,OAAOsE,iBAChCsc,EAAWhqB,GAAGuN,oBAEmBjN,SAA7B0pB,EAASrT,kBACTqT,EAAW,GAAInT,gBAEfmT,EAAS3a,OAAS,aAClB2a,EAASza,QAAU,aACnBya,EAAS+R,UAAY,aACrB/R,EAASgS,WAAa,eAIvBhS,EAIX,QAASiS,GAAY5e,EAAI6e,GACrB,GAAIlS,GAAWmS,EAAY9e,GAAI3G,GAkB/B,OAhBKsT,KAEGA,EADAkS,EACWA,EAGPl9B,EAAQ4qB,KAAKoI,SACF8J,IAGA97B,GAAGuN,oBAItB4uB,EAAY9e,GAAI3G,IAAMsT,GAGnBA,EAIX,QAASoS,GAAQ/e,GACb,GAEIgf,GAFAxoB,EAAI7T,GAAG6J,QAAQyyB,EAAOjf,GACtB4R,EAAMjwB,EAAQqqB,qBAGX8S,GAAY9e,GACnBif,EAAMpd,OAAOrL,EAAG,GAEZyoB,EAAMj4B,QAAU4qB,GAAOpb,EAAIob,IAC3BoN,EAASC,EAAMrN,EAAM,GACrBsN,EAAYF,IAIpB,QAAS9O,GAAWlQ,EAAImf,GACpB,GAAI9lB,GAAMulB,EAAY5e,GAClB+L,EAASpqB,EAAQoqB,OACjBa,EAAUuS,KAAa,CAE3BJ,GAAQ/e,GAEJ4M,EACA7nB,EAAIgnB,EAAS,gBAAkB/L,EAAK,cAAe,SAE7Cwe,EAAMnlB,IAAS+lB,EAAqB/lB,EAAIiH,UAC9CsM,GAAU,EACV7nB,EAAIgnB,EAAS,gBAAkB/L,EAAK,+BAAiC3G,EAAIiH,OAAQ,UAGrF3e,EAAQuuB,WAAWlQ,EAAI3G,EAAKuT,GAGhC,QAASyS,GAAUrf,GACf,GAEI7d,GAFAm9B,EAAiBR,EAAY9e,GAAIuf,iBACjCC,EAAiB79B,EAAQ69B,cAqB7B,OAlBI79B,GAAQ0qB,YAAY3E,MACpBvlB,EAASR,EAAQ0qB,YAAY3E,IAAI1H,IAGjCsf,GACA38B,GAAGY,KAAK+7B,EAAgB,SAAS37B,EAAMZ,GACnCZ,EAASA,MACTA,EAAOwB,GAAQZ,IAInBy8B,GACA78B,GAAGY,KAAKi8B,EAAgB,SAAS77B,EAAMZ,GACnCZ,EAASA,MACTA,EAAOwB,GAAQZ,IAIhBZ,EAGX,QAAS+8B,GAAYlf,EAAIyf,GACrB,GAIIC,GAJArmB,EAAMulB,EAAY5e,EAAIyf,GACtB1T,EAASpqB,EAAQoqB,OACjB5pB,EAASk9B,EAAUrf,GACnB2f,EAAUb,EAAY9e,GAAI2f,OA+C9B,OA5CAh+B,GAAQi+B,OAAO5f,GAEf0f,EAAMG,EAAU7f,EAAI7d,EAAQ28B,EAAY9e,GAAI8f,uBAGxCtB,EAAMnlB,IACNA,EAAIrH,OAAS+tB,EAAkB/f,GAC/B3G,EAAInH,QAAU8tB,EAAmBhgB,IAGjC3G,EAAI4mB,mBAAqBC,EAA8BlgB,GAG3DmgB,EAA0BngB,GAG1B3G,EAAI+mB,KAAKrU,EAAQ2T,GAAK,GAIlB/9B,EAAQ4qB,KAAKoI,UAAYhzB,EAAQ4qB,KAAK6Q,kBAAoBoB,EAAMnlB,KAChEA,EAAIC,iBAAkB,GAG1B+mB,EAAWrgB,GAEXjb,EAAI,WAAagnB,EAAS,gBAAkB/L,GAExC2f,EACAtmB,EAAIinB,KAAKX,GAEJY,IAAgCp+B,EACrCkX,EAAIinB,OAECn+B,GAAUR,EAAQ6+B,aAAe7+B,EAAQ6+B,YAAY99B,cAAc8J,QAAQ,sCAAwC,EACxH6M,EAAIinB,KAAK39B,GAAGqT,QAAQ7T,EAAQ,KAEvBA,GAAUR,EAAQ6+B,aAAe7+B,EAAQ6+B,YAAY99B,cAAc8J,QAAQ,qBAAuB,EACvG6M,EAAIinB,KAAKjpB,KAAKopB,UAAUt+B,IAGxBkX,EAAIinB,KAAKn+B,GAGNkX,EAGX,QAASwmB,GAAU7f,EAAI7d,EAAQ29B,GAC3B,GAAIrc,GAAW9hB,EAAQ2qB,cAAc5E,IAAI1H,GACrC0gB,EAAY5B,EAAY9e,GAAI0gB,SAehC,OAZiBz9B,SAAby9B,IACAjd,GAAY,IAAMid,GAGlBH,GAA+Bp+B,IAC/BshB,EAAW9gB,GAAGqT,QAAQ7T,EAAQshB,IAG9Bqc,IACArc,EAAW9gB,GAAGqT,QAAQ8pB,EAAuBrc,IAG1CA,EAKX,QAASyc,GAA8BlgB,GACnC,MAAO,YACgC,IAA/B4e,EAAY5e,GAAI2gB,YAChBzQ,EAAWlQ,IAKvB,QAASmgB,GAA0BngB,GAC/B,GAAI8P,GAAanuB,EAAQmuB,UAErBA,KACA8O,EAAY5e,GAAI7P,OAAOwuB,WAAa,SAAS3pB,GACrCA,EAAE4rB,kBACF9Q,EAAW9P,EAAIhL,EAAE+a,OAAQ/a,EAAEgb,SAQ3C,QAAS+P,GAAkB/f,GACvB,MAAO,YACHkQ,EAAWlQ,IAMnB,QAASggB,GAAmBhgB,GACxB,MAAO,YACHkQ,EAAWlQ,GAAI,IAIvB,QAASqgB,GAAWrgB,GAChB,GAAI3G,GAAMulB,EAAY5e,GAClBoM,EAAgBzqB,EAAQyqB,cACxByU,EAAkB/B,EAAY9e,GAAI8gB,sBAClC/U,EAASpqB,EAAQoqB,OACjBgV,IAGCvC,GAAMnlB,KACP1X,EAAQq/B,cAAgB3nB,EAAI4nB,iBAAiB,SAAUt/B,EAAQq/B,cAG3Dr/B,EAAQu/B,qCAKHv/B,EAAQ4qB,KAAKoI,UAAcyJ,MAAoBC,EAAyBjS,KACzE/S,EAAI4nB,iBAAiB,mBAAoB,kBACzC5nB,EAAI4nB,iBAAiB,gBAAiB,eAI1Ct/B,EAAQ6+B,aAA2B,SAAXzU,GAAgC,QAAXA,GAC7C1S,EAAI4nB,iBAAiB,eAAgBt/B,EAAQ6+B,aAGjD79B,GAAGwG,OAAO43B,EAAYp+B,GAAG0K,WAAW+e,GAAiBA,EAAcpM,GAAMoM,GACzEzpB,GAAGwG,OAAO43B,EAAYF,GAEtBl+B,GAAGY,KAAKw9B,EAAY,SAASp9B,EAAMZ,GAC/BsW,EAAI4nB,iBAAiBt9B,EAAMZ,MAKvC,QAASq8B,GAAqB+B,GAC1B,MAAOx+B,IAAG6J,QAAQ7K,EAAQy/B,wBAAwBz/B,EAAQoqB,QAASoV,IAAiB,EAGxF,QAASE,GAAcrhB,EAAIyf,EAAQiB,EAAWnB,EAAkBO,EAAuBgB,EAAmBnB,GACtGb,EAAY9e,IACR0gB,UAAWA,EACXnB,iBAAkBA,EAClBO,sBAAuBA,EACvBgB,kBAAmBA,EACnBnB,QAASA,EAGb,IAAI3sB,GAAMisB,EAAMx6B,KAAKub,EAGrB,IAAIhN,GAAOrR,EAAQqqB,eACf,MAAOkT,GAAYlf,EAAIyf,GA7U/B,GAAI16B,GAAKw7B,EACLtB,KACAH,KACAn9B,GACIq/B,aAAc,KACdM,cAAe,QAAS,OAAQ,OAChCvV,OAAQ,OACRyU,YAAa,oCACbxU,eAAgB,EAChBI,iBACAE,iBACAD,eACAmT,kBACA0B,oCAAoC,EACpCE,yBACIG,QAAS,IAAK,IAAK,KACnBC,OAAQ,IAAK,IAAK,IAAK,IAAK,KAC5BC,MAAO,IAAK,IAAK,IAAK,IAAK,KAC3BC,KAAM,IAAK,IAAK,IAAK,IAAK,KAC1BC,KAAM,MAEVpV,MACIoI,UAAU,EACVyI,iBAAiB,GAErBr4B,IAAK,SAASuJ,EAAKvB,KACnB6yB,OAAQ,SAAS5f,KACjBkQ,WAAY,SAASlQ,EAAI2M,EAAUC,KACnCkD,WAAY,KAMpB,IAHAntB,GAAGwG,OAAOxH,EAASic,GACnB7Y,EAAMpD,EAAQoD,IAEVpC,GAAG6J,QAAQ7K,EAAQ2/B,aAAc3/B,EAAQoqB,QAAU,EACnD,KAAM,IAAIjjB,OAAM,IAAMnH,EAAQoqB,OAAS,wDA8S3CwU,GAAiD,QAAnB5+B,EAAQoqB,QAAuC,WAAnBpqB,EAAQoqB,OAElEppB,GAAGwG,OAAOvE,MAENg9B,cAAe,SAAS5hB,GACpB,GAAI6hB,GAAM1/B,EAAQ0nB,EAAS8V,EAASmC,EAAahC,CAEjD,QAEIiC,SAAU,SAASC,GAEf,MADAH,GAAOG,EACAp9B,MAOXq9B,WAAY,SAAS1C,GAEjB,MADAp9B,GAASo9B,EACF36B,MAGXs9B,gBAAiB,SAASC,GAEtB,MADArC,GAAwBqC,EACjBv9B,MAIXw9B,YAAa,SAAStB,GAElB,MADAjX,GAAUiX,EACHl8B,MAIXy9B,YAAa,SAASC,GAElB,MADA3C,GAAU2C,EACH19B,MAIX29B,gBAAiB,WAEb,MADAT,IAAc,EACPl9B,MAIX07B,KAAM,SAASb,GAKX,MAJIqC,IAAen/B,GAAG6J,SAAS,MAAO,UAAW7K,EAAQoqB,SAAW,IAChE5pB,EAAOqgC,aAAc,GAAIC,OAAOC,WAG7BrB,EAAcrhB,EAAIyf,EAAQoC,EAAM1/B,EAAQ29B,EAAuBjW,EAAS8V,MAK3FgD,SAAU,SAAS3iB,GACf+e,EAAQ/e,OC1YpBrd,GAAGigC,cAAgB,SAAS5hB,GACxB,YAEA,IAAI6hB,GAAQ7hB,EAAK6hB,MACbC,KACA1S,EAAWyS,EAAMzS,SACjBtK,EAAU+c,EAAM/c,OAEpBnjB,IAAGwG,OAAOvE,MACN0R,IAAK,SAAS0J,EAAI+iB,GACdD,EAAU9iB,GAAM+iB,EAChBD,EAAU9iB,GAAI9J,SAGlBkP,OAAQ,SAASpF,GACb,GAAIrZ,GAAO/B,KACPyrB,EAA2B,GAAI1tB,IAAGoP,QAClCixB,EAAiB5S,EAASpQ,EAAI8F,EAAQ9F,GAAKqQ,EAE/C2S,GAAenmB,KAAK,WACZlW,EAAKyf,QAAQpG,KACb8iB,EAAU9iB,GAAI2iB,UAAW,EACzBh8B,EAAK+wB,QAAQ1X,IAEjBqQ,EAAyBpe,aAIjCylB,QAAS,SAAS1X,SACP8iB,GAAU9iB,IAGrBijB,oBAAqB,SAASjjB,GAC1B,MAAO8iB,GAAU9iB,GAAIld,KAGzBsjB,QAAS,SAASpG,GACd,MAAyB/c,UAAlB6/B,EAAU9iB,IAGrBN,MAAO,WACHojB,MAGJI,cAAe,SAASljB,GACpB,MAAO8iB,GAAU9iB,IAGrBmjB,qBAAsB,SAASnjB,EAAIojB,GAC/BN,EAAU9iB,GAAIld,IAAMsgC,GAGxBC,aAAc,SAASrjB,GACnB,QAAS8iB,EAAU9iB,GAAI2iB,aCpDnChgC,GAAG6uB,wBAA0B,SAAS5T,EAAGtb,GACrC,YAEA,IAGcghC,GAAsBv+B,EAAK2uB,EAHrC6P,EAAa3+B,KACb4+B,GAAmB,EACnBC,GAA6B,EAGjC9hC,GACI0qB,eACAL,eAAgB,EAChB5Q,UACIyK,SAAS,EACT7V,UACI6V,SAAS,IAGjB9gB,IAAK,SAASuJ,EAAKvB,KACnB+iB,WAAY,SAAS9P,EAAIjI,EAAUgY,EAAQC,KAC3CE,WAAY,SAASlQ,EAAIjI,EAAUse,EAAUhd,KAC7C+W,SAAU,SAASpQ,EAAIjI,KACvBwY,aAAc,SAASvQ,KACvByQ,SAAU,SAASzQ,EAAIjI,KACvB4Y,cAAe,SAAS3Q,EAAIjI,EAAU6Y,KACtCE,qBAAsB,SAAS9Q,EAAI4Q,EAAWyF,EAAUhd,KACxD2X,YAAa,SAAShR,EAAIjI,EAAUse,EAAUhd,KAC9C0X,SAAU,SAAS/Q,EAAIjI,EAAU6Y,KACjCO,cAAe,SAASnR,EAAI+B,KAC5B+D,QAAS,SAAS9F,KAClBoR,QAAS,SAASpR,EAAIoC,KACtBmP,SAAU,SAASvR,KACnBwC,mBAAoB,SAASxC,KAC7ByC,cAAe,SAASzC,MAG5B0jB,GAEIpmB,KAAM,SAAS0C,EAAI2jB,EAAUtN,EAAUhd,GACnC,GAAIuX,GAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,EAE1CjQ,GAAQwP,cAAcljB,GAAI6jB,kBAAmB,QAEtCnQ,GAAQwP,cAAcljB,GAAI9J,KAAK4tB,cAAcH,GACpDjQ,EAAQwP,cAAcljB,GAAI+P,QAAUa,EAAUzP,KAE9Cxf,EAAQmvB,qBAAqB9Q,EAAI0T,EAAQqQ,yBAAyBnT,GAAYyF,EAAUhd,IAK5F2qB,SAAU,SAAShkB,GACf,GAAImB,GAAOxf,EAAQqmB,QAAQhI,GACvBrc,EAAOhC,EAAQmkB,QAAQ9F,EAE3Bjb,GAAI,qCAAuCib,EAAK,qBAChD0T,EAAQuQ,eAAejkB,GAAInD,KACvB,SAASwZ,EAAUhd,GACftU,EAAI,2BAA6Bib,EAEjC,IAAIkkB,GAAoB/zB,EAAOg0B,kBAAkB9N,GAAU,EAE3D10B,GAAQmuB,WAAW9P,EAAIrc,EAAMwd,EAAMA,GACnCuS,EAAQ0Q,+BAA+BpkB,GACvC7P,EAAOk0B,QAAQrkB,EAAIkkB,EAAmB7qB,IAE1C,SAASgd,EAAUhd,GACf,GAAI6qB,GAAoB/zB,EAAOg0B,kBAAkB9N,GAAU,EAE3DtxB,GAAI,yCAA2Cib,EAAK,MAAQkkB,EAAkBp/B,MAAO,SAEjFo/B,EAAkBxkB,OAClBgkB,EAAQhkB,MAAMM,GAGbre,EAAQqvB,YAAYhR,EAAIrc,EAAMugC,EAAmB7qB,IAClDlJ,EAAOk0B,QAAQrkB,EAAIkkB,EAAmB7qB,MAMtDirB,cAAe,SAASX,EAAU3jB,EAAIqW,EAAUhd,GAC5C,GAAI1V,GAAOhC,EAAQmkB,QAAQ9F,EAE3Bjb,GAAI,qCAAuCib,EAAK,WAAa2jB,GAE7DjQ,EAAQ6Q,iBAAiBvkB,EAAI2jB,EAE7B,IACIa,GADAC,EAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,EAGtDoO,GAAiB/kB,MACjBgkB,EAAQhkB,MAAMM,IAGdwkB,EAAgB7hC,GAAG6J,QAAQknB,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAYf,GACtEa,GAAiB,IACjB9Q,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAW7iB,OAAO2iB,EAAe,GACpE9Q,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAUC,QAAQjB,KAMxDjQ,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,gBAG5BpB,IACA/P,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,eAAgB,EAE/C9/B,EAAIpC,GAAG0L,OAAO,mFAAoFgJ,KAAKopB,UAAUtzB,OAAO23B,KAAKpR,EAAQqR,SAAS/kB,KAAO3I,KAAKopB,UAAU/M,EAAQwP,cAAcljB,GAAI5E,SAASspB,cACvM/hC,GAAGY,KAAKmwB,EAAQqR,SAAS/kB,GAAK,SAASglB,EAAMC,GACzClgC,EAAIpC,GAAG0L,OAAO,sDAAuD2R,EAAIglB,EAAMC,EAAMtE,aACrFsE,EAAMC,QAGND,EAAME,YAAa,IAIvBzR,EAAQ0R,0BAA0BplB,GAIlCqlB,EAAkBC,KAAKtlB,GAAI,IAG1Bre,EAAQqvB,YAAYhR,EAAIrc,EAAM8gC,EAAkBprB,IAIjDlJ,EAAOk0B,QAAQrkB,EAAIykB,EAAkBprB,KAKjDksB,aAAc,SAASvlB,GACnB,QAAS0T,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAU39B,QAG1Dw+B,SAAU,SAASxlB,GACf,GAAIylB,GAAU/R,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAUvsB,OAM3D,OAJIqtB,IAAW/R,EAAQgS,gBAAgB1lB,KACnCylB,EAAU,MAGPA,GAGX/lB,MAAO,SAASM,GACZjb,EAAI,8FAAgGib,EAAI,SAExG0T,EAAQ0Q,+BAA+BpkB,GACvC0T,EAAQiS,mBAAmB3lB,GAC3B0T,EAAQwP,cAAcljB,GAAI+P,OAAS,GAGvC6V,SAAU,SAAS5lB,GACf,GAAImB,GAAOxf,EAAQqmB,QAAQhI,GACvBrc,EAAOhC,EAAQmkB,QAAQ9F,GACvB2jB,EAAWD,EAAQ8B,SAASxlB,GAC5B4Q,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCzG,EAAWxJ,EAAQwP,cAAcljB,GAAI6jB,iBACrCgC,EAAmBnS,EAAQwP,cAAcljB,GAAI5E,SAASspB,cAElB,OAApChR,EAAQwP,cAAcljB,GAAI+P,SAC1B2D,EAAQwP,cAAcljB,GAAI+P,OAAS,GAInCmN,GAAYv7B,EAAQovB,SAAS/Q,EAAIrc,EAAMitB,MAAe,IACtD8S,EAAQhkB,MAAMM,GACd2jB,EAAWD,EAAQ8B,SAASxlB,GAC5B4Q,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCzG,GAAW,GAIC,MAAZyG,GAAgD,IAA5BkC,EAAiB7+B,OACrC08B,EAAQM,SAAShkB,IAKjBjb,EAAIpC,GAAG0L,OAAO,oEAAqE2R,EAAI2jB,EAAU/S,EAAU5f,MAAQ,EAAG4f,EAAU3f,IAAKkQ,IACrIxf,EAAQgvB,cAAc3Q,EAAIrc,EAAM+vB,EAAQqQ,yBAAyBnT,IACjEiV,EAAiBphC,KAAKk/B,GACtBjQ,EAAQwP,cAAcljB,GAAI5E,SAASspB,WAAamB,EAE5CpC,GACA4B,EAAkBjF,KAAKpgB,EAAI2jB,GAG3BF,GAA8B4B,EAAkBS,aAAepS,EAAQwP,cAAcljB,GAAI5E,SAASupB,UAAU39B,QAC5G08B,EAAQkC,SAAS5lB,GAGO,IAAxB4Q,EAAUnf,KAAK0P,MACfpc,EAAIpC,GAAG0L,OAAO,+DAAgEs1B,EAAU3jB,GAAK,SAC7F0jB,EAAQY,cAAcX,EAAU3jB,EAAI,8BAA+B,OAGnE0T,EAAQqS,YAAY/lB,EAAI2jB,EAAUzG,GAAUrgB,KAExC,SAAiBwZ,EAAUhd,GACvBtU,EAAI,wCAA0Cib,EAAK,WAAa2jB,GAEhEjQ,EAAQ6Q,iBAAiBvkB,EAAI2jB,EAE7B,IAAIkC,GAAmBnS,EAAQwP,cAAcljB,GAAI5E,SAASspB,eACtDD,EAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,GACtD2P,EAAqBrjC,GAAG6J,QAAQq5B,EAAkBlC,EAEtD5+B,GAAIpC,GAAG0L,OAAO,8CAA+Cs1B,EAAU3jB,IAEvE0jB,EAAQpmB,KAAK0C,EAAI2jB,EAAUc,EAAkBprB,GAEzC2sB,GAAsB,GACtBH,EAAiBhkB,OAAOmkB,EAAoB,GAGhDtS,EAAQuS,0BAA0BjmB,GAE7B0jB,EAAQ6B,aAAavlB,IAAmC,IAA5B6lB,EAAiB7+B,OAGzC08B,EAAQ6B,aAAavlB,GAC1B0jB,EAAQkC,SAAS5lB,GAGjBjb,EAAIpC,GAAG0L,OAAO,oGAAqG2R,EAAI3I,KAAKopB,UAAUoF,KANtInC,EAAQM,SAAShkB,IAWzB,SAAiBqW,EAAUhd,GACvBqqB,EAAQY,cAAcX,EAAU3jB,EAAIqW,EAAUhd,KAGjDiE,KAAK,WACFoW,EAAQwS,SAASlmB,EAAI2jB,QAO7C0B,GACIc,SACAC,eACAC,YAEAP,UAAW,WACP,GAAIlU,GAAMjwB,EAAQqqB,eACdsa,EAAwB,EACxBC,EAAkB,CAOtB,OALA5jC,IAAGY,KAAK8hC,EAAkBe,YAAa,SAAS9f,EAAQkgB,GACpDF,IACAC,GAAmBC,EAAiBx/B,SAGjC4qB,GAAOyT,EAAkBc,MAAMn/B,OAASs/B,EAAwBC,IAM3EjB,KAAM,SAAStlB,EAAIymB,GACf,GAGIzH,GAHA0H,GAAaD,EACbE,EAAehkC,GAAG6J,QAAQ64B,EAAkBgB,SAAUrmB,GACtD4mB,EAAmBjkC,GAAG6J,QAAQ64B,EAAkBc,MAAOnmB,SAGpDqlB,GAAkBe,YAAYpmB,GAEjC7P,EAAO02B,eAAe7mB,YAAerd,IAAG4a,YACxCxY,EAAI,uCAAyCib,EAAK,qCAC3C0T,GAAQwP,cAAcljB,GAAIgF,MAIjC2hB,GAAgB,EAChBtB,EAAkBgB,SAASxkB,OAAO8kB,EAAc,GAG3CD,GAAaE,GAAoB,IACtCvB,EAAkBc,MAAMtkB,OAAO+kB,EAAkB,GAEjD5H,EAASqG,EAAkBgB,SAASjuB,QAChC4mB,GAAU,IACVqG,EAAkBc,MAAM1hC,KAAKu6B,GAC7B7uB,EAAOa,MAAMguB,MAKzB8H,sBAAuB,WACnB,GAAIC,KAqBJ,OAjBApkC,IAAGY,KAAK8hC,EAAkBe,YAAa,SAAS9f,EAAQ0gB,GAChDA,GAAUA,EAAOhgC,QACjB+/B,EAAmBtiC,KAAKwiC,SAAS3gB,MAMzC3jB,GAAGY,KAAK8hC,EAAkBc,MAAO,SAAS5hC,EAAK+hB,GACtC+e,EAAkBe,YAAY9f,IAC/BygB,EAAmBtiC,KAAKwiC,SAAS3gB,MAKzCygB,EAAqBA,EAAmBhxB,OAAOsvB,EAAkBgB,WAKrEa,kBAAmB,SAASlnB,GACxB,MAAOrd,IAAG6J,QAAQ64B,EAAkBc,MAAOnmB,IAAO;EAGtDogB,KAAM,SAASpgB,EAAI2jB,GAKf,MAJgB,OAAZA,GACA0B,EAAkBgB,SAAS5hC,KAAKub,KAGhCqlB,EAAkBS,cACF,MAAZnC,GACA0B,EAAkBgB,SAASc,MAC3B9B,EAAkBc,MAAM1hC,KAAKub,KAG5B,WACG,GAAIonB,GAAkB/B,EAAkBe,YAAYpmB,MACpDonB,GAAgB3iC,KAAKk/B,GACrB0B,EAAkBe,YAAYpmB,GAAMonB,MAIrC,IAMf1nB,MAAO,WACH2lB,EAAkBgB,YAClBhB,EAAkBc,WAI1BkB,GACI/G,KAAM,SAAStgB,EAAIrc,GACf+vB,EAAQwP,cAAcljB,GAAI+P,OAAS,EAEnChrB,EAAI,qCAAuCib,GAC3C0T,EAAQ4T,WAAWtnB,GAAInD,KACnB,SAASwZ,EAAUoJ,GACf16B,EAAI,uCAAyCib,EAE7C,IAAIykB,GAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,GACtDlV,EAAOxf,EAAQqmB,QAAQhI,EAE3Bre,GAAQmuB,WAAW9P,EAAIrc,EAAMwd,EAAMA,GACnChR,EAAOo3B,aAAavnB,EAAIykB,GACxBt0B,EAAOk0B,QAAQrkB,EAAIykB,EAAkBhF,IAGzC,SAASpJ,EAAUoJ,GACf16B,EAAI,oCAAsCib,EAE1C,IAAIykB,GAAmBt0B,EAAOg0B,kBAAkB9N,GAAU,EAErD10B,GAAQqvB,YAAYhR,EAAIrc,EAAM8gC,EAAkBhF,IACjDtvB,EAAOk0B,QAAQrkB,EAAIykB,EAAkBhF,OAOzDtvB,GACIiV,OAAQ,SAASpF,GACbjb,EAAI,cAAgBib,GACpBre,EAAQ0qB,YAAY3jB,OAAOsX,GAC3BqlB,EAAkBC,KAAKtlB,IAG3BqkB,QAAS,SAASrkB,EAAIqW,EAAUoJ,GAC5B,GAAI97B,GAAOhC,EAAQmkB,QAAQ9F,EAE3Bre,GAAQuuB,WAAWlQ,EAAIrc,EAAM0yB,EAAUoJ,GAEnC/L,EAAQwP,cAAcljB,IACtB0T,EAAQ8T,YAAc9T,EAAQ8T,WAAWxnB,GAG7CqlB,EAAkBC,KAAKtlB,IAK3B6mB,eAAgB,SAAS7mB,GACrB,MAAQ0T,GAAQ+T,UAAY/T,EAAQ+T,SAASznB,IACxC0T,EAAQ1M,SAAW0M,EAAQ1M,QAAQhH,IAG5C0nB,YAAa,WACT,GAAIC,GAAcrlC,EAAYK,GAAGL,GAAaK,GAAGilC,YAC7CC,EAAuBllC,GAAGiW,kBAAkBqC,cAAgB,MAAQ,MAExEyY,GAAU,GAAIiU,GAAYE,EAAuB,iBAC7ClmC,GAEI2vB,cAAe3vB,EAAQ2vB,cACvBxL,QAASnkB,EAAQmkB,QACjBkC,QAASrmB,EAAQqmB,QACjBO,QAAS5mB,EAAQ4mB,QACjBxjB,IAAKA,EACLqrB,SAAUzuB,EAAQyuB,SAClBN,WAAYnuB,EAAQmuB,WACpBqB,cAAexvB,EAAQwvB,gBAI3BuC,EAAQoU,+BACRpU,EAAQoU,iCAIhBC,4BAA6B,SAAS/nB,GAClC,MAAOre,GAAQ4vB,SAASvR,IAM5BgoB,WAAY,SAAShoB,EAAIvO,GAIrB,MAAIA,KAASiiB,EAAQ1M,QAAQhH,IAAOvO,YAAgB9O,IAAG4a,WAKnD5b,EAAQ4uB,aAAavQ,GAErBjb,EAAI,+CAAiDib,GACrDvO,EAAKiM,SAASb,KAAK,SAASorB,GACxBljC,EAAI,mCAAqCib,GAGzC0T,EAAQwU,WAAWloB,EAAIioB,GAGvBtmC,EAAQyvB,QAAQpR,EAAIioB,EAAc9mB,MAGlCuS,EAAQiS,mBAAmB3lB,GAE3B7P,EAAOg4B,uBAAuBnoB,IAIlC,SAAS6Y,GACL,GAAIuP,KAEAvP,KACAuP,EAActjC,MAAQ+zB,GAG1B9zB,EAAIpC,GAAG0L,OAAO,yDAA0D2R,EAAI6Y,GAAe,SAE3Fl3B,EAAQuuB,WAAWlQ,EAAIre,EAAQmkB,QAAQ9F,GAAKrd,GAAGwG,OAAOi/B,EAAe9E,GAAuB,MAC5FnzB,EAAOg4B,uBAAuBnoB,GAC9BqlB,EAAkBC,KAAKtlB,MAOxB,GAHI7P,EAAOg4B,uBAAuBnoB,IAO7CmoB,uBAAwB,SAASnoB,GAC7B,GAAIqoB,GAAa1mC,EAAQ6gB,mBAAmBxC,GACxCsoB,GAAiB,CAoBrB,OAlBID,IAAcA,EAAWrhC,QACzBjC,EAAI,0CAA4Cib,GAEhDrd,GAAGY,KAAK8kC,EAAY,SAAS9jC,EAAKgkC,GAC9B,GAAIp4B,EAAO43B,4BAA4BQ,IAAgB7U,EAAQ1M,QAAQuhB,GACnED,EAAiBC,IAAcvoB,EAC/B7P,EAAOq4B,IAAID,OAEV,IAAIp4B,EAAO43B,4BAA4BQ,GACxC,OAAO,MAKfD,GAAiB,EACjBn4B,EAAOq4B,IAAIxoB,IAGRsoB,GAGXf,aAAc,SAASvnB,EAAIqW,GACEpzB,SAArBozB,EAAStU,SACTpgB,EAAQwvB,cAAcnR,EAAIqW,EAAStU,UAO3CoiB,kBAAmB,SAASsE,EAAkB1R,GAC1C,GAAIV,GAAWoS,CAcf,OAVK9lC,IAAGsK,SAASw7B,KACbpS,KAEI1zB,GAAGoL,SAAS06B,KAAsB1R,IAClCV,EAASvxB,MAAQ2jC,IAIzBpS,EAASpkB,QAAU8kB,EAEZV,GAGXmS,IAAK,SAASxoB,GACV,GAAIrc,GAAOhC,EAAQmkB,QAAQ9F,EAE3B,KAAKujB,EAAWnd,QAAQpG,GACpB,KAAM,IAAIrd,IAAGmG,MAAMkX,EAAK,qCAG5Bre,GAAQ8uB,SAASzQ,EAAIrc,GAEjB6/B,GAAoB9P,EAAQgV,qBAAqB1oB,GACjD0jB,EAAQkC,SAAS5lB,GAGjBqnB,EAAO/G,KAAKtgB,EAAIrc,IAIxBqN,MAAO,SAASgP,GACZ,GAAI2oB,GAAex4B,EAAO02B,eAAe7mB,EAEzC,OAAI2oB,GACOx4B,EAAO63B,WAAWhoB,EAAI2oB,IAG7Bx4B,EAAOq4B,IAAIxoB,IACJ,IAKnBrd,IAAGwG,OAAOvE,MAIN0R,IAAK,SAAS0J,EAAIgF,GACd0O,EAAQpd,IAAI3R,MAAMC,KAAMP,YAM5B8L,OAAQ,SAAS6P,GACb,QAAIqlB,EAAkBjF,KAAKpgB,IAChB7P,EAAOa,MAAMgP,IAK5BuJ,MAAO,SAASvJ,GAWZ,MANIyjB,KACA/P,EAAQwP,cAAcljB,GAAI9J,KAAK2uB,eAAgB,GAK/CQ,EAAkB6B,kBAAkBlnB,GAC7B7P,EAAOa,MAAMgP,GAObujB,EAAWpzB,OAAO6P,IAOjCoF,OAAQ,SAASpF,GACb,GAAI4oB,GAAelV,EAAQtO,OAAOpF,EAE9Brd,IAAGga,iBAAiBisB,GACpBA,EAAa/rB,KAAK,WACd1M,EAAOiV,OAAOpF,KAGb4oB,KAAiB,GACtBz4B,EAAOiV,OAAOpF,IAOtBsF,UAAW,WACP,GACI9O,GADAuwB,EAAqB1B,EAAkByB,uBAK3C,IAAIC,EAAmB//B,OACnB,IAAKwP,EAAIuwB,EAAmB//B,OAAS,EAAGwP,GAAK,EAAGA,IAC5C+sB,EAAWne,OAAO2hB,EAAmBvwB,GAI7C6uB,GAAkB3lB,SAKtBsH,QAAS,SAAShH,GACd,MAAI0T,GAAQ+T,UAAY/T,EAAQ+T,SAASznB,GAC9B0T,EAAQ+T,SAASznB,GAAIxC,cAGzBkW,EAAQ1M,SAAW0M,EAAQ1M,QAAQhH,IAI9C6oB,UAAW,SAAS7oB,GAChB,SAAU0T,EAAQ+T,WAAY/T,EAAQ+T,SAASznB,KAGnDZ,SAAU,SAASY,GACf,GAAI0T,EAAQtU,SACR,MAAOsU,GAAQtU,SAASY,IAIhCN,MAAO,WACH3a,EAAI,4BACJw+B,EAAWje,YACX+f,EAAkB3lB,QAClBgU,EAAQhU,SAGZgY,QAAS,SAAS1X,GACd,GAAIujB,EAAWnd,QAAQpG,GACnB,MAAO0T,GAAQgE,QAAQ1X,IAO/BoG,QAAS,SAASpG,GACd,MAAO0T,GAAQtN,QAAQpG,IAG3B+H,sBAAuB,WACnB,MAAI2L,GAAQ3L,sBACD2L,EAAQ3L,4BAavBkb,oBAAqB,SAASjjB,GAC1B,GAAIujB,EAAWnd,QAAQpG,GACnB,MAAO0T,GAAQuP,oBAAoBjjB,IAS3ChE,MAAO,SAASgE,GACZ,SAAIujB,EAAWuF,YAAY9oB,IAAO0T,EAAQ1X,OAASunB,EAAWnd,QAAQpG,IAAO0T,EAAQ1X,MAAMgE,MACvFqlB,EAAkBC,KAAKtlB,GACvB0T,EAAQ0R,0BAA0BplB,IAC3B,IAMf8oB,YAAa,SAAS9oB,GAClB,QAAS0T,EAAQoV,aAAepV,EAAQoV,YAAY9oB,MAI5Drd,GAAGwG,OAAOxH,EAASic,GACnB7Y,EAAMpD,EAAQoD,IACdy+B,EAAmB7hC,EAAQyZ,SAASyK,SAAWljB,GAAGiW,kBAAkBwC,SACpEqoB,EAA6BD,GAAoB7hC,EAAQyZ,SAASohB,WAAW3W,QAE7Eyd,EAAwB,WACpB,GAAIjN,KAIJ,OAFAA,GAAS10B,EAAQiuB,oBAAqB,EAE/ByG,KAGXlmB,EAAOu3B,eC9uBX/kC,GAAGomC,qBAAuB,SAASnrB,GAC/B,YAEA,IAAIjc,IACIoD,IAAK,SAASC,EAAS+H,MAE3Bi8B,IAEJrmC,IAAGwG,OAAOxH,EAASic,GAEnBjb,GAAGwG,OAAOvE,MACNqkC,eAAgB,SAASjpB,EAAIzK,GACzB,GAAI2zB,GAA2B,SAAS7P,GAChC9jB,EAAS8jB,EAAMr2B,MAGnB+I,QAAOiP,YACPguB,EAAyBhpB,GAAMrd,GAAGoJ,QAAQjE,OAAO,UAAWohC,GAG5DnkC,IAAI,wDAAyD,UAIrEokC,sBAAuB,SAASnpB,GAC5B,GAAIjU,OAAOiP,YAAa,CACpB,GAAIouB,GAAWJ,EAAyBhpB,EACpCopB,IACAA,SCvBpBzmC,GAAG0mC,kBAAoB,SAASroB,GAC5B,YAoBA,SAASsoB,GAAYtpB,SACVupB,GAAiBvpB,GAKpBwpB,IACAhS,aAAaiS,EAA0BzpB,UAChCypB,GAA0BzpB,GACjC0pB,EAAoBP,sBAAsBnpB,GAG9C,IAAI2pB,GAAS75B,SAAS85B,eAAelW,EAAQmW,eAAe7pB,GACxD2pB,KAIAA,EAAO1yB,aAAa,MAAO,qBAE3BtU,GAAGgnC,GAAQjhC,UAQnB,QAASohC,GAAuBC,GAC5B,MAAOA,GAAWx9B,MAAM,KAAK,GAUjC,QAASy9B,GAAoBrmC,GACzB,GAAIgmC,GAAShnC,GAAGuS,UAAU,yCAA2CvR,EAAO,OAO5E,OALAgmC,GAAO1yB,aAAa,KAAMtT,GAE1BgmC,EAAO/hC,MAAMC,QAAU,OACvBiI,SAASm6B,KAAK/yB,YAAYyyB,GAEnBA,EAUX,QAASO,GAA4BP,EAAQp0B,GACzC,GAAIw0B,GAAaJ,EAAO3pB,GACpBsG,EAASwjB,EAAuBC,GAChC5pB,EAAOoI,EAAQjC,EAEnB6jB,GAAgBhqB,GAAQ5K,EAIxBg0B,EAAiBjjB,GAAU3jB,GAAGgnC,GAAQ7hC,OAAO,OAAQ,WAC7C4rB,EAAQtU,SAASkH,KACjBvhB,EAAI,mEAAqEglC,EAAa,KAEtFN,EAA0BM,GAAcvb,WAAW,WAC/C,GAAIqK,GAAe,gEAAkEkR,CACrFhlC,GAAI8zB,EAAc,SAClBtjB,GACIzQ,MAAO+zB,KAEZ,QAMX6Q,EAAoBT,eAAec,EAAY,SAAS/kC,GACpDD,EAAI,2CAA6CC,EAAU,IAC3D,IAGIolC,GAFA/T,GADSyT,EAAuBC,GACrBrW,EAAQ2W,mBAAmBrlC,IACtCmb,EAAOkW,EAASlW,IAGhBA,IAAQgqB,EAAgBhqB,IACxBpb,EAAI,qCAAuCglC,GAC3CvS,aAAaiS,EAA0BM,UAChCN,GAA0BM,GAEjCrW,EAAQ4W,iBAAiBP,GAEzBK,EAAiBD,EAAgBhqB,SAE1BgqB,GAAgBhqB,GACvBupB,EAAoBP,sBAAsBY,GAC1CK,EAAe/T,IAETlW,GACNpb,EAAI,IAAMC,EAAU,2CAxHhC,GAAIrD,GAAUqf,EAAKrf,QACf+xB,EAAU9uB,KACVi+B,EAAQ7hB,EAAK6hB,MACb0H,EAAwB5nC,GAAGuQ,cAC3Bi3B,KACAZ,KACAE,KACAD,EAAS7nC,EAAQ6nC,OACjBna,EAAY1tB,EAAQ0tB,UACpB9G,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,IACZ2kC,EAAsB,GAAI/mC,IAAGomC,sBAAsBhkC,IAAKA,GAkH5DpC,IAAGwG,OAAOvE,KAAM,GAAIjC,IAAGigC,cAAc5hB,IAErCre,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OAII4D,IAAK,SAAS0J,EAAIwS,GACd9f,EAAO4D,IAAI0J,GAAKnQ,MAAO2iB,IAEvBA,EAAUvb,aAAa,OAAQoY,GAG3BmD,EAAU/pB,YACV9F,GAAG6vB,GAAW9pB,UAItBgvB,QAAS,SAAS1X,GACdspB,EAAYtpB,GACZtN,EAAOglB,QAAQ1X,IAGnBoG,QAAS,SAASpG,GACd,MAAOtN,GAAO0T,QAAQpG,IACkB/c,SAApCywB,EAAQwP,cAAcljB,GAAInQ,UAK1ClN,GAAGwG,OAAOvE,MACNwa,SAAU,SAASY,GACf,MAAO0T,GAAQwP,cAAcljB,GAAInQ,OAWrC26B,iBAAkB,SAASb,EAAQp0B,GAE/B,GAAIk1B,EAEAjB,GACAU,EAA4BP,EAAQp0B,GAGpCg0B,EAAiBI,EAAO3pB,IAAMrd,GAAGgnC,GAAQ7hC,OAAO,OAAQ,WAMpD,GALA/C,EAAI,yBAA2B4kC,EAAO3pB,IAKjC2pB,EAAOlhC,WAAZ,CAIA,IAEI,GAAIkhC,EAAOe,iBACPf,EAAOe,gBAAgBT,MACkB,SAAzCN,EAAOe,gBAAgBT,KAAK50B,UAK5B,OAGR,MAAOvQ,GAEHC,EAAI,8EAAgFD,EAAME,QAAU,IAAK,SACzGylC,GAAsBx4B,SAAS,GAGnCsD,EAASk1B,OAWrBE,cAAe,SAAS3qB,GACpB,GAAI+pB,GAAarW,EAAQmW,eAAe7pB,EAExC,OAAOgqB,GAAoBD,IAQ/BO,iBAAkB,SAAStqB,GACM/c,SAAzBsmC,EAAiBvpB,KACjBupB,EAAiBvpB,WACVupB,GAAiBvpB,KAQhC6pB,eAAgB,SAASvjB,GACrB,MAAOA,GAAS,IAAMikB,GAY1BK,mBAAoB,SAAS5pB,GACzB,GAAI+K,GAAS/K,EAAK+K,OACdtI,EAAWzC,EAAKyC,SAChBthB,EAAS6e,EAAK7e,OACdi5B,EAAepa,EAAKoa,aACpByP,EAAa7pB,EAAK6pB,WAClB7zB,EAAOrU,GAAGuS,UAAU,iBAAmB6W,EAAS,2CAChD2T,EAAMjc,CAcV,OAZI2X,GACAz4B,GAAGoU,WAAW5U,EAAQ6U,GAGtB0oB,EAAM/8B,GAAGqT,QAAQ7T,EAAQshB,GAG7BzM,EAAKC,aAAa,SAAUyoB,GAC5B1oB,EAAKC,aAAa,SAAU4zB,GAC5B7zB,EAAKpP,MAAMC,QAAU,OACrBiI,SAASm6B,KAAK/yB,YAAYF,GAEnBA,GAOXqzB,mBAAoB,SAASS,GACzB,GAAIzU,KAEJ,KACIA,EAAW1zB,GAAGwU,UAAU2zB,GAE5B,MAAOhmC,GACHC,EAAI,0DAA4DD,EAAME,QAAU,IAAK,SAGzF,MAAOqxB,OCnSnB1zB,GAAGooC,iBAAmB,SAAS/pB,GAC3B,YAkBA,SAASkkB,GAAMllB,GACXrd,GAAGY,KAAKmwB,EAAQqR,SAAS/kB,GAAK,SAASgrB,EAAO3xB,GAC1C,GAAI4xB,GAAgBvX,EAAQwX,kBAAkBlrB,EAAIgrB,EAElD3xB,GAAI4mB,mBAAqB,KACzB5mB,EAAIlJ,OAAOwuB,WAAa,KACxBtlB,EAAI6rB,QACJ+F,GAAiBA,EAActI,UAAYsI,EAActI,SAAS3iB,KAvB1E,GAAI0T,GAAU9uB,KACVtC,EAAY0e,EAAKrf,QAAQW,UACzBugC,EAAQ7hB,EAAK6hB,MACbznB,EAAW4F,EAAKrf,QAAQyZ,SACxBc,EAAS8E,EAAKrf,QAAQua,OACtBivB,EAAa/vB,GAAY4F,EAAKrf,QAAQyZ,SAASyK,SAAWljB,GAAGiW,kBAAkBwC,SAC/EgwB,EAAgBlvB,GAAU8E,EAAKrf,QAAQua,OAAO2J,SAAWslB,GAAcxoC,GAAGiW,kBAAkBsD,OAC5F4J,EAAU+c,EAAM/c,QAChBkC,EAAU6a,EAAM7a,QAChBO,EAAUsa,EAAMta,QAChBf,EAAcqb,EAAMrb,YACpB8J,EAAgBuR,EAAMvR,cACtBH,EAAgB0R,EAAM1R,cACtBrB,EAAa+S,EAAM/S,WACnB/qB,EAAM89B,EAAM99B,GAahBpC,IAAGwG,OAAOvE,KAAM,GAAIjC,IAAGigC,cAAc5hB,IAErCre,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OAII4D,IAAK,SAAS0J,EAAIqrB,GACd,GAAI1oC,GAAGgM,OAAO08B,IAAgB1oC,GAAG+M,OAAO27B,GACpC34B,EAAO4D,IAAI0J,GAAKgF,KAAMqmB,QAErB,CAAA,KAAIA,YAAuB1oC,IAAG4a,WAI/B,KAAM,IAAIzU,OAAM,2CAHhB4J,GAAO4D,IAAI0J,GAAK6iB,MAAOwI,IAM3B3X,EAAQ4X,eAAetrB,GACvBorB,GAAiB1X,EAAQ6X,uBAAuBvrB,IAGpD0X,QAAS,SAAS1X,GACdklB,EAAMllB,GACN0T,EAAQ0Q,+BAA+BpkB,GACvC0T,EAAQ8T,WAAWxnB,GACnBtN,EAAOglB,QAAQ1X,OAK3Brd,GAAGwG,OAAOvE,MAEN2/B,iBAAkB,SAASvkB,EAAI2jB,SACpBjQ,GAAQwP,cAAcljB,GAAI9J,KAAKs1B,aAAa7H,IAGvDuC,SAAU,SAASlmB,EAAI2jB,GACnB,GAAI8H,GAAY/X,EAAQwP,cAAcljB,GAAI9J,IAEtCu1B,GAAUC,YACHD,GAAUC,KAAK/H,GAEtB8H,EAAUE,sBACHF,GAAUE,eAAehI,IAMxCM,eAAgB,SAASjkB,EAAI4rB,GACzB,GAAIC,GAAenY,EAAQgS,gBAAgB1lB,GAAM,EAC7C3G,EAAMqa,EAAQoY,QAAQ9rB,EAAI6rB,EAE9B,OAAID,IACO,GAAIjpC,IAAGoP,SAAUE,QAAQ25B,EAAevyB,GAAMA,IAGlD,GAAI1W,IAAGoP,SAAUE,WAAYoH,IAGxC2N,QAAS,SAAShH,GACd,MAAO0T,GAAQtN,QAAQpG,IAAO0T,EAAQwP,cAAcljB,GAAIgF,MAG5DyiB,SAAU,SAASznB,GACf,MAAO0T,GAAQtN,QAAQpG,IAAO0T,EAAQwP,cAAcljB,GAAI6iB,OAO5D9a,sBAAuB,WACnB,GAAIgkB,KAmBJ,OAjBArY,GAAQsY,sBAAsB,SAASlpC,EAAK6iB,GACxC+N,EAAQ0R,0BAA0B,KAAMzf,EAAWvK,SAASspB,WAAa/e,EAAWvK,SAASupB,UAE7F,IAAI3hC,IACAW,KAAMgiB,EAAWhiB,KACjBghC,UAAWhf,EAAWvK,SAASupB,UAC/BxjB,KAAMwE,EAAWxE,KACjBhB,KAAMwF,EAAWxF,KAGjBwF,GAAW7iB,MACXE,EAAKF,IAAM6iB,EAAW7iB,KAG1BipC,EAAmBtnC,KAAKzB,KAGrB+oC,GAGXjD,YAAa,SAAS9oB,GAClB,QAAS5E,GAAYsY,EAAQtN,QAAQpG,KAAQ0T,EAAQwP,cAAcljB,GAAIisB,cAG3E7G,0BAA2B,SAASplB,EAAIksB,EAAeC,GACnD,GAAIzH,GAAawH,GAAiBxY,EAAQwP,cAAcljB,GAAI5E,SAASspB,WACjEC,EAAYwH,GAAgBzY,EAAQwP,cAAcljB,GAAI5E,SAASupB,SAE/DD,KACA3/B,EAAIpC,GAAG0L,OAAO,yDAA0DgJ,KAAKopB,UAAUiE,KACvFA,EAAW0H,UACXzpC,GAAGY,KAAKmhC,EAAY,SAASngC,EAAKo/B,GAC9BgB,EAAUC,QAAQjB,KAEtBe,EAAW19B,OAAS,IAI5BgV,MAAO,SAASgE,GACZ,GAAI0T,EAAQtN,QAAQpG,GAIhB,MAHAjb,GAAIpC,GAAG0L,OAAO,4DAA6D2R,EAAI8F,EAAQ9F,KACvF0T,EAAQwP,cAAcljB,GAAIqsB,QAAS,EACnCnH,EAAMllB,IACC,GAIf2lB,mBAAoB,SAAS3lB,GACzB,GAAI5E,GAAYsY,EAAQtN,QAAQpG,GAAK,CACjC,GACIssB,GACA91B,EAFA2G,EAAQuW,EAAQwP,cAAcljB,EAQlC,UAJO7C,GAAM/B,SAEb+B,EAAM/B,YACNkxB,EAAc5Y,EAAQgS,gBAAgB1lB,GAClCssB,EAAc,GAAKlxB,EAASqhB,UAAW,CAKvC,IAJAtf,EAAM/B,SAASyK,SAAU,EACzB1I,EAAM/B,SAASmxB,MAAQD,EACvBnvB,EAAM/B,SAASupB,aAEVnuB,EAAI,EAAGA,EAAI81B,EAAa91B,IACzB2G,EAAM/B,SAASupB,UAAUlgC,KAAK+R,EAGlCkd,GAAQ4X,eAAetrB,OAGvB7C,GAAM/B,SAASyK,SAAU,IAKrCqiB,WAAY,SAASloB,EAAIwsB,GACjB9Y,EAAQtN,QAAQpG,KAChB0T,EAAQwP,cAAcljB,GAAIgF,KAAOwnB,IAIzChF,WAAY,SAASxnB,GACjB,GAAIyrB,GAAY/X,EAAQwP,cAAcljB,GAAI9J,IAE1CvT,IAAGY,KAAKkoC,EAAUE,eAAgB,SAASc,SAChChB,GAAUE,eAAec,KAGpC9pC,GAAGY,KAAKkoC,EAAUC,KAAM,SAASe,SACtBhB,GAAUC,KAAKe,MAW9BC,WAAY,SAAS1sB,EAAI2sB,GACrB,MAAOjZ,GAAQkZ,aAAa5sB,EAAI2sB,EAAahqC,GAAGuN,sBAGpDg7B,kBAAmB,SAASlrB,EAAI2sB,GAC5B,GAAIhJ,GAA0B,MAAfgJ,GAAsB,EAAKA,CAC1C,OAAOjZ,GAAQwP,cAAcljB,GAAI9J,KAAKy1B,eAAehI,IAGzDC,cAAe,SAAS5jB,EAAI6sB,GACxB,GAAIhQ,GAAYzhB,EAAS4hB,SACrB8P,EAAW9kB,EAAQhI,GACnBjP,EAAa2iB,EAAQ1M,QAAQhH,GAC7B+sB,EAAalQ,EAAYgQ,EACzBG,EAAWD,EAAalQ,GAAaiQ,EAAWA,EAAWC,EAAalQ,EACxEyP,EAAc5Y,EAAQgS,gBAAgB1lB,GACtCwrB,EAAe5mC,KAAKs+B,cAAcljB,GAAI9J,KAAKs1B,aAI3C/5B,EAAO+5B,EAAaqB,IAAelqC,GAAGmO,UAAUC,EAAYg8B,EAAYC,EAI5E,OAFAxB,GAAaqB,GAAcp7B,GAGvBw7B,KAAMJ,EACN77B,MAAO+7B,EACP97B,IAAK+7B,EACLE,MAAOZ,EACP76B,KAAMA,EACN0P,KAAM6rB,EAAWD,IAIzBhJ,yBAA0B,SAASnT,GAC/B,OACI+L,UAAW/L,EAAUqc,KACrBE,UAAWvc,EAAU5f,MAAQ,EAC7Bo8B,QAASxc,EAAU3f,IACnB8rB,WAAYnM,EAAUsc,QAQ9BG,mBAAoB,SAASrtB,GACzB,GAAIstB,GAAgB,MAChB3pC,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,GACf6c,EAAYzhB,EAAS4hB,SACrBvZ,EAAW+D,EAAYxH,EAE3B,OAAOrd,IAAG0L,OAAO,2BAA4B/L,EAAWgrC,EAAe3pC,EAAMwd,EAAM0b,EAAWpZ,IAGlG8pB,aAAc,SAASvtB,GACnB,MAAO0T,GAAQ1M,QAAQhH,GAAIja,MAG/BynC,oBAAqB,SAASxtB,GAC1B,MAAO0T,GAAQwP,cAAcljB,GAAI5E,UAOrCsqB,gBAAiB,SAAS1lB,GACtB,GAAI5E,EAAU,CACV,GAAI0xB,GAAW9kB,EAAQhI,GACnB6c,EAAYzhB,EAAS4hB,QAEzB,OAAO/zB,MAAKwkC,KAAKX,EAAWjQ,KAIpCiP,QAAS,SAAS9rB,EAAI2sB,GAClB,GAAIhJ,GAA0B,MAAfgJ,GAAsB,EAAKA,CAC1C,OAAOjZ,GAAQwP,cAAcljB,GAAI9J,KAAKw1B,KAAK/H,IAG/CoB,SAAU,SAAS/kB,GACf,MAAO0T,GAAQwP,cAAcljB,GAAI9J,KAAKw1B,MAK1CM,sBAAuB,SAASz2B,GACxB61B,GACAzoC,GAAGY,KAAKsW,aAAc,SAAS/W,EAAK+K,GAChC,GAAwD,IAApD/K,EAAI0J,QAAQ7J,GAAG0L,OAAO,aAAc/L,IAAmB,CACvD,GAAIqjB,GAAatO,KAAKC,MAAMzJ,EAC5B0H,GAASzS,EAAK6iB,OAM9B2lB,eAAgB,SAAStrB,GACrB0T,EAAQwP,cAAcljB,GAAI9J,MACtBy1B,kBACA7H,iBACA4H,QACAF,kBAIRkC,kBAAmB,SAAS1tB,GACxB0T,EAAQwP,cAAcljB,GAAIisB,cAAe,GAK7C7H,+BAAgC,SAASpkB,GACrC,GAAI2tB,EAEJ,UAAIvC,GAAiB1X,EAAQoV,YAAY9oB,KACrC2tB,EAAiBja,EAAQ2Z,mBAAmBrtB,GAExC2tB,GAAkB9zB,aAAanE,QAAQi4B,OACvC9zB,aAAa+zB,WAAWD,IACjB,IASnBpC,uBAAwB,SAASvrB,GAC7B,GACI2tB,GAAgBE,EADhB1wB,EAAQuW,EAAQwP,cAAcljB,EAK9BorB,IAA+BnoC,SAAdka,EAAMra,MACvB6qC,EAAiBja,EAAQ2Z,mBAAmBrtB,GAC5C6tB,EAAgBh0B,aAAanE,QAAQi4B,GAGjCE,IACAA,EAAgBx2B,KAAKC,MAAMu2B,GAIvBvc,EAAcuc,EAAc1tB,MAC5BuT,EAAQga,kBAAkB1tB,IAG1Bjb,EAAIpC,GAAG0L,OAAO,0DAA2D2R,EAAI8F,EAAQ9F,KAErFmR,EAAcnR,EAAI6tB,EAAc1tB,MAEhChD,EAAMra,IAAM+qC,EAAc/qC,IAC1Bqa,EAAM/B,SAAWyyB,EAAczyB,SAC/B+B,EAAM4S,OAAS8d,EAAc9d,OAC7B5S,EAAM0mB,kBAAmB,EAEzBnQ,EAAQ0R,0BAA0BplB,OAOlDimB,0BAA2B,SAASjmB,GAChC,GACI2tB,GAAgBE,EADhB1wB,EAAQuW,EAAQwP,cAAcljB,EAIlC,IAAIorB,GAAiB1X,EAAQoV,YAAY9oB,GAAK,CAC1C2tB,EAAiBja,EAAQ2Z,mBAAmBrtB,GAE5C6tB,GACIlqC,KAAMmiB,EAAQ9F,GACdmB,KAAM6G,EAAQhI,GACdG,KAAMoI,EAAQvI,GACdld,IAAKqa,EAAMra,IACXsY,SAAU+B,EAAM/B,SAChB2U,OAAQ5S,EAAM4S,OACd+d,YAAarL,KAAK+F,MAGtB,KACI3uB,aAAaC,QAAQ6zB,EAAgBt2B,KAAKopB,UAAUoN,IAExD,MAAO/oC,GACHC,EAAIpC,GAAG0L,OAAO,0DAA2D2R,EAAIlb,EAAMsI,YAAa,WAK5G2gC,yBAA0B,SAAS/tB,EAAI2jB,EAAU9G,GAC7C,GAAIxjB,GAAMqa,EAAQoY,QAAQ9rB,EAAI2jB,GAC1BhgC,EAAOmiB,EAAQ9F,GACfguB,GACI3G,OAAQ,SAAStX,EAAQC,GACrB,GAAI8c,GAAW9kB,EAAQhI,EAEnB+P,KAAWC,EACXF,EAAW9P,EAAIrc,EAAMmpC,EAAUA,GAG/Bhd,EAAW9P,EAAIrc,EAAOosB,GAAU+c,EAAWA,EAAW,EAAI/c,EAAS+c,IAI3EpJ,QAAS,SAAS3T,EAAQC,GACtB,GAAI8T,GAAgBpQ,EAAQwP,cAAcljB,GAAI9J,KAAK4tB,cAC/CmK,EAAiCva,EAAQwP,cAAcljB,GAAI+P,OAC3Dme,EAAmBne,EACnBoe,EAAkBne,EAClB8M,EAAgB9U,EAAQhI,GACxBouB,EAAuBF,GAAoBC,EAAkBtR,GAC7DwR,EAAqBJ,CAEzBnK,GAAcH,GAAYyK,EAE1BzrC,GAAGY,KAAKugC,EAAe,SAASH,EAAU2K,GACtCD,GAAsBC,IAG1Bxe,EAAW9P,EAAIrc,EAAM0qC,EAAoBvR,IAIrDzjB,GAAIlJ,OAAOwuB,WAAa,SAAS3pB,GAC7B,GAAIA,EAAE4rB,iBAAkB,CAEpB,GAAI76B,GAAoB,MAAb82B,EAAoB,SAAW,SAC1CmR,GAAmBjoC,GAAMiP,EAAE+a,OAAQ/a,EAAEgb,UAcjD4c,aAAc,SAAS5sB,EAAI2sB,EAAatzB,EAAKk1B,GACzC,GAAIC,GAAwB,MAAf7B,GAAsB,EAAKA,EACpClB,EAAY/X,EAAQwP,cAAcljB,GAAI9J,IAW1C,OATAu1B,GAAUC,KAAOD,EAAUC,SAC3BD,EAAUE,eAAiBF,EAAUE,mBAErCF,EAAUC,KAAK8C,GAAUn1B,EAErBk1B,IACA9C,EAAUE,eAAe6C,GAAUD,GAGhCl1B,GAIXyuB,8BAA+B,WAC3B,GAAI2G,GAAiBvyB,EAAO+gB,eAE5BvJ,GAAQsY,sBAAsB,SAASlpC,EAAK6iB,GACxC,GAAI+oB,GAAiB,GAAIjM,MAAK9c,EAAWmoB,YAGzCY,GAAeC,QAAQD,EAAeE,UAAYH,GAE9CC,EAAehM,WAAaD,KAAK+F,QACjCzjC,EAAI,2CAA6CjC,GACjD+W,aAAa+zB,WAAW9qC,OAWpC4lC,qBAAsB,SAAS1oB,GAC3B,GAAI7C,GAAQuW,EAAQwP,cAAcljB,EAMlC,OAJK7C,GAAM/B,UACPsY,EAAQiS,mBAAmB3lB,GAGxB7C,EAAM/B,SAASyK,YCxflCljB,GAAGmpB,wBAA0B,SAASlO,GAClC,YAqBA,SAASixB,KACL,MAAqC,SAAjCltC,EAAQoqB,OAAOvpB,eAEXssC,QAAS,aAtBrB,GAAIC,GACAptC,GACIoqB,OAAQ,SACRE,cAAe,SACfK,iBACAN,eAAgB,EAChBI,cAAe,SAASpM,GAAK,UAC7BqM,eACAE,MACIoI,UAAU,EACVyI,iBAAiB,GAErBr4B,IAAK,SAASuJ,EAAKvB,KACnByf,SAAU,SAASxM,KACnB0M,iBAAkB,SAAS1M,EAAI2M,EAAUC,KAGjDjqB,IAAGwG,OAAOxH,EAASic,GAYnBmxB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAe,OAAQ,UACvBvV,OAAQpqB,EAAQoqB,OAChBO,cAAe3qB,EAAQ2qB,cACvBD,YAAa1qB,EAAQ0qB,YACrBmT,eAAgBqP,IAChB7iB,eAAgBrqB,EAAQqqB,eACxBI,cAAe,SAASpM,GACpB,MAAOre,GAAQyqB,cAAc1E,IAAI1H,IAErCjb,IAAKpD,EAAQoD,IACb66B,OAAQj+B,EAAQ6qB,SAChB0D,WAAYvuB,EAAQ+qB,iBACpBH,KAAM5qB,EAAQ4qB,QAGlB5pB,GAAGwG,OAAOvE,MACN2zB,WAAY,SAASvY,EAAIG,EAAMgY,GAC3B,GAAIzI,GAAoByI,KAExBx2B,GAAQoD,IAAI,sCAAwCib,GAE7B,WAAnBre,EAAQoqB,OACRgjB,EAAUnN,cAAc5hB,GACnB+hB,SAAS5hB,GACT8hB,WAAWvS,GACX4Q,QAGL5Q,EAAkB/tB,EAAQsqB,eAAiB9L,EAC3C4uB,EAAUnN,cAAc5hB,GACnBiiB,WAAWvS,GACX4Q,YCpDrB,WAMI,QAAS0O,GAAkBC,GACvB,GAGIC,GAHAC,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTnkC,EAAS2E,SAASC,cAAc,SAGpC,OAAIo/B,GAAKE,EAAK,UACVlkC,EAAOokC,MAAQpkC,EAAOyT,OAAS,EAC/BswB,EAAM/jC,EAAOqkC,WAAW,MACxBN,EAAIO,UAAUR,GAAME,EAAK,EAAG,GAIoB,IAAzCD,EAAIQ,aAAa,EAAG,EAAG,EAAG,GAAG1sC,KAAK,IAUjD,QAAS2sC,GAAqBV,EAAKE,EAAIE,GACnC,GAIIH,GAAKlsC,EAAM4sC,EAAOC,EAJlB1kC,EAAS2E,SAASC,cAAc,UAChC+/B,EAAK,EACLC,EAAKV,EACLW,EAAKX,CAUT,KAPAlkC,EAAOokC,MAAQ,EACfpkC,EAAOyT,OAASywB,EAChBH,EAAM/jC,EAAOqkC,WAAW,MACxBN,EAAIO,UAAUR,EAAK,EAAG,GACtBjsC,EAAOksC,EAAIQ,aAAa,EAAG,EAAG,EAAGL,GAAIrsC,KAG9BgtC,EAAKF,GACRF,EAAQ5sC,EAAgB,GAAVgtC,EAAK,GAAS,GACd,IAAVJ,EACAG,EAAKC,EAELF,EAAKE,EAETA,EAAMD,EAAKD,GAAO,CAItB,OADAD,GAASG,EAAKX,EACI,IAAVQ,EAAe,EAAIA,EAM/B,QAASI,GAAqBhB,EAAKx9B,EAAM9P,EAASuuC,GAC9C,GAAI/kC,GAAS2E,SAASC,cAAc,UAChC3E,EAAOzJ,EAAQyJ,MAAQ,aACvB0G,EAAU,GAAInP,IAAGoP,OASrB,OAPAo+B,GAAoBlB,EAAKx9B,EAAMtG,EAAQxJ,EAASuuC,GAC3CrzB,KAAK,WACF/K,EAAQG,QACJ9G,EAAOI,UAAUH,EAAMzJ,EAAQ0J,SAAW,OAI/CyG,EAGX,QAASs+B,GAAoCpvB,GACzC,GAAIqvB,GAAY,MAEhB,KAAK1tC,GAAG6R,MACJ,KAAM,IAAI7R,IAAGmG,MAAM,kEAGvB,IAAIkY,EAAKsvB,WAAatvB,EAAKuvB,UAAYF,EACnC,OACIG,UAAWvnC,KAAKC,MAAMD,KAAKwnC,KAAKJ,GAAarvB,EAAKsvB,WAAatvB,EAAKuvB,aACpEG,SAAUznC,KAAKC,MAAMD,KAAKwnC,KAAKJ,GAAarvB,EAAKuvB,UAAYvvB,EAAKsvB,eAQ9E,QAASH,GAAoBlB,EAAKx9B,EAAMtG,EAAQxJ,EAASuuC,GACrD,GAMIS,GANAxB,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTC,EAAQ5tC,EAAQ4tC,MAChB3wB,EAASjd,EAAQid,OACjBswB,EAAM/jC,EAAOqkC,WAAW,MACxB19B,EAAU,GAAInP,IAAGoP,OAKrB,OAFAm9B,GAAI0B,OAEAjvC,EAAQkvC,OACDC,GACHr/B,KAAMA,EACNtG,OAAQA,EACRqvB,MAAOyU,EACP8B,YAAa1B,EACb2B,WAAY7B,EACZ8B,YAAatvC,EAAQsvC,YACrBJ,OAAQlvC,EAAQkvC,OAChBK,aAActyB,EACduyB,YAAa5B,KAIhB5sC,GAAGiW,kBAAkByD,2BACtBs0B,EAAqBP,GACjBG,UAAWhB,EACXe,WAAY1xB,IAGZ+xB,IACAhuC,GAAGoC,IAAIpC,GAAG0L,OAAO,iFACbkhC,EAAO3wB,EAAQ+xB,EAAmBD,SAAUC,EAAmBH,WAC/D,QAEJjB,EAAQoB,EAAmBD,SAC3B9xB,EAAS+xB,EAAmBH,YAIpCY,EAAoBjmC,EAAQokC,EAAO3wB,EAAQjd,EAAQsvC,aAI/CtuC,GAAG6R,OACF,WACOw6B,EAAkBC,KAClBE,GAAM,EACNE,GAAM,EAGV,IAOIgC,GAAQC,EAAIC,EAPZC,EAAI,KACJC,EAAY3hC,SAASC,cAAc,UACnC2hC,EAAkBxB,EAAWP,EAAqBV,EAAKE,EAAIE,GAAM,EACjEsC,EAAK1oC,KAAKwkC,KAAK+D,EAAIjC,EAAQJ,GAC3ByC,EAAK3oC,KAAKwkC,KAAK+D,EAAI5yB,EAASywB,EAAKqC,GACjC5B,EAAK,EACL+B,EAAK,CAMT,KAHAJ,EAAUlC,MAAQkC,EAAU7yB,OAAS4yB,EACrCH,EAASI,EAAUjC,WAAW,MAEvBM,EAAKT,GAAI,CAGZ,IAFAiC,EAAK,EACLC,EAAK,EACED,EAAKnC,GACRkC,EAAOS,UAAU,EAAG,EAAGN,EAAGA,GAC1BH,EAAO5B,UAAUR,GAAMqC,GAAKxB,GAC5BZ,EAAIO,UAAUgC,EAAW,EAAG,EAAGD,EAAGA,EAAGD,EAAIM,EAAIF,EAAIC,GACjDN,GAAME,EACND,GAAMI,CAEV7B,IAAM0B,EACNK,GAAMD,EAEV1C,EAAI6C,UACJN,EAAYJ,EAAS,QAIzBnC,EAAIO,UAAUR,EAAK,EAAG,EAAGM,EAAO3wB,GAGpCzT,EAAO6mC,iBAAmB7mC,EAAO6mC,kBACjClgC,EAAQG,UAEDH,GAGX,QAASg/B,GAAqCmB,GAC1C,GAAIxgC,GAAOwgC,EAAWxgC,KAClB+oB,EAAQyX,EAAWzX,MACnBuW,EAAckB,EAAWlB,YACzBC,EAAaiB,EAAWjB,WACxBC,EAAcgB,EAAWhB,YACzBn/B,EAAU,GAAInP,IAAGoP,QACjB8+B,EAASoB,EAAWpB,OACpBqB,EAAepiC,SAASC,cAAc,UACtCoiC,EAAsBD,EAAa1C,WAAW,MAC9C4C,EAAeH,EAAW9mC,OAC1B+lC,EAAee,EAAWf,aAC1BC,EAAcc,EAAWd,WAyB7B,OAvBAC,GAAoBc,EAAclB,EAAYD,EAAaE,GAE3DmB,EAAaxzB,OAASsyB,EACtBkB,EAAa7C,MAAQ4B,EAErBgB,EAAoB1C,UAAUjV,EAAO,EAAG,GAExCqW,GACIp/B,KAAMA,EACNmN,OAAQsyB,EACR1W,MAAOA,EACP0X,aAAcA,EACdE,aAAcA,EACd7C,MAAO4B,IAENt0B,KACG,WACIu1B,EAAaJ,iBAAmBI,EAAaJ,kBAC7ClgC,EAAQG,WAEZH,EAAQK,SAGTL,EAOX,QAASs/B,GAAoBjmC,EAAQokC,EAAO3wB,EAAQqyB,GAChD,OAAQA,GACJ,IAAK,GACL,IAAK,GACL,IAAK,GACL,IAAK,GACD9lC,EAAOokC,MAAQ3wB,EACfzT,EAAOyT,OAAS2wB,CAChB,MACJ,SACIpkC,EAAOokC,MAAQA,EACfpkC,EAAOyT,OAASA,EAExB,GAAIswB,GAAM/jC,EAAOqkC,WAAW,KAC5B,QAAQyB,GACJ,IAAK,GAED/B,EAAImD,UAAU9C,EAAO,GACrBL,EAAInoB,OAAM,EAAI,EACd,MACJ,KAAK,GAEDmoB,EAAImD,UAAU9C,EAAO3wB,GACrBswB,EAAIoD,OAAOrpC,KAAKspC,GAChB,MACJ,KAAK,GAEDrD,EAAImD,UAAU,EAAGzzB,GACjBswB,EAAInoB,MAAM,GAAG,EACb,MACJ,KAAK,GAEDmoB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAInoB,MAAM,GAAG,EACb,MACJ,KAAK,GAEDmoB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAImD,UAAU,GAAIzzB,EAClB,MACJ,KAAK,GAEDswB,EAAIoD,OAAO,GAAMrpC,KAAKspC,IACtBrD,EAAImD,UAAU9C,GAAQ3wB,GACtBswB,EAAInoB,OAAM,EAAI,EACd,MACJ,KAAK,GAEDmoB,EAAIoD,QAAO,GAAOrpC,KAAKspC,IACvBrD,EAAImD,WAAW9C,EAAO,IAUlC,QAASiD,GAAaC,EAAUC,GAC5B,GAAI/rC,GAAO/B,IAEPmH,QAAOO,MAAQmmC,YAAoBnmC,QAClC,WACG,GAAI2iC,GAAM,GAAI0D,OACVC,EAAM7mC,OAAO6mC,KAAO7mC,OAAO6mC,IAAIC,gBAAkB9mC,OAAO6mC,IACpD7mC,OAAO+mC,WAAa/mC,OAAO+mC,UAAUD,gBAAkB9mC,OAAO+mC,UAAY,IAClF,KAAKF,EAAO,KAAM9pC,OAAM,uDACxBmmC,GAAI8D,IAAMH,EAAIC,gBAAgBJ,GAC9B9rC,EAAK8K,KAAOghC,EACZA,EAAWxD,KAGdwD,EAASrD,cAAiBqD,EAASnD,gBACpCmD,EAASzgC,OAAS,WACd,GAAIghC,GAAYrsC,EAAKssC,kBACjBD,KACArsC,EAAKssC,mBAAqB,KAG1BzkB,WAAW,WACP,IAAK,GAAIhY,GAAI,EAAGxD,EAAMggC,EAAUhsC,OAAQwP,EAAIxD,EAAKwD,IAC7Cw8B,EAAUx8B,MAEf,KAGXi8B,EAASvgC,QAAUwgC,EACnB9tC,KAAKquC,uBAETruC,KAAK6tC,SAAWA,EAMpBD,EAAaruC,UAAU+uC,OAAS,SAAS1gC,EAAQ7Q,GAC7CA,EAAUA,KAEV,IASIwxC,GATAxsC,EAAO/B,KACPwuC,EAAWxuC,KAAK6tC,SAASrD,aACzBiE,EAAYzuC,KAAK6tC,SAASnD,cAC1BC,EAAQ5tC,EAAQ4tC,MAChB3wB,EAASjd,EAAQid,OACjB2c,EAAW55B,EAAQ45B,SACnBD,EAAY35B,EAAQ25B,UACpB4U,GAAYtrC,KAAK6M,MAA2B,eAAnB7M,KAAK6M,KAAK1L,KACnC0J,EAAU+C,EAAO/C,QAAQ/M,aAG7B,OAAIkC,MAAKquC,uBACLruC,MAAKquC,mBAAmBxuC,KAAK,WAAakC,EAAKusC,OAAO1gC,EAAQ7Q,MAI9D4tC,IAAU3wB,EACVA,EAAUy0B,EAAY9D,EAAQ6D,GAAa,EACpCx0B,IAAW2wB,EAClBA,EAAS6D,EAAWx0B,EAASy0B,GAAc,GAE3C9D,EAAQ6D,EACRx0B,EAASy0B,GAET9X,GAAYgU,EAAQhU,IACpBgU,EAAQhU,EACR3c,EAAUy0B,EAAY9D,EAAQ6D,GAAa,GAE3C9X,GAAa1c,EAAS0c,IACtB1c,EAAS0c,EACTiU,EAAS6D,EAAWx0B,EAASy0B,GAAc,GAG/CF,GAAQ5D,MAAOA,EAAO3wB,OAAQA,GAC9Bjc,GAAGY,KAAK5B,EAAS,SAAS2xC,EAAYC,GAClCJ,EAAIG,GAAcC,IAGN,QAAZ9jC,GACC,WACG,GAAI+jC,GAAehhC,EAAOugC,GAC1B9C,GAAqBtpC,EAAK8rC,SAAU9rC,EAAK8K,KAAM0hC,EAAKjD,GAC/CrzB,KAAK,SAASrR,GACXgH,EAAOugC,IAAMvnC,EACbgoC,IAAiBhhC,EAAOugC,KAAOvgC,EAAOR,cAG/B,WAAZvC,GACP0gC,EAAoBvrC,KAAK6tC,SAAU7tC,KAAK6M,KAAMe,EAAQ2gC,EAAKjD,QAElC,kBAAlBtrC,MAAK6uC,UACZ7uC,KAAK6uC,SAASjhC,MAItB7P,GAAG6vC,aAAeA,KCtYtB7vC,GAAGm7B,eAAiB,SAAS/4B,GACzB,YAEA,SAAS2uC,GAAM3sC,GACX,MAAoC,QAA7BA,EAAG0I,QAAQ/M,cAGtB,QAASixC,GAAS5sC,GACd,MAAoC,WAA7BA,EAAG0I,QAAQ/M,cAGtB,QAASkxC,KACL,MAAmC3wC,WAA5B,GAAI0vC,QAAQkB,YAGvB,QAASC,KACL,GAAI3oC,GAAS2E,SAASC,cAAc,SAEpC,OAAO5E,GAAOqkC,YAAcrkC,EAAOqkC,WAAW,MAMlD,QAASuE,GAAwBC,GAE7B,GAAIC,GAAeD,EAAaznC,MAAM,KAClC5I,EAAOswC,EAAaA,EAAajtC,OAAS,GAAGuF,MAAM,KAAK,GACxD0nB,EAAYtxB,GAAG6U,aAAa7T,EAIhC,QAFAswB,EAAYA,GAAaA,EAAUvxB,eAG/B,IAAK,OACL,IAAK,MACD,MAAO,YACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,OACL,IAAK,MACD,MAAO,cASnB,QAASwxC,GAAcxU,GACnB,GACIyU,GAAgBC,EAAgBC,EADhCC,EAAexkC,SAASC,cAAc,IAS1C,OANAukC,GAAaC,KAAO7U,EAEpByU,EAAiBG,EAAaE,SAC9BH,EAAaC,EAAaG,KAC1BL,EAAiBE,EAAaI,SAE1BP,EAAezxC,gBAAkBqJ,OAAO4oC,SAASH,SAAS9xC,gBAI1D0xC,EAAe1xC,gBAAkBqJ,OAAO4oC,SAASD,SAAShyC,eAK1D2xC,IAAetoC,OAAO4oC,SAASF,OAAS9xC,GAAG4Q,MAOnD,QAASqhC,GAAyB3F,EAAKn9B,GACnCm9B,EAAIj9B,OAAS,WACTi9B,EAAIj9B,OAAS,KACbi9B,EAAI/8B,QAAU,KACdJ,EAAQG,QAAQg9B,IAGpBA,EAAI/8B,QAAU,WACV+8B,EAAIj9B,OAAS,KACbi9B,EAAI/8B,QAAU,KACdnN,EAAI,6BAA8B,SAClC+M,EAAQK,QAAQ88B,EAAK,+BAI7B,QAAS4F,GAAgC1pC,EAAQ2G,GAO7C3G,EAAO6mC,gBAAkB,WACrBlgC,EAAQG,QAAQ9G,IAQxB,QAAS2pC,GAAkCvuB,EAAazU,GACpD,GAAIijC,GAAarB,EAAMntB,IAAgBotB,EAASptB,EAahD,OAXImtB,GAAMntB,GACNquB,EAAyBruB,EAAazU,GAEjC6hC,EAASptB,GACdsuB,EAAgCtuB,EAAazU,IAG7CA,EAAQK,QAAQoU,GAChBxhB,EAAIpC,GAAG0L,OAAO,iDAAkDkY,EAAY9W,SAAU,UAGnFslC,EAKX,QAASC,GAAKjkC,EAAYkW,EAAWtlB,GACjC,GAAIszC,GAAc,GAAItyC,IAAGoP,QACrBub,EAAa,GAAI3qB,IAAGuyC,SAASnkC,EAAYhM,GACzCyhB,EAAU7kB,EAAQ6kB,QAElBgX,EAA2B,MAAlB77B,EAAQ67B,QAAwB77B,EAAQ67B,OACjD2X,EAAsB,WAClBluB,EAAU/U,QAAU,KACpB+U,EAAUjV,OAAS,KACnBjN,EAAI,mDAAoD,SACxDkwC,EAAY9iC,QAAQ8U,EAAW,gCAiDvC,OA9CAqG,GAAW8nB,gBAAgBv4B,KACvB,SAASzR,GAGL,GAAIiqC,IACI/9B,MAAO,WACH,OAAO,GAAI3U,IAAGoP,SAAUE,YAGhCqjC,EAAO9X,EAAS,GAAI76B,IAAG4yC,KAAKxkC,EAAYhM,GAAOswC,EAC/CG,EAAQ,GAAI7yC,IAAG6vC,aAAazhC,EAAYokC,EAExCL,GAAkC7tB,EAAWguB,IAC7CK,EAAKh+B,QAAQuF,KACT,SAASy4B,GACL,GAAIrE,GAAcqE,GAAQA,EAAKG,WAE/BD,GAAMtC,OAAOjsB,GACTsU,SAAU/U,EACV8U,UAAW9U,EACXyqB,YAAaA,EACb7lC,KAAMA,EACNylC,OAAQlvC,EAAQ+kB,wBAIxB,SAASgvB,GACL3wC,EAAIpC,GAAG0L,OAAO,iEAAkEqnC,IAEhFF,EAAMtC,OAAOjsB,GACTsU,SAAU/U,EACV8U,UAAW9U,EACXpb,KAAMA,EACNylC,OAAQlvC,EAAQ+kB,0BAOpC,WACI3hB,EAAI,mBACJkwC,EAAY9iC,QAAQ8U,EAAW,qBAIhCguB,EAGX,QAASU,GAAyBjW,EAAKkW,EAAaZ,EAAMxuB,EAASE,GAC/D,GAAImvB,GAAU,GAAIlD,OACdmD,EAAgB,GAAInzC,IAAGoP,OAE3B+iC,GAAkCe,EAASC,GAEvC5B,EAAcxU,KACdmW,EAAQhC,YAAc,aAG1BgC,EAAQ9C,IAAMrT,EAEdoW,EAAcj5B,KACV,WACIi4B,EAAkCc,EAAaZ,EAE/C,IAAIQ,GAAQ,GAAI7yC,IAAG6vC,aAAaqD,EAChCL,GAAMtC,OAAO0C,GACTra,SAAU/U,EACV8U,UAAW9U,EACXpb,KAAM2oC,EAAwBrU,GAC9BmR,OAAQnqB,KAIhBsuB,EAAK7iC,SAIb,QAAS4jC,GAA+BrW,EAAKuP,EAAK+F,EAAMxuB,GACpDsuB,EAAkC7F,EAAK+F,GAKvCryC,GAAGssC,GAAKrmC,KACJ2yB,SAAU/U,EAAU,KACpB8U,UAAW9U,EAAU,OAGzByoB,EAAI8D,IAAMrT,EAWd,QAASsW,GAAYtW,EAAKzY,EAAWtlB,GACjC,GAAIqzC,GAAO,GAAIryC,IAAGoP,QACdgV,EAAQplB,EAAQolB,MAChBP,EAAUO,EAAQplB,EAAQ6kB,QAAU,IA8BxC,OA3BIO,IAAS2sB,EAAMzsB,GAGX6sB,IAIII,EAAcxU,KAASkU,IACvBmC,EAA+BrW,EAAKzY,EAAW+tB,EAAMxuB,GAGrDmvB,EAAyBjW,EAAKzY,EAAW+tB,EAAMxuB,GAInDuvB,EAA+BrW,EAAKzY,EAAW+tB,EAAMxuB,GAIpDmtB,EAAS1sB,GACd0uB,EAAyBjW,EAAKzY,EAAW+tB,EAAMxuB,GAG1CsuB,EAAkC7tB,EAAW+tB,KAClD/tB,EAAU8rB,IAAMrT,GAGbsV,EAGXryC,GAAGwG,OAAOvE,MAWNsiB,SAAU,SAAS+uB,EAAehvB,EAAWtlB,GACzC,MAAIgB,IAAGoL,SAASkoC,IACZlxC,EAAI,4DACGixC,EAAYC,EAAehvB,EAAWtlB,SAG7CoD,EAAI,iDACGiwC,EAAKiB,EAAehvB,EAAWtlB,WAMlDiD,KAAKsxC,YACLtxC,KAAKsxC,SAASxC,MAAQA,EACtB9uC,KAAKsxC,SAASvC,SAAWA,EACzB/uC,KAAKsxC,SAAShC,cAAgBA,EAC9BtvC,KAAKsxC,SAASnC,wBAA0BA,GChT5CpxC,GAAG4yC,KAAO,SAASxkC,EAAYhM,GAC3B,YAYA,SAASoxC,GAAkBC,GAIvB,IAHA,GAAIpsC,GAAS,EACTqsC,EAAM,EAEHD,EAAIpvC,OAAS,GAChBgD,GAAUi9B,SAASmP,EAAItyC,UAAU,EAAG,GAAI,IAAMmF,KAAKotC,IAAI,EAAGA,GAC1DD,EAAMA,EAAItyC,UAAU,EAAGsyC,EAAIpvC,QAC3BqvC,GAAO,CAGX,OAAOrsC,GAKX,QAASssC,GAAWC,EAAQzkC,GACxB,GAAI0kC,GAAYD,EACZE,EAAa3kC,CAwBjB,OAvBkB7O,UAAduzC,IACAA,EAAY,EACZC,EAAa,GAAI9zC,IAAGoP,SAGxBpP,GAAG6O,cAAcT,EAAYylC,EAAW,GAAG35B,KAAK,SAASu5B,GACrD,GACIM,GADA1wC,EAAQ,cAAcnC,KAAKuyC,EAG3BpwC,GACiB,MAAbA,EAAM,IACN0wC,EAAgBzP,SAASmP,EAAI3zC,MAAM,EAAG,GAAI,IAC1C6zC,EAAWE,EAAYE,EAAgB,EAAGD,IAG1CA,EAAWxkC,QAAQukC,GAIvBC,EAAWtkC,QAAQ,iCAIpBskC,EAIX,QAASE,KACL,GAAI7kC,GAAU,GAAInP,IAAGoP,OAgBrB,OAdApP,IAAG6O,cAAcT,EAAY,EAAG,GAAG8L,KAAK,SAASu5B,GACjB,IAAxBA,EAAI5pC,QAAQ,QACZsF,EAAQK,QAAQ,qBAGhBmkC,IAAaz5B,KAAK,SAAS05B,GACvBzkC,EAAQG,QAAQskC,IAEpB,SAASzxC,GACLgN,EAAQK,QAAQrN,OAKrBgN,EAIX,QAAS8kC,GAAeC,GACpB,GAAI/kC,GAAU,GAAInP,IAAGoP,OAMrB,OAJApP,IAAG6O,cAAcT,EAAY8lC,EAAY,GAAI,GAAGh6B,KAAK,SAASu5B,GAC1DtkC,EAAQG,QAAgB,SAARmkC,KAGbtkC,EAIX,QAASglC,GAAiBD,EAAWE,GACjC,GAAIjlC,GAAU,GAAInP,IAAGoP,OAWrB,OATApP,IAAG6O,cAAcT,EAAY8lC,EAAY,GAAI,GAAGh6B,KAAK,SAASu5B,GAC1D,MAAIW,GACOjlC,EAAQG,QAAQkkC,EAAkBC,QAGzCtkC,GAAQG,QAAQg1B,SAASmP,EAAK,OAI/BtkC,EAIX,QAASklC,GAAOH,EAAWI,GACvB,GAAIV,GAASM,EAAY,GACrBxlC,EAAqB,GAAb4lC,CAEZ,OAAOt0C,IAAG6O,cAAcT,EAAYwlC,EAAQllC,GAIhD,QAAS6lC,GAAcC,GAInB,IAHA,GAAIp3B,MACAw2B,EAAS,EAENA,EAAS,IAAMY,EAAOnwC,QACzB+Y,EAAQtb,KAAK0yC,EAAO10C,MAAM8zC,EAAQA,EAAS,KAC3CA,GAAU,EAGd,OAAOx2B,GAIX,QAASq3B,GAAaL,EAAcE,GAChC,GAAII,GAAiB,GACjBC,EAAa30C,GAAGwG,UAAWouC,GAC3BC,IAsBJ,OApBA70C,IAAGY,KAAK0zC,EAAY,SAAS1yC,EAAK25B,GAC9B,GAGIuZ,GAAWhoC,EAASioC,EAHpBC,EAAQzZ,EAAMz7B,MAAM,EAAG,GACvBud,EAAK+2B,EAAeZ,EAAkBwB,GAAS1Q,SAAS0Q,EAAO,IAC/DC,EAAgBN,EAAW9qC,QAAQwT,EAYvC,IATI43B,GAAiB,IACjBnoC,EAAUooC,EAAS73B,GAAIrc,KACvB+zC,EAAeG,EAAS73B,GAAI3O,MAC5BomC,EAAYvZ,EAAMz7B,MAAM40C,EAAgBA,EAAiC,EAAfK,GAC1DF,EAAK/nC,GAAWsnC,EAAeZ,EAAkBsB,GAAaxQ,SAASwQ,EAAW,IAElFH,EAAWz1B,OAAO+1B,EAAe,IAGX,IAAtBN,EAAWtwC,OACX,OAAO,IAIRwwC,EApJX,GAAID,IAAW,KACXM,GACIC,KACIn0C,KAAM,cACN0N,MAAO,GAmJnB1O,IAAGwG,OAAOvE,MAON0S,MAAO,WACH,GAAIygC,GAAS,GAAIp1C,IAAGoP,QAChBimC,EAAiB,SAAShzC,GACtBD,EAAIpC,GAAG0L,OAAO,kCAAmCrJ,IACjD+yC,EAAO5lC,QAAQnN,GA0BvB,OAvBA2xC,KAAgB95B,KAAK,SAASo7B,GAC1BlzC,EAAIpC,GAAG0L,OAAO,mDAAwEpL,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,OAEtHizC,EAAeqB,GAAYp7B,KAAK,SAASk6B,GAErChyC,EAAIpC,GAAG0L,OAAO,+BAAgC0oC,EAAe,SAAW,QAExED,EAAiBmB,EAAYlB,GAAcl6B,KAAK,SAASq7B,GAErDnzC,EAAIpC,GAAG0L,OAAO,kCAAmC6pC,IAEjDlB,EAAOiB,EAAYC,GAAer7B,KAAK,SAASs6B,GAC5C,GAAIF,GAAaC,EAAcC,GAC3BgB,EAAYf,EAAaL,EAAcE,EAE3ClyC,GAAI,sCAEJgzC,EAAO9lC,QAAQkmC,IAChBH,IACJA,IACJA,IACJA,GAEID,KAKfnzC,KAAKsxC,YACLtxC,KAAKsxC,SAASC,kBAAoBA,GC7MtCxzC,GAAGuyC,SAAW,SAASnkC,EAAYhM,GAC/B,YAEA,SAASqzC,GAAeC,EAAYC,GAChC,GAAIC,IAAe,EACfC,KAAuBziC,OAAOsiC,EASlC,OAPA11C,IAAGY,KAAKi1C,EAAmB,SAASj0C,EAAKk0C,GACrC,GAAwD,IAApDH,EAAkB9rC,QAAQisC,GAE1B,MADAF,IAAe,GACR,IAIRA,EAGX51C,GAAGwG,OAAOvE,MASNwwC,cAAe,WACX,GAAIzuC,GAAO/B,KACP0oB,EAAa,GAAI3qB,IAAGoP,QACpB2mC,GAAc,EACd/0C,EAA2BV,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,IAsC/D,OApCAoB,GAAIpC,GAAG0L,OAAO,gEAAiE1K,IAE/EoB,EAAI,oDAEAH,KAAK+zC,qBACL5zC,EAAI,sDAEJpC,GAAG6O,cAAcT,EAAY,EAAG,GAAG8L,KAAK,SAASu5B,GAC7CzzC,GAAGY,KAAKoD,EAAKiyC,uBAAwB,SAASxtC,EAAMiG,GAChD,GAAI+mC,EAAe/mC,EAAO+kC,GAQtB,OALa,eAAThrC,GAAyBzI,GAAGiW,kBAAkBwD,gBAC9Cs8B,GAAc,EACdprB,EAAWrb,QAAQ7G,KAGhB,IAIfrG,EAAIpC,GAAG0L,OAAO,iDAAkD1K,EAAM+0C,EAAc,GAAK,QAEpFA,GACDprB,EAAWnb,WAGnB,WACIpN,EAAI,+BAAiCpB,EAAO,gDAC5C2pB,EAAWnb,aAIfmb,EAAWnb,UAGRmb,GAWXqrB,kBAAmB,WACf,GAAIE,GAAW9nC,EAAWhL,KAEtB+yC,EAAoBn2C,GAAG6J,QAAQW,OAAO23B,KAAKlgC,KAAKg0C,wBAAyBC,IAAa,EACtFH,GAAc,EACd/0C,EAA2BV,SAApB8N,EAAWpN,KAAqB,OAASoN,EAAWpN,IAa/D,OAXIm1C,KAEIJ,EADa,eAAbG,GACcl2C,GAAGiW,kBAAkBwD,eAO1Cs8B,GAAe3zC,EAAIpB,EAAO,gEAEpB+0C,MAKnB/1C,GAAGuyC,SAAS/wC,UAAUy0C,wBAClBG,aAAc,SACdC,YAAa,SACbC,YAAa,SACbC,YAAa,OACbC,cAAe,WAAY,aCpG/Bx2C,GAAG23B,gBAAkB,SAAS7oB,EAAM1M,GAChC,YAMA,SAASq0C,GAAiBC,GACtB,GAAIC,IAAa,CASjB,OAPA32C,IAAGY,KAAK81C,EAAQ,SAASE,EAAOjsC,GAC5B,GAAIA,EAAQ,EAER,MADAgsC,IAAa,GACN,IAIRA,EAQX,QAASE,KACL,GAAIC,GAAoB,GAAI92C,IAAGoP,OA6B/B,OA3BA,IAAIpP,IAAGuyC,SAASzjC,EAAM1M,GAAKqwC,gBAAgBv4B,KAAK,WAC5C,GAAI2d,GAAQ,GAAImY,OACZjT,EAAM3zB,OAAO6mC,KAAO7mC,OAAO6mC,IAAIC,gBAAkB9mC,OAAO6mC,IAClD7mC,OAAO+mC,WAAa/mC,OAAO+mC,UAAUD,gBAAkB9mC,OAAO+mC,UAC9D,IAENpT,IACAlF,EAAMtoB,QAAU,WACZnN,EAAI,4DAA6D,SACjE00C,EAAkBtnC,WAGtBqoB,EAAMxoB,OAAS,WACXynC,EAAkBxnC,SACds9B,MAAO3qC,KAAK2qC,MACZ3wB,OAAQha,KAAKga,UAIrB4b,EAAMuY,IAAMrT,EAAImT,gBAAgBphC,KAGhC1M,EAAI,+DAAgE,SACpE00C,EAAkBtnC,YAEvBsnC,EAAkBtnC,SAEdsnC,EASX,QAASC,GAAgBL,EAAQM,GAC7B,GAAIC,EA0BJ,OAxBAj3C,IAAGY,KAAK81C,EAAQ,SAASQ,EAAWC,GAChC,GAAIA,EAAa,EAAG,CAChB,GAAIC,GAAe,0BAA0Bl2C,KAAKg2C,GAC9CG,EAAoBD,EAAa,GAAGx3C,OAAO,GAAGG,cAAgBq3C,EAAa,GAAGt3C,MAAM,GACpFw3C,EAAcN,EAAWK,EAG7B,QAAQD,EAAa,IACjB,IAAK,MACD,GAAIE,EAAcH,EAEd,MADAF,GAAeC,GACR,CAEX,MACJ,KAAK,MACD,GAAII,EAAcH,EAEd,MADAF,GAAeC,GACR,MAOpBD,EAWXh1C,KAAK21B,SAAW,SAAS8e,GACrB,GAAIa,GAAmB,GAAIv3C,IAAGoP,OAoB9B,OAlBAhN,GAAI,iCAEAq0C,EAAiBC,GACjBG,IAAiB38B,KAAK,SAAS88B,GAC3B,GAAIC,GAAeF,EAAgBL,EAAQM,EAEvCC,GACAM,EAAiB/nC,QAAQynC,GAGzBM,EAAiBjoC,WAEtBioC,EAAiBjoC,SAGpBioC,EAAiBjoC,UAGdioC,IC7Hfv3C,GAAG42B,QAAU,SAASvY,GAClB,YAaA,SAASm5B,GAAoB9jB,GACzB,QAAI1zB,GAAG8C,QAAQ4wB,QAIf10B,GAAQoD,IAAI,oCAAqC,SAGrD,QAASq1C,GAAgBC,EAAWpoC,EAAS0a,EAAU7a,GACnD,GAAIwoC,IAAmB,CAEvBroC,GAAUA,GAAWkoC,EAAoBE,GAErCpoC,GACAtP,GAAGY,KAAK82C,EAAW,SAAS91C,EAAKw+B,GAE7B,GAAqB,MAAjBA,EAAS5iB,KACTm6B,GAAmB,EACnB34C,EAAQoD,IAAIpC,GAAG0L,OAAO,oEAAqE9J,GAAM,aAEhG,IAAqB,MAAjBw+B,EAASp/B,KACd22C,GAAmB,EACnB34C,EAAQoD,IAAIpC,GAAG0L,OAAO,oEAAqE9J,GAAM,aAGjG,KAEI,MADA5C,GAAQ83B,cAAcsJ,IACf,EAEX,MAAOwX,GACHD,GAAmB,EACnB34C,EAAQoD,IAAIw1C,EAAIv1C,QAAS,SAIjC,OAAO,IAIf8M,EAAQG,IAAYqoC,EAAmB,UAAY,WAAWD,EAAW1tB,GAlD7E,GAAIhrB,IACA8hB,SAAU,KACVthB,UACAiqB,iBACAG,QACAkN,cAAe,SAAStO,KACxBpmB,IAAK,SAASC,EAAS+H,KAG3BpK,IAAGwG,OAAOxH,EAASqf,GAAM,GA8CzBpc,KAAK80B,QAAU,WAEX,GAAI8gB,GAAgB,GAAI73C,IAAGoP,QACvB0oC,EAA0B,SAASpkB,EAAUpkB,EAAS0a,GAClDytB,EAAgB/jB,EAAUpkB,EAAS0a,EAAU6tB,IAEjDE,EAAmB/3C,GAAGwG,UAAWxH,GACjCotC,EAAY,GAAIpsC,IAAGg4C,qBACfh4C,GAAGwG,OAAOuxC,GAAmBxqB,WAAYuqB,IAKjD,OAFA1L,GAAU6L,cAEHJ,ICrEf73C,GAAGg4C,qBAAuB,SAAS35B,GAC/B,YAiBA,SAASkP,GAAWlQ,EAAI2M,EAAUC,GAC9B,GAAIyJ,GAAW,IAGf,IAA6B,MAAzB1J,EAASkuB,aACT,IACIxkB,EAAW1zB,GAAGwU,UAAUwV,EAASkuB,cAErC,MAAON,GACH54C,EAAQoD,IAAI,qCAAuCw1C,EAAIv1C,QAAS,SAChE4nB,GAAU,EAIlBjrB,EAAQuuB,WAAWmG,GAAWzJ,EAASD,GA7B3C,GAAIoiB,GACAptC,GACI8hB,SAAU,KACV2I,iBACAjqB,UACAoqB,MACIoI,UAAU,EACVyI,iBAAiB,GAErBlN,WAAY,SAASmG,EAAUpkB,EAAS0a,KACxC5nB,IAAK,SAASuJ,EAAKvB,KAG3BpK,IAAGwG,OAAOxH,EAASqf,GAmBnB+tB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAe,OACfvV,OAAQ,MACRO,eACI5E,IAAK,WACD,MAAO/lB,GAAQ8hB,WAGvB2I,cAAezqB,EAAQyqB,cACvBrnB,IAAKpD,EAAQoD,IACbmrB,WAAYA,EACZ3D,KAAM5qB,EAAQ4qB,QAGlB5pB,GAAGwG,OAAOvE,MACNg2C,YAAa,WACT,GAAIz4C,GAASQ,GAAGwG,UAAWxH,EAAQQ,OAEnCR,GAAQoD,IAAI,0BAEZgqC,EAAUnN,cAAc,kBACnBK,WAAW9/B,GACXogC,kBACAjC,WCzDjB39B,GAAGgnB,OAAS,SAAS3I,EAAMjc,GACvB,YAEA,IACI2hB,GAAuB1F,EAAKsc,cAC5Bwd,EAAkB95B,EAAKuc,aACvBC,EAASxc,EAAKwc,OACdC,EAAczc,EAAKyc,YACnBC,EAAiB1c,EAAK0c,eAAiB,IACvCqd,EAAoB/5B,EAAK2c,YACzBC,EAAc5c,EAAK4c,YACnBC,EAAQj5B,KAAKo2C,gBAAgBh6B,EAAK6c,MAGtCl7B,IAAGwG,OAAOvE,MAGNihB,QAASljB,GAAGiW,kBAAkBuD,SAAW0hB,EAAM72B,OAAS,EAExDi0C,eAAgB,SAASC,EAAkBC,EAAkBC,GACzD,GAAIz0C,GAAO/B,KACPy2C,KACAC,EAAeF,EAAuB3pC,KAAO2pC,EAAuB3pC,KAAO2pC,EAC3E9tB,EAAa,GAAI3qB,IAAGuyC,SAASoG,EAAcv2C,EAiD/C,OA9CIuoB,GAAWqrB,qBAEXh2C,GAAGY,KAAKs6B,EAAO,SAASt5B,EAAKg3C,GACzB,GAAIC,GAAa70C,EAAK80C,sBAClBhe,YAAaA,EACbie,cAAeH,EAAWx1C,KAC1B41C,QAASL,EAAav1C,MAG1Bs1C,GAAQ52C,MACJ0b,KAAMxd,GAAGuQ,cACTvP,KAAMgD,EAAKi1C,SAAST,GAChBx3C,KAAM43C,EAAW53C,KACjBoC,KAAMy1C,EACNG,QAASL,EAAav1C,OAE1B0L,KAAM,GAAI9O,IAAG4a,UAAU+9B,EACvB34C,GAAGgT,KAAKhP,EAAKk1C,qBAAsBl1C,GAC/B+f,qBAAsBA,EACtBF,QAAS+0B,EAAW/0B,QACpBgX,OAAQA,EACRz3B,KAAMy1C,EACNnwC,QAASqyB,EACToe,WAAYf,EACZnd,YAAaA,EACb74B,IAAKA,SAKjBs2C,EAAQ52C,MACJ0b,KAAM+6B,EACNv3C,KAAMw3C,EACNh6B,KAAMm6B,EAAan6B,KACnB1P,KAAMqpC,EAAkBQ,EAAe,QAI3CD,EAAQ52C,MACJ0b,KAAM+6B,EACNv3C,KAAMw3C,EACNh6B,KAAMm6B,EAAan6B,KACnB1P,KAAM6pC,IAIPD,GAGXrd,cAAe,SAAShZ,EAAMrhB,EAAMwc,EAAMgB,EAAM4S,EAAU3S,EAAS6K,EAAe8vB,GAC9E,GAAIp1C,GAAO/B,KAEPo3C,GADWh3B,EAAKyG,YAAezG,EAAKvT,MAAQuT,EAAKvT,KAAKga,eAEtDwwB,EAAa,KACbpoB,EAAmBkoB,EAAIloB,iBACvBlO,EAAao2B,EAAIp2B,WACjB0G,EAAc0vB,EAAI1vB,YAClBhL,EAAe1e,GAAGuQ,aAEtBvQ,IAAGY,KAAKoD,EAAKs0C,eAAe96B,EAAMxc,EAAMqhB,GAAO,SAASzgB,EAAK23C,GACzD,GACIl8B,GADAm8B,EAAWD,EAAO/6B,IAGlB+6B,GAAOzqC,eAAgB9O,IAAG4a,YAC1B4+B,GAAW,GAGfn8B,EAAK2F,EAAW5E,SACZZ,KAAM+7B,EAAO/7B,KACbxc,KAAMu4C,EAAOv4C,KACbwd,KAAMg7B,EACN/6B,QAASA,EACTC,aAAcA,IAGd66B,EAAOzqC,eAAgB9O,IAAG4a,UAC1By+B,EAAUv3C,KAAKub,GAGfi8B,EAAaj8B,EAGbk8B,EAAOzqC,MACPoiB,EAAiB7T,EAAIk8B,EAAOzqC,MAC5BsiB,EAAStvB,MAAMub,GAAIA,EAAIgF,KAAMk3B,EAAOzqC,QAGpCkU,EAAWlE,UAAUzB,EAAIrd,GAAG2d,OAAOqC,YAOxB,OAAfs5B,IACAt5C,GAAGY,KAAKy4C,EAAW,SAASz3C,EAAK63C,GAC7B,GAAIj6C,IACAk6C,aAAc12B,EAAWpE,UAAUvB,GAAIi8B,IAAa97B,KACpDm8B,aAAc32B,EAAWpE,UAAUvB,GAAIi8B,IAAa96B,KAKxDhf,GAAO8pB,GAAiBtG,EAAWpE,UAAUvB,GAAIo8B,IAAWj8B,KAE5DwF,EAAWtD,YAAY+5B,EAAUH,GACjC5vB,EAAY+B,YAAYguB,EAAUj6C,KAKlC65C,EAAUh1C,SACT,WACG,GAAIu1C,KACJA,GAAMtwB,GAAiBtG,EAAWpE,UAAUvB,GAAIi8B,IAAa97B,KAC7DkM,EAAY+B,YAAY6tB,EAAYM,WAQ5D55C,GAAGwG,OAAOxG,GAAGgnB,OAAOxlB,WAChBslB,WAAY,SAASzJ,EAAI0J,EAAOqyB,GAC5B,YAEA,KAAKp5C,GAAGiW,kBAAkBuD,QACtB,KAAM,IAAIxZ,IAAGmG,MAAM,4CAGvB,IAAI0zC,GAAgB,GAAI75C,IAAGoP,QACvBhN,EAAMg3C,EAAIh3C,IACVigB,EAAO+2B,EAAI/0B,QAAQhH,GACnB2F,EAAao2B,EAAIp2B,WAAWpE,UAAUvB,GAAIA,IAC1Crc,EAAOgiB,GAAcA,EAAWhiB,KAChCwc,EAAOwF,GAAcA,EAAWxF,KAChCs8B,GACInf,cAAe5T,EAAM4T,cACrBC,cAAc,EACdC,OAAQ9T,EAAM8T,OACdC,YAAa/T,EAAM3jB,MAAQ,KAC3B23B,eAAgBhU,EAAMre,QACtB0vC,kBAAmB,kBACnBld,QAASl6B,KAAM,GAAI6iB,QAASkD,EAAMlD,WAEtCk2B,EAAS,GAAI/5C,IAAGgnB,OAAO8yB,EAAgB13C,EAuB3C,OArBKpC,IAAGgnB,QAAWhnB,GAAGiW,kBAAkBiD,eAAkBmJ,EAOrDriB,GAAGgT,KAAK,WAEL,GAAIumC,GAASQ,EAAOzB,eAAe96B,EAAMxc,EAAMqhB,GAAM,EAEjDk3B,IAAUA,EAAOzqC,eAAgB9O,IAAG4a,UACpC2+B,EAAOzqC,KAAKiM,SAASb,KAAK2/B,EAAcvqC,QAASuqC,EAAcrqC,UAG/DpN,EAAIib,EAAK,4BAA6B,SACtCw8B,EAAcrqC,YAEnBvN,SAjBH43C,EAAcrqC,UAEdpN,EAAI,iDAAmDib,EAAK,uFAC6B,UAiBtFw8B,GAKXf,qBAAsB,SAASz6B,GAC3B,YAEA,IAAI06B,GAAgB16B,EAAK06B,cACrBje,EAAczc,EAAKyc,YACnBkf,EAAgB37B,EAAK26B,OAIzB,OAAKle,IAAgBie,EAQhBA,GAKD/4C,GAAG6J,QAAQW,OAAO23B,KAAKniC,GAAGuyC,SAAS/wC,UAAUy0C,wBAAyB8C,IAAkB,EAClE,eAAlBA,EACO/4C,GAAGiW,kBAAkBwD,aAAes/B,EAAgBje,EAGxDie,EATAje,EARe,eAAlBkf,EACO,YAEJA,GAqBff,SAAU,SAAS16B,EAAc07B,GAC7B,YAEA,IAAIC,GAAa37B,EAAavJ,YAAY,KACtCmlC,EAAcF,EAAwB72C,MAAQ,YAC9C42C,EAAgBC,EAAwBjB,QACxCoB,EAAa,GACbC,EAAYr6C,GAAG6U,aAAa0J,GAC5B+7B,EAAgB,EAmBpB,OAjBIL,GAAwBj5C,MAAQi5C,EAAwBj5C,KAAKyK,OAAOpH,SACpEi2C,EAAgB,KAAOL,EAAwBj5C,KAAO,KAGtDk5C,GAAc,GACdE,EAAa77B,EAAatJ,OAAO,EAAGilC,GAEhCF,IAAkBG,IAClBE,EAAYF,EAAYvwC,MAAM,KAAK,IAGvCwwC,GAAcE,EAAgB,IAAMD,GAGpCD,EAAa77B,EAAe+7B,EAGzBF,GAIX/B,gBAAiB,SAASnd,GACtB,YAIA,OAFAA,GAAQl7B,GAAGwG,UAAW00B,GAEfA,EAAMqf,KAAK,SAASC,EAAGC,GAC1B,MAAID,GAAE32B,QAAU42B,EAAE52B,QACP,EAEP22B,EAAE32B,QAAU42B,EAAE52B,SACP,EAEJ,KAIfq1B,qBAAsB,SAAS76B,EAAMq8B,GACjC,YAEA,IAAI12C,GAAO/B,KACP8hB,EAAuB1F,EAAK0F,qBAC5B3hB,EAAMic,EAAKjc,IACXyhB,EAAUxF,EAAKwF,QACfgX,EAASxc,EAAKwc,OACdz3B,EAAOib,EAAKjb,KACZsF,EAAU2V,EAAK3V,QACfywC,EAAa96B,EAAK86B,WAClBle,EAAc5c,EAAK4c,aAAmC,eAApByf,EAAWt3C,MAAkC,eAATA,EACtEy2C,EAAgB,GAAI75C,IAAGoP,QACvBurC,EAAiB,GAAI36C,IAAGm7B,eAAe/4B,GACvCoG,EAAS2E,SAASC,cAAc,SA8BpC,OA5BAhL,GAAI,6CAA+Cs4C,EAAW15C,MAE9D25C,EAAep2B,SAASm2B,EAAYlyC,GAASqb,QAASA,EAASgX,OAAQA,EAAQ9W,qBAAsBA,IAAuB7J,KAAK,WAC7H,GAAI0gC,GAAqBpyC,EAAOI,UAAUxF,EAAMsF,GAC5CmyC,EAAgB,WACZz4C,EAAI,yCAA2Cs4C,EAAW15C,KAC1D,IAAI8N,GAAO9O,GAAG2I,cAAciyC,EAC5Bf,GAAcvqC,QAAQR,GAG1BmsB,GACAj3B,EAAK82C,kBAAkBJ,EAAYE,EAAoBx4C,GAAK8X,KAAK,SAAS6gC,GACtEH,EAAqBG,EACrBF,KAEJ,WACIz4C,EAAI,wFAAyF,SAC7Fy4C,MAIJA,KAEL,WACCz4C,EAAI,iDAAmDs4C,EAAW15C,KAAM,SACxE64C,EAAcrqC,QAAQ2pC,KAGnBU,GAIXiB,kBAAmB,SAASE,EAAeJ,EAAoBx4C,GAC3D,YAEA,IAAI64C,GAAS,GAAI/rC,YACbgsC,EAAkB,GAAIl7C,IAAGoP,QACzB+rC,EAAuB,EAc3B,OAZAF,GAAO5rC,OAAS,WACZ8rC,EAAuBF,EAAO5zC,OAC9B6zC,EAAgB5rC,QAAQtP,GAAGo7C,aAAahM,QAAQ+L,EAAsBP,KAG1EK,EAAO1rC,QAAU,WACbnN,EAAI,mBAAqB44C,EAAch6C,KAAO,2DAA4D,SAC1Gk6C,EAAgB1rC,WAGpByrC,EAAOI,cAAcL,GAEdE,GAGXI,eAAgB,SAASzyC,GACrB,YAEA,IAAIE,GAAYE,EAAYH,EAAaE,CAsBzC,OAlBID,GADAF,EAAQe,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKjB,EAAQe,MAAM,KAAK,IAGxBG,UAAUlB,EAAQe,MAAM,KAAK,IAI9CX,EAAaJ,EAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBd,EAAc,GAAIkB,aAAYjB,EAAW1E,QACzC2E,EAAW,GAAIiB,YAAWnB,GAC1B9I,GAAGY,KAAKmI,EAAY,SAASnH,EAAKsI,GAC9BlB,EAASpH,GAAOsI,EAAUC,WAAW,KAGlClI,KAAKs5C,YAAYzyC,EAAaG,IAGzCsyC,YAAa,SAASl7C,EAAMoI,GACxB,YAEA,IAAIU,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOpJ,GACZmJ,EAAYE,QAAQjB,IAGpB,GAAIkB,OAAMtJ,IAAQ+C,KAAMqF,OChZ3CzI,GAAGo7C,aAAe,WAGjB,GAAIA,KA+KD,OA7KAA,GAAaI,QAAU;AAMvBJ,EAAaK,SAAW,SAASvuC,GAE7B,GACIwuC,GAAMC,EACNC,EAAMC,EAAMC,EAFZC,EAAS,GACGC,EAAO,GACDC,EAAO,GACzBpoC,EAAI,CAER,GACI6nC,GAAOxuC,EAAM2G,KACb8nC,EAAOzuC,EAAM2G,KACbmoC,EAAO9uC,EAAM2G,KAEb+nC,EAAOF,GAAQ,EACfG,GAAgB,EAAPH,IAAa,EAAMC,GAAQ,EACpCG,GAAgB,GAAPH,IAAc,EAAMK,GAAQ,EACrCC,EAAc,GAAPD,EAEHE,MAAMP,GACPG,EAAOG,EAAO,GACNC,MAAMF,KACdC,EAAO,IAGVF,EAASA,EACN95C,KAAKu5C,QAAQ57C,OAAOg8C,GACpB35C,KAAKu5C,QAAQ57C,OAAOi8C,GACpB55C,KAAKu5C,QAAQ57C,OAAOk8C,GACpB75C,KAAKu5C,QAAQ57C,OAAOq8C,GACvBP,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SACvBpoC,EAAI3G,EAAM7I,OAEnB,OAAO03C,IAGXX,EAAahM,QAAU,SAAS+M,EAAgBC,GAE5C,GAAIC,GAAuB,yBAE3B,KAAKF,EAAe94C,MAAMg5C,GAEzB,MAAOD,EAGR,IAAIE,GAAWr6C,KAAKs6C,SAASJ,EAAel1C,QAAQo1C,EAAsB,KACtEG,EAAWv6C,KAAKw6C,eAAeH,GAE/BzkB,EAAQ51B,KAAKy6C,iBAAiBN,EAAmBI,EAErD,OAAOH,GAAuBp6C,KAAKw5C,SAAS5jB,IAKhDujB,EAAasB,iBAAmB,SAASN,EAAmBI,GAEpD,GAAIG,GAAY16C,KAAK26C,aAAaJ,GAC9BK,EAAgB56C,KAAK66C,WAAWV,EAAmBO,GACnDI,EAAU,GAAI9yC,YAAW4yC,EAE7B,OAAOE,IAIf3B,EAAawB,aAAe,SAASJ,GAG7B,IAAK,GADDQ,GACKC,EAAI,EAAGA,EAAIT,EAASn4C,OAAQ44C,IAGjC,GADAD,EAAMR,EAASS,GACD,KAAVD,EAAI,GAAsB,KAAVA,EAAI,GAEpB,MAAOA,EAGf,WAIR5B,EAAa0B,WAAa,SAASV,EAAmBO,GAE9C,GAAIO,GAAYd,EAAkBn1C,QAAQ,0BAA2B,IACjEk2C,EAAMl7C,KAAKs6C,SAASW,GACpBE,EAAgBD,EAAItzC,QAAQ,IAAI,GAChCwzC,EAAMF,EAAIr9C,MAAM,EAAGs9C,GACnBE,EAAMH,EAAIr9C,MAAMs9C,GAChBG,EAAQF,CAIb,OAFCE,GAAQA,EAAMnqC,OAAOupC,GACrBY,EAAQA,EAAMnqC,OAAOkqC,IAM7BlC,EAAaqB,eAAiB,SAASe,GAKnC,IAHA,GAAIC,GAAO,EACPjB,OAGJ,CACI,GAA2B,KAAvBgB,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAAW,KACjE,IAA2B,KAAvBD,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAElDA,GAAQ,MAGZ,CACI,GAAIp5C,GAAmC,IAA1Bm5C,EAAcC,EAAO,GAAWD,EAAcC,EAAO,GAC9DC,EAAWD,EAAOp5C,EAAS,EAC3B24C,EAAMQ,EAAc19C,MAAM29C,EAAMC,EACpClB,GAAS16C,KAAKk7C,GACdS,EAAOC,EAEX,GAAID,EAAOD,EAAcn5C,OAAQ,MAGrC,MAAOm4C,IAKXpB,EAAamB,SAAW,SAASrvC,GAE7B,GACIwuC,GAAMC,EACNC,EAAMC,EAAMC,EADAE,EAAO,GACDC,EAAO,GACzBpoC,EAAI,EACJspC,KAGAQ,EAAa,qBACjB,IAAIA,EAAWz8C,KAAKgM,GAChB,KAAM,IAAI/G,OAAM,uHAGpB+G,GAAQA,EAAMjG,QAAQ,sBAAuB,GAE7C,GACI20C,GAAO35C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCgoC,EAAO55C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCioC,EAAO75C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MACzCooC,EAAOh6C,KAAKu5C,QAAQ3xC,QAAQqD,EAAMtN,OAAOiU,MAEzC6nC,EAAQE,GAAQ,EAAMC,GAAQ,EAC9BF,GAAgB,GAAPE,IAAc,EAAMC,GAAQ,EACrCE,GAAgB,EAAPF,IAAa,EAAKG,EAE3BkB,EAAIr7C,KAAK45C,GAEG,IAARI,GACDqB,EAAIr7C,KAAK65C,GAEA,IAARM,GACDkB,EAAIr7C,KAAKk6C,GAGZN,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SAEvBpoC,EAAI3G,EAAM7I,OAEnB,OAAO84C,IAIJ/B,KC7KXp7C,GAAGs7B,cAAgB,SAAS1oB,EAAUyS,GAClC,YAEA,IAAIu4B,MACAC,EAAc,EACdC,EAAY,EAEZC,GAAiB,EACjBC,GAAgB,EAChBC,EAAgB,SAAS7wB,EAAQC,GACzBD,IAAW2wB,GAAkB1wB,IAAU2wB,GACvCprC,EAASwa,EAAQC,GAGrB0wB,EAAiB3wB,EACjB4wB,EAAgB3wB,GAQpB6wB,EAAmB,SAAS7pB,EAAQ8pB,GAChC,GAAIC,IAAO,CASX,OAPAp+C,IAAGY,KAAKyzB,EAAQ,SAASzyB,EAAKy8C,GAC1B,GAAIr+C,GAAG6J,QAAQs0C,EAAWE,IAAa,EAEnC,MADAD,IAAO,GACA,IAIRA,GAGX3wB,EAAW,SAASpQ,GAChBihC,EAAoBjhC,GAAI,GAAI,SACrBugC,GAAgBvgC,IAG3BiX,EAAgB,SAASF,EAAYC,EAAQ8pB,IACnB,IAAlB9pB,EAAOhwB,QAAgB65C,EAAiB7pB,EAAQ8pB,MAChDF,EAAcH,EAAWA,GACzB77C,KAAK8a,UAIbwhC,EAAQ,SAASlhC,GACb,GAAImB,GAAO6G,EAAQhI,EAGfmB,GAAO,IACP8/B,EAAoBjhC,EAAI,EAAGmB,GAC3Bo/B,EAAgBvgC,IAAO+P,OAAQ,EAAGC,MAAO7O,KAYjD8/B,EAAsB,SAASjhC,EAAImhC,EAAWC,GAC1C,GAAIC,GAAYd,EAAgBvgC,GAAMugC,EAAgBvgC,GAAI+P,OAAS,EAC/DuxB,EAAWf,EAAgBvgC,GAAMugC,EAAgBvgC,GAAIgQ,MAAQ,CAE7DmxB,MAAc,GAAMC,KAAa,GACjCZ,GAAea,EACfZ,GAAaa,IAGTH,IACAX,GAAeW,EAAYE,GAE3BD,IACAX,GAAaW,EAAWE,IAIhCV,EAAcJ,EAAaC,GAGnC99C,IAAGwG,OAAOvE,MAENqyB,cAAeA,EAGf3V,eAAgB,SAAStB,EAAI2B,EAAWD,GAChCA,IAAc/e,GAAG2d,OAAOuC,UAAYnB,IAAc/e,GAAG2d,OAAOqC,SAC5DyN,EAASpQ,GAEJ0B,IAAc/e,GAAG2d,OAAOW,YAC7BigC,EAAMlhC,IAKd4X,qBAAsB,SAAS5X,EAAI+P,EAAQC,GACvCixB,EAAoBjhC,EAAI+P,EAAQC,GAChCuwB,EAAgBvgC,IAAO+P,OAAQA,EAAQC,MAAOA,IAIlD6J,UAAW,SAAS7Z,GAChBkhC,EAAMlhC,IAGVN,MAAO,WACH6gC,KACAC,EAAc,EACdC,EAAY,MCzHxB99C,GAAGoqB,aAAe,SAASnP,GACvB,YAYA,SAAS2jC,GAAQ1zC,GACb,MAAOA,GAAK9H,MACwB,IAAhC8H,EAAK9H,KAAKyG,QAAQ,UAG1B,QAASg1C,KACLC,EAAqB9+C,GAAGhB,EAAQqrB,eAAellB,OAAO,QAAS,SAASuxB,GACpE,GAAIqoB,GAAgBroB,EAAMqoB,aAEtBA,IACA/+C,GAAGY,KAAKm+C,EAAclxC,MAAO,SAASjM,EAAKsJ,GACvC,GAAI0zC,EAAQ1zC,GAAO,CACf,GAAI4D,GAAO5D,EAAK8zC,WAChBhgD,GAAQ2B,UAAU4pB,cAAczb,QAOpD,QAASmwC,KACDH,GACAA,IAhCR,GAAI9/C,GAAS8/C,CAEb9/C,IACIqrB,cAAe,KACf1pB,WACIyB,IAAK,SAASC,EAAS+H,KACvBmgB,cAAe,SAASzb,OA8BhC9O,GAAGwG,OAAOxH,EAASic,GACnB4jC,IAEA7+C,GAAGwG,OAAOvE,MACN8a,MAAO,WACHkiC,QCpCZj/C,GAAGyxB,YAAc,SAASzyB,EAASkgD,EAAa98C,GAC5C,YAgCA,SAAS+8C,GAAqBC,GACtBA,EAAO92C,aAAa,YACpBtE,EAAK8tB,YAAcstB,EAAO92C,aAAa,WAM/C,QAAS+2C,GAAaD,EAAQE,GAC1B,QAAIF,EAAOG,gBAAkBH,EAAOG,mBAChCn9C,EAAI,yDAA0D,aAC9Dk9C,MAQR,QAASE,GAAoBJ,GACzB,GAAIE,GAAeF,EAAOK,MAG1Bz/C,IAAGo/C,GAAQj6C,OAAO,SAAU,SAASuxB,GACjCA,EAAQA,GAASttB,OAAOstB,MAEpBA,EAAMtkB,eACNskB,EAAMtkB,iBAGNskB,EAAMpkB,aAAc,EAGxB+sC,EAAaD,EAAQE,IAAiBJ,MAK1CE,EAAOK,OAAS,WACZJ,EAAaD,EAAQE,IAAiBJ,KAM9C,QAASQ,GAAgBN,GAarB,MAZIA,KACIp/C,GAAGoL,SAASg0C,KACZA,EAASjyC,SAAS85B,eAAemY,IAGjCA,IACAh9C,EAAI,8BACJ+8C,EAAqBC,GACrB1kB,GAAmB8kB,EAAoBJ,KAIxCA,EAzFX,GAAIp7C,GAAQ/B,KACRy4B,EAAkB17B,EAAQ07B,gBAC1B0kB,EAASpgD,EAAQ0D,QACjBkvB,EAAa5yB,EAAQ4yB,UAGzB5xB,IAAGwG,OAAOvE,MAIN6vB,YAAa,KAIbD,cAAeD,EAGfF,gBAAgB,EAGhBC,sBAAuB,WAEnB,MAAc,OAAVytB,EACO,KAGJp7C,EAAK27C,UAAUP,MAkE9BA,EAASM,EAAgBN,GACzBn9C,KAAKyvB,iBAAmB0tB,GAG5Bp/C,GAAGwG,OAAOxG,GAAGyxB,YAAYjwB,WAGrBm+C,UAAW,SAAStrC,GAChB,YACA,IAAIf,MACAssC,EAAoB,SAASx8C,GACzB,GAAIy8C,IACA,SACA,QACA,QACA,SAGJ,OAAO7/C,IAAG6J,QAAQg2C,EAAiBz8C,EAAKrD,eAAiB,GAE7D+/C,EAAkB,SAAS18C,GACvB,MAAOpD,IAAG6J,SAAS,WAAY,SAAUzG,EAAKrD,gBAAkB,GAEpEggD,EAAc,SAAS37C,GACnB,SAAI07C,EAAgB17C,EAAGhB,OAAUgB,EAAG47C,UAI7B57C,EAAGiS,UAAsC,WAA1BjS,EAAGhB,KAAKrD,eAElCkgD,EAAc,SAASC,GACnB,GAAIv1C,GAAQ,IASZ,OAPA3K,IAAGY,KAAKZ,GAAGkgD,GAAQx4C,WAAY,SAAS9F,EAAK+F,GACzC,GAAoC,WAAhCA,EAAMmF,QAAQ/M,eAA8B4H,EAAMw4C,SAElD,MADAx1C,GAAQhD,EAAMgD,OACP,IAIRA,EAmBf,OAhBA3K,IAAGY,KAAKyT,EAAK+rC,SAAU,SAASx+C,EAAKwC,GACjC,IAAKpE,GAAGwM,QAAQpI,GAAI,IAAsC,aAA7BA,EAAG0I,QAAQ/M,gBACpC6/C,EAAkBx7C,EAAGhB,OACpB28C,EAAY37C,IAIZ,GAAiC,WAA7BA,EAAG0I,QAAQ/M,gBAA+BggD,EAAY37C,GAAK,CAChE,GAAIuG,GAAQs1C,EAAY77C,EAEV,QAAVuG,IACA2I,EAAIlP,EAAGpD,MAAQ2J,QANnB2I,GAAIlP,EAAGpD,MAAQoD,EAAGuG,QAWnB2I,KCzJftT,GAAGilC,YAAcjlC,GAAGilC,gBACpBjlC,GAAGilC,YAAYyB,kBAAoB,SAAS1nC,EAASkhC,GACjD,YAUA,SAASmgB,GAAqBhjC,EAAI2pB,GAG9B,GAAItT,GAAU4sB,EAAKC,CAGnB,KAEID,EAAMtZ,EAAOe,iBAAmBf,EAAOwZ,cAAcrzC,SACrDozC,EAAYD,EAAIhZ,KAAK50B,UAErBtQ,EAAI,yCACJA,EAAI,eAAiBm+C,GAEjBA,GAAaA,EAAUl9C,MAAM,YAC7Bk9C,EAAYD,EAAIhZ,KAAK1/B,WAAWA,WAAW64C,WAG/C/sB,EAAW3C,EAAQ2W,mBAAmB6Y,GAE1C,MAAOp+C,GACHC,EAAI,wDAA0DD,EAAME,QAAU,IAAK,SACnFqxB,GAAYpkB,SAAS,GAGzB,MAAOokB,GAMX,QAASgtB,GAAWrjC,EAAI2pB,GACpB,GAAIxnC,GAASR,EAAQ0qB,YAAY3E,IAAI1H,GACjC+L,EAA0C,QAAjCpqB,EAAQoqB,OAAOrpB,cAA0B,MAAQ,OAC1D+gB,EAAW9hB,EAAQ2qB,cAAc5E,IAAI1H,GACrCrc,EAAOmiB,EAAQ9F,EAKnB,OAHA7d,GAAOR,EAAQwqB,UAAY5D,EAAQvI,GACnC7d,EAAOR,EAAQu5B,eAAiBv3B,EAEzB+vB,EAAQkX,oBACX7e,OAAQA,EACRtI,SAAUA,EACVthB,OAAQA,EACRi5B,aAAcz5B,EAAQy5B,aACtByP,WAAYlB,EAAOhmC,OArD3B,GAAI+vB,GAAU9uB,KACVkhB,EAAU+c,EAAM/c,QAChByC,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,GAsDhBH,MAAK0iC,WAAa,SAAStnB,GACvB,GAGIhJ,GAHAnH,EAAQ6jB,EAAQtU,SAASY,GACzB2pB,EAASjW,EAAQiX,cAAc3qB,GAC/BlO,EAAU,GAAInP,IAAGoP,OA8BrB,OA3BAiF,GAAOqsC,EAAWrjC,EAAI2pB,GACtB3yB,EAAKE,YAAYrH,GAEjB6jB,EAAQ8W,iBAAiBb,EAAQ,SAAS2Z,GACtCv+C,EAAI,gBAEJ,IAAIsxB,GAAWitB,EAAsBA,EAAsBN,EAAqBhjC,EAAI2pB,EAEpFjW,GAAQ4W,iBAAiBtqB,GAGpBre,EAAQ4qB,KAAKoI,UACdhyB,GAAGgnC,GAAQjhC,SAGX2tB,EAASpkB,QACTH,EAAQG,QAAQokB,GAGhBvkB,EAAQK,QAAQkkB,KAIxBtxB,EAAI,8BAAgCib,GACpChJ,EAAKorC,SACLz/C,GAAGqU,GAAMtO,SAEFoJ,GAGXnP,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAG0mC,mBACnB1nC,SACI6nC,OAAQ7nC,EAAQ4qB,KAAKoI,SACrBtF,UAAW1tB,EAAQ0tB,WAGvBwT,OACIzS,SAAUzuB,EAAQyuB,SAClBtK,QAASA,EACTyC,QAASA,EACTxjB,IAAKA,OC5GjBpC,GAAGilC,YAAcjlC,GAAGilC,gBACpBjlC,GAAGilC,YAAYmD,iBAAmB,SAAS/pB,EAAM6hB,GAC7C,YAEA,IAAInP,GAAU9uB,KACVkhB,EAAU+c,EAAM/c,QAChBkC,EAAU6a,EAAM7a,QAChBO,EAAUsa,EAAMta,QAChBxjB,EAAM89B,EAAM99B,IACZw+C,EAAYviC,EAAKma,gBAAkBna,EAAKoa,aAExCooB,EAA4B,SAASxjC,EAAI7d,EAAQyuB,GAC7C,GAAIzP,GAAO6G,EAAQhI,GACfrc,EAAOmiB,EAAQ9F,EAEnB7d,GAAO6e,EAAK5F,SAASshB,WAAWC,WAAa/L,EAAUqc,KACvD9qC,EAAO6e,EAAK5F,SAASshB,WAAWE,gBAAkBhM,EAAU5f,MAC5D7O,EAAO6e,EAAK5F,SAASshB,WAAWG,WAAajM,EAAUzP,KACvDhf,EAAO6e,EAAK5F,SAASshB,WAAWK,YAAcnM,EAAUsc,MACxD/qC,EAAO6e,EAAKqa,mBAAqBla,EAM7BoiC,IACAphD,EAAO6e,EAAKka,eAAiBv3B,IAIrC8/C,EAAyB,GAAI9gD,IAAGilC,YAAY8b,4BACxCn3B,KAAMvL,EAAKuL,KACX9I,SAAUzC,EAAK5F,SAASnJ,QAAQwR,SAChC1e,IAAKA,IAGT4+C,EAAiC,SAAS3jC,EAAI3G,GAC1C,GAAIvH,GAAU,GAAInP,IAAGoP,OAerB,OAbAsH,GAAI4mB,mBAAqB,WACrB,GAAuB,IAAnB5mB,EAAIsnB,WAAkB,CACtB,GAAI32B,GAAS45C,EAAwB5jC,EAAI3G,EAErCrP,GAAOiI,QACPH,EAAQG,QAAQjI,EAAOqsB,SAAUhd,GAGjCvH,EAAQK,QAAQnI,EAAOqsB,SAAUhd,KAKtCvH,GAGX+xC,EAA0B,SAAS7jC,GAC/B,GAAI7d,GAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9Brc,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,EAOnB,OALA7d,GAAO6e,EAAKmL,UAAY5D,EAAQvI,GAChC7d,EAAO6e,EAAKka,eAAiBv3B,EAC7BxB,EAAO6e,EAAKqa,mBAAqBla,EACjChf,EAAO6e,EAAK5F,SAASshB,WAAWK,YAAcrJ,EAAQgS,gBAAgB1lB,GAE/D7d,GAGX2hD,EAAwB,SAASzqC,EAAKgd,GAClC,MAAO1zB,IAAG6J,SAAS,IAAK,IAAK,IAAK,IAAK,KAAM6M,EAAIiH,QAAU,IACtD+V,EAASpkB,SACVokB,EAAS3W,OAGjBkkC,EAA0B,SAAS5jC,EAAI3G,GACnC,GAAIgd,EAOJ,OALAtxB,GAAI,sCAAwCib,GAC5Cjb,EAAI,kBAAoBsU,EAAIwhC,cAE5BxkB,EAAW0tB,GAAc,EAAM1qC,IAG3BpH,SAAU6xC,EAAsBzqC,EAAKgd,GACrCA,SAAUA,IAKlB0tB,EAAgB,SAAS5zC,EAAQkJ,GAC7B,GAAIgd,KAEJ,KACItxB,EAAIpC,GAAG0L,OAAO,4CAA6CgL,EAAIiH,OAAQjH,EAAIwhC,eAC3ExkB,EAAW1zB,GAAGwU,UAAUkC,EAAIwhC,cAEhC,MAAO/1C,GACHqL,GAAUpL,EAAI,qDAAuDD,EAAME,QAAU,IAAK,SAG9F,MAAOqxB,IAGX2tB,EAA4B,SAAShkC,GACjC,GAAIlO,GAAU,GAAInP,IAAGoP,OAcrB,OAZA0xC,GAAuBQ,SACfjkC,EACA0T,EAAQgZ,WAAW1sB,GACnB6jC,EAAwB7jC,GACxBgB,EAAKoL,cAAc1E,IAAI1H,IAE1BnD,KAAK,SAASxD,GACXvH,EAAQG,QAAQ8xC,GAAc,EAAO1qC,GAAMA,IAC5C,SAASA,GACRvH,EAAQK,QAAQ4xC,GAAc,EAAO1qC,GAAMA,KAG5CvH,GAGXoyC,EAA8B,SAAS/hD,EAAQkX,EAAKtI,EAAYiP,GAC5D,GAAInJ,GAAW,GAAI5G,UACf8b,EAAS/K,EAAK+K,OACdtI,EAAWzC,EAAKsL,cAAc5E,IAAI1H,GAClCrc,EAAOmiB,EAAQ9F,GACfmB,EAAO6G,EAAQhI,EAuBnB,OArBA7d,GAAO6e,EAAKmL,UAAY5D,EAAQvI,GAChC7d,EAAO6e,EAAKka,eAAiBv3B,EAEzB4/C,IACAphD,EAAO6e,EAAKqa,mBAAqBla,GAIhCH,EAAKoa,eACDmoB,IACDphD,EAAO6e,EAAKqO,WAAa1rB,GAE7B8f,EAAW9gB,GAAGqT,QAAQ7T,EAAQshB,IAGlCpK,EAAI+mB,KAAKrU,EAAQtI,GAAU,GAEvBzC,EAAKuL,KAAKoI,UAAY3T,EAAKuL,KAAK6Q,kBAChC/jB,EAAIC,iBAAkB,GAGtBiqC,GACIviC,EAAKoa,cACLz4B,GAAGiU,aAAazU,EAAQ0U,GAG5BA,EAASzK,OAAO4U,EAAKqO,UAAWte,GACzB8F,GAGJ9F,GAGXozC,EAAmB,SAASnkC,EAAI3G,GAC5B,GAAI+qC,GAAepjC,EAAKoL,cAAc1E,IAAI1H,GACtCjP,EAAa2iB,EAAQ1M,QAAQhH,EAEjC3G,GAAI4nB,iBAAiB,SAAU,oBAC/B5nB,EAAI4nB,iBAAiB,mBAAoB,kBACzC5nB,EAAI4nB,iBAAiB,gBAAiB,YAEjCsiB,IACDlqC,EAAI4nB,iBAAiB,eAAgB,4BAErC5nB,EAAI4nB,iBAAiB,cAAelwB,EAAWhL,OAGnDpD,GAAGY,KAAK6gD,EAAc,SAASzgD,EAAMZ,GACjCsW,EAAI4nB,iBAAiBt9B,EAAMZ,KAIvCJ,IAAGwG,OAAOvE,MACNmhC,YAAa,SAAS/lB,EAAI2jB,EAAUzG,GAChC,GAGIprB,GAASuyC,EAAQliD,EAHjByuB,EAAY8C,EAAQkQ,cAAc5jB,EAAI2jB,GACtCtqB,EAAMqa,EAAQgZ,WAAW1sB,EAAI2jB,EACtB3b,GAAQhI,EAgBnB,OAbAlO,GAAU6xC,EAA+B3jC,EAAI3G,GAC7Cqa,EAAQqa,yBAAyB/tB,EAAI2jB,EAAU/S,EAAUzP,MACzDhf,EAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9BwjC,EAA0BxjC,EAAI7d,EAAQyuB,GAElCsM,IACA/6B,EAAO6e,EAAK9E,OAAOwgB,WAAWQ,WAAY,GAG9CmnB,EAASH,EAA4B/hD,EAAQkX,EAAKuX,EAAUnf,KAAMuO,GAClEmkC,EAAiBnkC,EAAI3G,GACrBA,EAAIinB,KAAK+jB,GAEFvyC,GAGXw1B,WAAY,SAAStnB,GACjB,GACIlO,GAASuH,EAAKlX,EAAQkiD,EADtBtzC,EAAa2iB,EAAQ1M,QAAQhH,EAWjC,OARA3G,GAAMqa,EAAQgZ,WAAW1sB,GACzB0T,EAAQqa,yBAAyB/tB,GACjClO,EAAU6xC,EAA+B3jC,EAAI3G,GAC7ClX,EAAS6e,EAAKqL,YAAY3E,IAAI1H,GAC9BqkC,EAASH,EAA4B/hD,EAAQkX,EAAKtI,EAAYiP,GAC9DmkC,EAAiBnkC,EAAI3G,GACrBA,EAAIinB,KAAK+jB,GAEFvyC,KAIfnP,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGooC,kBACnBppC,QAASgB,GAAGwG,QAAQ7G,UAAW,eAAgB0e,GAC/C6hB,MAAOlgC,GAAGwG,QAAQqe,YAAaxG,EAAKsL,cAAc5E,KAAMmb,MAG5DlgC,GAAG4P,SAAS3N,KAAM,SAAS8N,GACvB,OACIuxB,eAAgB,SAASjkB,GACrB,MAAIgB,GAAK5F,SAASnJ,QAAQwR,SACfugC,EAA0BhkC,GAG1BtN,EAAOuxB,eAAejkB,EAAIrd,GAAGgT,KAAKouC,EAAen/C,MAAM,SCvOlFjC,GAAGilC,YAAY8b,2BAA6B,SAAS9lC,GACjD,YAEA,IAAImxB,GACAhjB,EAAS,OACTpqB,GACI4qB,MACIqI,UAAU,EACVD,UAAU,EACVyI,iBAAiB,GAErB3Z,SAAU,KACV1e,IAAK,SAASuJ,EAAKvB,MAEvBu3C,KACAC,GACI78B,IAAK,SAAS1H,GACV,MAAOre,GAAQ8hB,UAI3B9gB,IAAGwG,OAAOxH,EAASic,GAEnBmxB,EAAYpsC,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGw7B,eAC/B6C,aAAc,mBACdM,cAAevV,GACfA,OAAQA,EACRO,cAAei4B,EACfrjB,oCAAoC,EACpC3U,KAAM5qB,EAAQ4qB,KACdxnB,IAAKpD,EAAQoD,IACbmrB,WAAY,SAASlQ,EAAI3G,EAAKuT,GAC1B,GAAI9a,GAAUwyC,EAAStkC,SAEhBskC,GAAStkC,GAEZ4M,EACA9a,EAAQK,QAAQkH,GAGhBvH,EAAQG,QAAQoH,OAK5B1W,GAAGwG,OAAOvE,MACNq/C,SAAU,SAASjkC,EAAI3G,EAAKlX,EAAQ0nB,GAChC,GAAI/X,GAAU,GAAInP,IAAGoP,OAWrB,OATApQ,GAAQoD,IAAI,0CAA4Cib,GAExDskC,EAAStkC,GAAMlO,EAEfi9B,EAAUnN,cAAc5hB,GACnBiiB,WAAW9/B,GACXigC,YAAYvY,GACZyW,KAAKjnB,GAEHvH,MCjEnBnP,GAAGyE,YAAc,SAASwW,GACtB,YAoBA,SAAS4mC,GAAmBz/B,EAAO0/B,GAE/B,GAAIC,GAAexgD,MAAMC,UAAU1B,MAAM2B,KAAK2gB,EAE9CpjB,GAAQ2B,UAAUqhD,QAAQ,WAAa5/B,EAAM/d,OAAS,mBACtDy9C,EAAeG,cAAa,GAC5BjjD,EAAQ2B,UAAUuhD,+BAA+BH,EAAcD,EAAeK,cAGlF,QAASC,GAAiB7mB,GACtB,GAAI8mB,GAAoB,GAAIriD,IAAGoP,OAoD/B,OAlDImsB,GAAMvvB,OACNuvB,EAAMlZ,KAAK,SAASA,GAChB,GAAIrhB,GAAOu6B,EAAMv6B,KACbshD,EAAW/mB,EAAM+mB,SACjBC,EAAwBD,EAASz4C,QAAQ7I,EAG7CshD,GAAWA,EAASrtC,OAAO,EAAGstC,GAGH,MAAvBD,EAAS1iD,OAAO,KAChB0iD,EAAWA,EAASrtC,OAAO,IAG/BoN,EAAKmgC,OAASF,EACdG,EAAa3gD,KAAKugB,GAClBggC,EAAkB/yC,WAEtB,SAASozC,GACL1jD,EAAQ2B,UAAUqhD,QAAQ,oBAAsBzmB,EAAM+mB,SAAW,sBAAwBI,EAAUpwB,KAAO,IAAK,SAC/G+vB,EAAkB7yC,YAGjB+rB,EAAMonB,aACXC,EAAoBrnB,GAAOrhB,KACvB,SAAwBkD,GACpB,GAAIylC,GAAczlC,EAAQ/Y,MAE1BrE,IAAGY,KAAKwc,EAAS,SAASxb,EAAK25B,GAC3B6mB,EAAiB7mB,GAAO5gB,KAAK,WACzBkoC,GAAe,EAEK,IAAhBA,GACAR,EAAkB/yC,cAKzB8N,EAAQ/Y,QACTg+C,EAAkB/yC,WAI1B,SAAqBozC,GACjB1jD,EAAQ2B,UAAUqhD,QAAQ,oBAAsBzmB,EAAM+mB,SAAW,sBAAwBI,EAAUpwB,KAAO,IAAK,SAC/G+vB,EAAkB7yC,YAKvB6yC,EAIX,QAASO,GAAoBrnB,EAAO0f,EAAQ6H,EAAcC,GACtD,GAAI5zC,GAAU4zC,GAAmB,GAAI/iD,IAAGoP,QACpC4zC,EAAY/H,GAAU1f,EAAM0nB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqB9lC,GACjB,GAAI+lC,GAAaL,EAAeA,EAAa1vC,OAAOgK,GAAWA,CAE3DA,GAAQ/Y,OACRwnB,WAAW,WACP+2B,EAAoBrnB,EAAOynB,EAAWG,EAAYh0C,IACnD,GAGHA,EAAQG,QAAQ6zC,IAIxBh0C,EAAQK,SAGLL,EAGX,QAASi0C,GAAmBx1C,EAAck0C,GACtC,GAAIuB,MACAC,EAA4B,GAAItjD,IAAGoP,OA4CvC,OA1CApQ,GAAQ2B,UAAU4iD,yBAClBzB,EAAeG,cAAa,GAExBr0C,EAAawU,MAAM/d,OAAS,IAAMrF,EAAQwkD,oBAC1CxkD,EAAQ2B,UAAUuhD,mCAClBljD,EAAQ2B,UAAU8iD,UAAU,oBAAqB,IACjD3B,EAAeG,cAAa,GAC5BqB,EAA0B9zC,YAG1BizC,KAEIziD,GAAG2N,sBAAsBC,GACzB5N,GAAGY,KAAKgN,EAAaC,MAAO,SAASjM,EAAKsJ,GACtC,GAAIqwB,GAAQrwB,EAAK4C,kBAEbytB,KAEIA,EAAMvvB,OACNy2C,EAAa3gD,KAAKoJ,EAAK8zC,aAIvBqE,EAAsBvhD,KAAKsgD,EAAiB7mB,GAAO5gB,KAAK,WACpD0oC,EAAsB7e,MACe,IAAjC6e,EAAsBh/C,QACtBi/C,EAA0Bh0C,gBAQ9CmzC,EAAe70C,EAAawU,MAGK,IAAjCihC,EAAsBh/C,QACtBi/C,EAA0Bh0C,WAI3Bg0C,EAGX,QAASI,GAAcC,GACnB,GAAIC,GAAW,GAAI5jD,IAAG6jD,gBAClBC,sBAAuBA,EACvBphD,QAASihD,EACTI,QAAS,SAAS1xC,GACdrS,GAAG2jD,GAAU58C,SAAS/H,EAAQstB,QAAQ03B,YACtC3xC,EAAE4xC,mBAENC,sBAAuB,SAAS7xC,GAC5BrS,GAAG2jD,GAAU38C,YAAYhI,EAAQstB,QAAQ03B,aAE7CG,OAAQ,SAAS9xC,GACb+wC,EAAmB/wC,EAAEzE,aAAcg2C,GAAU1pC,KACzC,WACI2nC,EAAmBY,EAAcmB,IAErC,WACI5kD,EAAQ2B,UAAUqhD,QAAQ,sEAAuE,aAcjH,OARA9lC,GAAexG,YAAY,WACvBkuC,EAASruC,YAGbvV,GAAG2jD,GAAUx7C,aAAai8C,IAA2BpkD,GAAG2jD,GAAU3+C,OAElEq/C,EAAgBviD,KAAK8hD,GAEdA,EAGX,QAASU,GAAWC,GAChB,GAAIC,EASJ,OAPAxkD,IAAGY,KAAK2jD,EAAU32C,aAAa62C,MAAO,SAAStkD,EAAKC,GAChD,GAAY,UAARA,EAEA,MADAokD,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBryC,GACxB,MAAIrS,IAAGwR,WACKa,EAAEsyC,cAGV3kD,GAAGoR,SACIiB,EAAE4qC,EAAI,GAAK5qC,EAAEuyC,EAAI,EAGb,IAARvyC,EAAE4qC,GAAmB,IAAR5qC,EAAEuyC,EAG1B,QAASC,KACL,GAAIC,GAAY9lD,EAAQuF,iBAEpBwgD,EAAqB,WACjBl5B,WAAW,WACP7rB,GAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAC7B5jD,GAAG4jD,GAAUz7C,aAAai8C,IAA2BpkD,GAAG4jD,GAAU5+C,OAClEhF,GAAG4jD,GAAU58C,YAAYhI,EAAQstB,QAAQ03B,eAE9C,IAGXhkD,IAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAC7B,GAAI9B,GAAiB4B,EAAcE,EAG/BkB,GAAUzgD,QAAUrE,GAAGiW,kBAAkB8C,UACzCmD,EAAe/W,OAAOgI,SAAU,YAAa,SAASkF,IAC7CyvC,EAAeG,gBAAkBqC,EAAWjyC,IAC7CrS,GAAGY,KAAKkkD,EAAW,SAASljD,EAAKgiD,GAGzBA,YAAoBoB,cACpBhlD,GAAG4jD,GAAUz7C,aAAai8C,IAE1BpkD,GAAG4jD,GAAU39C,KAAKf,QAAS,gBAQnDgX,EAAe/W,OAAOgI,SAAU,YAAa,SAASkF,GAC9CqyC,EAAmBryC,IACnB0yC,MAOR7oC,EAAe/W,OAAOnF,GAAGmN,UAAUzF,WAAW,GAAI,aAAc,SAAS2K,GACrE0yC,MAGJ7oC,EAAe/W,OAAOgI,SAAU,OAAQ,SAASkF,GAC7CA,EAAED,iBACF2yC,MAGJ7oC,EAAe/W,OAAOgI,SAAU22C,EAAuBiB,GAnR3D,GAAI/lD,GACA8kD,EAAwB,eACxBM,EAAyB,mBACzBC,KACA5B,KACAvmC,EAAiB,GAAIlc,IAAGqV,cAE5BrW,IACIuF,oBACAi/C,oBAAoB,EACpBl3B,SACI03B,WAAY,MAEhBrjD,UAAW,GAAIX,IAAGyE,YAAY9D,WAGlCX,GAAGwG,OAAOxH,EAASic,GAAG,GAsQtB4pC,IAEA7kD,GAAGwG,OAAOvE,MACNgjD,mBAAoB,SAASviD,GACzB1D,EAAQuF,iBAAiBzC,KAAKY,GAC9BghD,EAAchhD,IAGlBwiD,eAAgB,SAASxiD,GACrB,GAAImR,GACAsxC,EAAMnmD,EAAQuF,gBAElB,KAAKsP,IAAKsxC,GACN,GAAIA,EAAItxC,KAAOnR,EACX,MAAOyiD,GAAIjmC,OAAOrL,EAAG,IAKjC0B,QAAS,WACL2G,EAAe3G,UACfvV,GAAGY,KAAKyjD,EAAiB,SAASziD,EAAKgiD,GACnCA,EAASruC,gBAMzBvV,GAAGyE,YAAY9D,UAAY,WACvB,YAEA,QACI4iD,uBAAwB,aACxBrB,+BAAgC,SAAS9/B,EAAOgjC,KAChD3B,UAAW,SAASnxB,EAAM+yB,GACtBrlD,GAAGoC,IAAI,2BAA6BkwB,EAAO,2BAA6B+yB,EAAiB,IAAK,UAElGrD,QAAS,SAAS3/C,EAAS+H,GACvBpK,GAAGoC,IAAIC,EAAS+H,MAK5BpK,GAAG6jD,eAAiB,SAAS5oC,GACzB,YAiBA,SAASqqC,KACL,MAAOtlD,IAAGoR,UAAapR,GAAGwR,WAAaxR,GAAGyR,UAG9C,QAAS8zC,GAAmBlzC,GAEnBmzC,IAGGF,EACAppC,EAAe/W,OAAOgI,SAAU,WAAY,SAASkF,GACjDA,EAAED,mBAGN8J,EAAe/W,OAAOgI,SAAU,WAAY,SAASkF,GAC7CA,EAAEzE,eACFyE,EAAEzE,aAAa63C,WAAa,OAC5BpzC,EAAED,oBAKdozC,GAAsB,GAI9B,QAASE,GAAgBrzC,GAGrB,IAAKrS,GAAGiW,kBAAkB8C,SACtB,OAAO,CAGX,IAAI4sC,GAAYC,EAAKvzC,EAAEzE,aAEvBi4C,EAAW7lD,GAAGoR,QAQd,OADAu0C,MAAa3lD,GAAG4Q,OAAQ5Q,GAAGiW,kBAAkB8C,WAAuC,SAArB6sC,EAAGE,cAC3DF,GAAMD,IAAeC,EAAGxjC,QAAWyjC,GAAYD,EAAGnB,MAAMh/C,UAAYmgD,EAAGnB,MAAMh/C,SAAS,UAGjG,QAASsgD,GAAoBC,GAIzB,MAHmB1lD,UAAf0lD,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiBj5C,SAASk5C,YAAY,SACtCD,EAAeE,UAAUtnD,EAAQ8kD,uBAAuB,GAAM,GAJlE,GAAIsC,EAOJ,IAAIh9C,OAAOm9C,YACP,IACIH,EAAiB,GAAIG,aAAYvnD,EAAQ8kD,uBAE7C,MAAOlM,GACHuO,QAIJA,IAGJh5C,UAASq5C,cAAcJ,GAG3B,QAASK,KACLvqC,EAAe/W,OAAOzC,EAAS,WAAY,SAAS2P,GAChD,GAAKqzC,EAAgBrzC,GAArB,CAMA,GAAIq0C,GAAS1mD,GAAG4Q,MAAQ5Q,GAAGiW,kBAAkB8C,SAAW,KAAO1G,EAAEzE,aAAak4C,aAC/D,UAAXY,GAAgC,aAAXA,EACrBr0C,EAAEzE,aAAa63C,WAAa,OAE5BpzC,EAAEzE,aAAa63C,WAAa,OAGhCpzC,EAAE4xC,kBACF5xC,EAAED,oBAGN8J,EAAe/W,OAAOzC,EAAS,YAAa,SAAS2P,GACjD,IAAK0zC,IAAuB,CACxB,IAAKL,EAAgBrzC,GACjB,MAEJrT,GAAQ+kD,QAAQ1xC,MAIxB6J,EAAe/W,OAAOzC,EAAS,YAAa,SAAS2P,GACjD,GAAKqzC,EAAgBrzC,GAArB,CAIArT,EAAQ23B,QAAQtkB,EAEhB,IAAIsyC,GAAgBx3C,SAASw5C,iBAAiBt0C,EAAEu0C,QAASv0C,EAAEw0C,QAEvD7mD,IAAGiC,MAAMwD,SAASk/C,IAItB3lD,EAAQklD,sBAAsB7xC,MAGlC6J,EAAe/W,OAAOzC,EAAS,OAAQ,SAAS2P,GAC5C,IAAK0zC,IAAuB,CACxB,IAAKL,EAAgBrzC,GACjB,MAGJA,GAAED,iBACFC,EAAE4xC,kBACFjlD,EAAQmlD,OAAO9xC,GAEf6zC,OAjJZ,GACIlnD,GAAS0D,EAASujD,EAAaT,EAD/BtpC,EAAiB,GAAIlc,IAAGqV,cAG5BrW,IACI0D,QAAS,KACTqhD,QAAS,SAAS1xC,KAClBskB,QAAS,SAAStkB,KAElB6xC,sBAAuB,SAAS7xC,KAChC8xC,OAAQ,SAAS9xC,MAGrBrS,GAAGwG,OAAOxH,EAASic,GACnBvY,EAAU1D,EAAQ0D,QAyIlB6iD,IACAkB,IAEAzmD,GAAGwG,OAAOvE,MACNggD,aAAc,SAAS+D,GACnB,MAAOD,GAAoBC,IAG/BzwC,QAAS,WACL2G,EAAe3G,WAGnB4sC,WAAY,WACR,MAAOz/C,OCvelB,WACG,YAEA1C,IAAG8mD,aACC9lC,gBAAiB,SAASC,GACtBhf,KAAK8kD,QAAQvlD,UAAUwf,gBAAgBhf,MAAMC,KAAMP,WACnDO,KAAK+kD,YAAYC,iBAGrBnkC,iBAAkB,WACd7gB,KAAK8kD,QAAQvlD,UAAUshB,iBAAiB9gB,MAAMC,KAAMP,WACpDO,KAAK+kD,YAAYE,cAGrBC,iBAAkB,SAASzkD,GACvBT,KAAKmlD,MAAQnlD,KAAKmlD,KAAKnC,mBAAmBviD,IAG9C2kD,oBAAqB,SAAS3kD,GAC1B,GAAIT,KAAKmlD,KACL,MAAOnlD,MAAKmlD,KAAKlC,eAAexiD,IAIxC4kD,gBAAiB,SAASjqC,GACtB,IAAKpb,KAAK+kD,YAAYO,gBAAgBlqC,GAClC,MAAOpb,MAAK+kD,YAAYQ,iBAAiBnqC,IAIjDN,MAAO,WACH9a,KAAK8kD,QAAQvlD,UAAUub,MAAM/a,MAAMC,KAAMP,WACzCO,KAAK+kD,YAAYjqC,SAEZ9a,KAAKpB,SAASslB,QAAUlkB,KAAK+kD,YAAYtiC,cAC1CziB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAK+kD,YAAYtiC,YAC1BrJ,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGHza,KAAKmlD,OACLnlD,KAAKmlD,KAAK7xC,UACVtT,KAAKmlD,KAAOnlD,KAAKwlD,qBAGrBxlD,KAAKylD,mBAAqB,EAC1BzlD,KAAK0lD,uBAAyB,EAE9B1lD,KAAK2lD,mCAGT3/B,QAAS,SAAS5K,EAAIkC,GAClB,GAAIsoC,GAAoB5lD,KAAKpB,SAASkyB,eAAexT,EAErDtd,MAAK8kD,QAAQvlD,UAAUymB,QAAQjmB,MAAMC,KAAMP,WAC3CO,KAAK+kD,YAAYc,eAAezqC,EAAIwqC,IAGxC/hC,YAAa,SAASzI,GAClB,GAAIqsB,GAASznC,KAAK8kD,QAAQvlD,UAAUskB,YAAY9jB,MAAMC,KAAMP,UAG5D,OADAgoC,IAAUznC,KAAK+kD,YAAYe,aAAa1qC,GACjCqsB,GAGX3mB,eAAgB,SAAS1F,GACrB,GAAI2qC,GAAY/lD,KAAK8kD,QAAQvlD,UAAUuhB,eAAe/gB,MAAMC,KAAMP,UAGlE,OADAsmD,IAAa/lD,KAAK+kD,YAAYiB,gBAAgB5qC,GACvC2qC,GAGXE,MAAO,SAASC,GACZ,MAAOlmD,MAAK+kD,YAAYoB,UAAUD,IAGtCE,cAAe,SAAS1kC,GACpB,GAAItB,GAAOpgB,KAAKoiB,QAAQV,EAExB,OAAOtB,GAAKimC,eAOpBtoD,GAAGuoD,cACC5jC,WAAY,SAASvJ,GACjB,GAAI+K,GAASlkB,KAAK8kD,QAAQvlD,UAAUmjB,WAAW3iB,MAAMC,KAAMP,UAQ3D,OANKykB,IACG/K,IAAanZ,KAAKytB,mBAClBvJ,EAASlkB,KAAK+kD,YAAYtiC,aAI3ByB,GAGXqiC,gBAAiB,SAAS7kC,GACtB1hB,KAAK+kD,YAAYyB,WAAW9kC,IAGhCikC,gCAAiC,WAC7B3lD,KAAKymD,yBAA2B1oD,GAAG2oD,yBAA2B1mD,KAAK2mD,6BAInE3mD,KAAK4mD,wBAA0B7oD,GAAGwR,UAE9BvP,KAAK6mD,2BAEL7mD,KAAK8mD,sBAAwB9mD,KAAK+mD,0BAClC/mD,KAAKgnD,6BAA+BhnD,KAAKinD,iCACzCjnD,KAAKknD,2BAA6BlnD,KAAKmnD,iCAI/C3B,kBAAmB,WACf,GAAIzjD,GAAO/B,KACPsC,EAAmBtC,KAAKpB,SAASwoD,YAAYC,eAC7CC,EAAatnD,KAAK+kD,YAClBwC,EAAkBD,EAAWE,aAIjC,OAFAD,IAAmBjlD,EAAiBzC,KAAK0nD,GAElC,GAAIxpD,IAAGyE,aACVF,iBAAkBA,EAClBi/C,mBAAoBvhD,KAAKpB,SAASwM,SAClCif,SACI03B,WAAY/hD,KAAKpB,SAASyrB,QAAQ03B,YAEtCrjD,WACI4iD,uBAAwB,WACpBgG,EAAWG,sBAEfxH,+BAAgC,SAAS9/B,EAAOgjC,GAC5CmE,EAAWI,qBAEX3pD,GAAGY,KAAKwhB,EAAO,SAASxgB,EAAKygB,GACzBA,EAAKimC,aAAelD,IAGpBhjC,EAAM/d,QACNL,EAAK+c,SAASqB,EAAO,KAAM,OAGnCqhC,UAAW,SAASnxB,EAAMs3B,GACtB5lD,EAAKqkB,WAAWiK,EAAMs3B,IAE1B5H,QAAS,SAAS3/C,EAAS+H,GACvBpG,EAAK5B,IAAIC,EAAS+H,QAMlCw+C,2BAA4B,WACxB,GAAI5kD,GAAO/B,IAEX,OAAO,IAAIjC,IAAG2oD,yBACVY,WAAYtnD,KAAK+kD,YAEjB5kD,IAAK,SAASC,EAASwnD,GACnB7lD,EAAK5B,IAAIC,EAASwnD,IAGtBC,aAAc,SAASnmC,GACnB3f,EAAKqf,WAAWM,IAGpB8J,SAAU,SAAS9J,GACf3f,EAAKye,OAAOkB,IAGhBomC,QAAS,SAASpmC,GACd3f,EAAK4iB,MAAMjD,IAGfqmC,QAAS,SAASrmC,GACd3f,EAAK8hB,YAAYnC,IAGrBsmC,WAAY,SAAStmC,GACjB3f,EAAK+e,eAAeY,IAGxBumC,UAAW,SAASvmC,GAChB,MAAO3f,GAAKmf,QAAQQ,OAKhCmlC,uBAAwB,WAEpB,MAAO7mD,MAAK+kD,YAAYmD,2BAChBloD,KAAKpB,SAAS+wB,YACf5xB,GAAGoqD,sBACHpqD,GAAGqqD,2BACHrqD,GAAGqqD,2BAGdC,qBAAsB,WAClB,GAAItmD,GAAO/B,KACPsnD,EAAatnD,KAAK+kD,WAEtB,QACIuC,WAAYA,EACZnnD,IAAK,SAASC,EAASwnD,GACnB7lD,EAAK5B,IAAIC,EAASwnD,IAEtBU,kBAAmB,SAAS5mC,GACxB,MAAO3f,GAAKmhB,YAAY9H,GAAIsG,IAAShG,QAEzCusC,UAAW,SAASvmC,GAChB,MAAO3f,GAAKmf,QAAQQ,IAExB6mC,UAAW,SAASntC,EAAIkC,GACpBvb,EAAKikB,QAAQ5K,EAAIkC,IAErBkrC,sBAAuB,SAASptC,EAAIqtC,GAChC,GAAIC,GAAU3qD,GAAGupD,EAAWqB,aAAavtC,IACrCwtC,EAAkB7qD,GAAGupD,EAAW/B,iBAAiBnqC,GAEjDqtC,IACAC,EAAQ5jD,SAAS,cACjBwiD,EAAWuB,aAAaztC,GACxBksC,EAAWwB,aAAa1tC,KAGxBstC,EAAQ3jD,YAAY,cACpBuiD,EAAWyB,aAAa3tC,GACxBksC,EAAW0B,aAAa5tC,IAI5BwtC,EAAgB9jD,SAAS,WAAWC,YAAY,cAK5D2kB,sBAAuB,SAAStO,EAAI2B,EAAWD,GAC3C9c,KAAK8kD,QAAQvlD,UAAUmqB,sBAAsB3pB,MAAMC,KAAMP,WAErDO,KAAK6mD,0BAED7mD,KAAK+kD,YAAYQ,iBAAiBnqC,IAAO0B,IAAc/e,GAAG2d,OAAOoC,YACjE9d,KAAK+kD,YAAYkE,qBAAqB7tC,GACtCpb,KAAK+kD,YAAY+D,aAAa1tC,IAIlC2B,IAAchf,GAAG2d,OAAO0C,iBAAmBtB,IAAc/e,GAAG2d,OAAOyC,WACnEne,KAAK+kD,YAAYmE,UAAU9tC,GAC3Bpb,KAAK+kD,YAAYoE,cAAc/tC,GAC/Brd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKrW,YAAY/E,KAAKopD,SAASC,WAE/DvsC,IAAc/e,GAAG2d,OAAO4C,eAC7Bte,KAAK+kD,YAAYuE,UAAUluC,IAInC6rC,+BAAgC,WAC5B,GAAI7qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGwrD,4BAA4BntC,IAG9C+qC,6BAA8B,WAC1B,GAAI/qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGqqD,0BAA0BhsC,IAG5C2qC,wBAAyB,WACrB,GAAI3qC,GAAOre,GAAGwG,UAAWvE,KAAKqoD,uBAE9B,OAAO,IAAItqD,IAAGoqD,qBAAqB/rC,IAGvCiX,eAAgB,SAASjY,GACrBpb,KAAK8kD,QAAQvlD,UAAU8zB,eAAetzB,MAAMC,KAAMP,WAClDO,KAAK+kD,YAAYyE,YAAYpuC,IAGjCgW,eAAgB,SAASe,EAAYC,GACjCpyB,KAAK8kD,QAAQvlD,UAAU6xB,eAAerxB,MAAMC,KAAMP,WAClDO,KAAK+kD,YAAY0E,sBAGrBx2B,UAAW,SAAS7X,EAAIrc,GACpB,GAAIqhB,GAAOpgB,KAAKoiB,QAAQhH,EAEpBgF,IAAQA,EAAKmgC,QAAUvgD,KAAKpB,SAASwoD,YAAYsC,sBACjD1pD,KAAKmkB,aAAaqF,YAAYpO,GAC1BuuC,OAAQvpC,EAAKmgC,SAIrBvgD,KAAK8kD,QAAQvlD,UAAU0zB,UAAUlzB,MAAMC,KAAMP,WAC7CO,KAAK4pD,WAAWxuC,EAAIrc,IAIxBo0B,aAAc,SAAS/X,GAEfpb,KAAK6mD,2BACL7mD,KAAK+kD,YAAYkE,qBAAqB7tC,GACtCpb,KAAK+kD,YAAYiE,aAAa5tC,GAGzBpb,KAAK4mD,wBACN5mD,KAAKknD,2BAA2B2C,WAAW7pD,KAAK+kD,YAAY4D,aAAavtC,MAMrFiQ,YAAa,SAASjQ,EAAIrc,EAAMosB,EAAQC,GACpCprB,KAAK8kD,QAAQvlD,UAAU8rB,YAAYtrB,MAAMC,KAAMP,WAE/CO,KAAK+kD,YAAY+E,eAAe1uC,EAAI+P,EAAQC,GAE9B,IAAVA,GAAoD,MAArC/mB,KAAKC,MAAM6mB,EAASC,EAAQ,MAC3CprB,KAAK+kD,YAAYgF,WAAW3uC,GAC5Bpb,KAAK+kD,YAAYuE,UAAUluC,GAC3Bpb,KAAK+kD,YAAYiF,aAAa5uC,GAC9Bpb,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASkH,KAAKmkD,oBAGtDjqD,KAAKkqD,iBAAiB9uC,IAItBpb,KAAKkqD,iBAAiB9uC,EAAI+P,EAAQC,IAI1CwI,iBAAkB,SAASzI,EAAQC,GAC/BprB,KAAK8kD,QAAQvlD,UAAUq0B,iBAAiB7zB,MAAMC,KAAMP,WACpDO,KAAK+kD,YAAY1I,oBAAoBlxB,EAAQC,IAGjDG,YAAa,SAASnQ,EAAIrc,EAAMqG,EAAQqP,GAMpC,QAAS01C,GAAe/kD,GAGfkb,IAILgnC,EAAW6B,cAAc/tC,GAEzBrd,GAAGuiB,GAAevb,YAAYhD,EAAKqnD,SAASC,UAC5C/B,EAAW0C,aAAa5uC,GAEpBrZ,EAAKmhB,YAAY9H,GAAIA,IAAKM,SAAW3d,GAAG2d,OAAO4C,eAC/CgpC,EAAWyC,WAAW3uC,GAE1BksC,EAAWkC,YAAYpuC,GAEnBhW,EAAOiI,QACPtL,EAAKqoD,sBAAsBhvC,IAG3Brd,GAAGuiB,GAAexb,SAAS/C,EAAKqnD,SAASiB,MACzC/C,EAAWgD,WAAWlvC,GAElBksC,EAAWiD,oBAAsBxoD,EAAKiiB,gBAAgB5I,KACtDrd,GAAGuiB,GAAexb,SAAS/C,EAAKqnD,SAASlN,WACzCoL,EAAWkD,UAAUpvC,IAEzBrZ,EAAK0oD,2BAA2BrvC,EAAIhW,KAjC5C,GAAIslD,GAAe1qD,KAAK8kD,QAAQvlD,UAAUgsB,YAAYxrB,MAAMC,KAAMP,WAC9D6nD,EAAatnD,KAAK+kD,YAClBzkC,EAAgBgnC,EAAW/B,iBAAiBnqC,GAC5CrZ,EAAO/B,IA6CX,OAVI0qD,aAAwB3sD,IAAGoP,QAC3Bu9C,EAAahyC,KAAK,SAASiyC,GACvBR,EAAeQ,KAKnBR,EAAe/kD,GAGZslD,GAGXN,sBAAuB,SAAShvC,GAC5B,GAAIksC,GAAatnD,KAAK+kD,WAElB/kD,MAAK8vB,qBACLw3B,EAAWsD,iBAAiBxvC,GAGhCrd,GAAGupD,EAAW/B,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAAS/7C,SAE3DrN,KAAK6qD,sBAAsBzvC,IAG/BwQ,cAAe,SAASxQ,GACpBpb,KAAK8kD,QAAQvlD,UAAUqsB,cAAc7rB,MAAMC,KAAMP,WACjDO,KAAK+kD,YAAY+F,YAAY1vC,IAGjC0Q,UAAW,SAAS1Q,EAAIrc,GACpB,GAAI2rD,GAAe1qD,KAAK8kD,QAAQvlD,UAAUusB,UAAU/rB,MAAMC,KAAMP,UAIhE,OAFAO,MAAK+kD,YAAY+F,YAAY1vC,GAEtBsvC,GAGXz+B,eAAgB,SAAS7Q,EAAI4Q,GACzBhsB,KAAK8kD,QAAQvlD,UAAU0sB,eAAelsB,MAAMC,KAAMP,WAI9CusB,EAAU+L,UAAY,GAAK/3B,KAAKygB,SAASyjB,YAAY9oB,IACrDpb,KAAK+kD,YAAYgG,WAAW3vC,IAIpCsQ,UAAW,SAAStQ,EAAIrc,GACpBiB,KAAK8kD,QAAQvlD,UAAUmsB,UAAU3rB,MAAMC,KAAMP,WAC7CO,KAAKumD,gBAAgBnrC,GAEU,IAA3Bpb,KAAK8tB,mBACL9tB,KAAK+kD,YAAY0E,sBAIzBh3B,mBAAoB,SAASrX,GACzB,GAAI4vC,GAAoBC,EAASC,CAEjClrD,MAAK8kD,QAAQvlD,UAAUkzB,mBAAmB1yB,MAAMC,KAAMP,WAEtDO,KAAKmrD,gBAAgB/vC,GAEjBpb,KAAKpB,SAAS+lB,MAAMymC,oBACpBJ,EAAqBhrD,KAAK8jB,aAAa1I,GACvC6vC,EAAUjrD,KAAKpB,SAAS+lB,MAAMwQ,gBAE9B+1B,EAAYlrD,KAAKpB,SAAS+lB,MAAM0mC,cAAcrmD,QAAQ,gBAAiBgmD,GACvEE,EAAYA,EAAUlmD,QAAQ,eAAgBimD,GAE9CjrD,KAAK+kD,YAAYoE,cAAc/tC,EAAI8vC,GACnCntD,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAASC,YAKzEn4B,qBAAsB,SAAS9V,GAC3B,MAAIpb,MAAK8kD,QAAQvlD,UAAU2xB,qBAAqBnxB,MAAMC,KAAMP,YACxDO,KAAK+kD,YAAYuG,cAAclwC,GAC/Brd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKrW,YAAY/E,KAAKopD,SAASiB,MACpErqD,KAAK+kD,YAAYoE,cAAc/tC,GAC/Bpb,KAAK+kD,YAAY+F,YAAY1vC,GAC7Bpb,KAAKmrD,gBAAgB/vC,IACd,IAGPrd,GAAGiC,KAAK+kD,YAAYQ,iBAAiBnqC,IAAKtW,SAAS9E,KAAKopD,SAASlN,WACjEl8C,KAAK+kD,YAAYyF,UAAUpvC,IACpB,IAIfiG,gBAAiB,SAASjG,GACtB,GAAIkY,GAAoBv1B,GAAGgT,KAAK/Q,KAAKurD,uBAAwBvrD,KAE7DA,MAAK8kD,QAAQvlD,UAAU8hB,gBAAgB7hB,KAAKQ,KAAMob,EAAIkY,IAG1Di4B,uBAAwB,SAASnwC,EAAIG,EAAMgY,GACnCvzB,KAAKpB,SAASwiB,WAAWoqC,aACzBxrD,KAAKyrD,mBAAmB1rD,MAAMC,KAAMP,WAGpCO,KAAK0rD,mBAAmB3rD,MAAMC,KAAMP,YAI5CwoB,kBAAmB,SAAS7M,EAAI3G,EAAKuT,GACjChoB,KAAK8kD,QAAQvlD,UAAU0oB,kBAAkBloB,MAAMC,KAAMP,WAErDO,KAAK+kD,YAAYyE,YAAYpuC,GAEzB4M,GACAhoB,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASwiB,WAAWuqC,oBAC5D3rD,KAAK+kD,YAAY6F,iBAAiBxvC,IAGlCpb,KAAKumD,gBAAgBnrC,IAI7BswC,mBAAoB,SAAStwC,EAAIG,EAAMgY,GACnCvzB,KAAK+kD,YAAY6G,iBAAiBxwC,GAClCpb,KAAK+kD,YAAY+F,YAAY1vC,GAC7Bpb,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASwiB,WAAWyqC,oBAC5D7rD,KAAK0zB,eAAeC,WAAW5zB,MAAMC,KAAMP,YAG/CgsD,mBAAoB,SAASrwC,EAAIG,EAAMqf,GAEnC,GAKIt5B,GALA6R,EAAWnT,KAAKkhB,QAAQ9F,GACxB0wC,EAAiB9rD,KAAKpB,SAASwiB,WAAW0qC,eAAe9mD,QAAQ,gBAAiBmO,GAElF44C,GADO/rD,KAAK2jB,QAAQvI,GACA3b,WACpBsC,EAAO/B,IAGXsB,GAAStB,KAAKpB,SAASotD,YAAYF,GAE/B/tD,GAAGga,iBAAiBzW,GACpBA,EAAO2W,KAAK,WACRlW,EAAK2pD,mBAAmB3rD,MAAMgC,EAAMgqD,KAGnCzqD,KAAW,GAChBS,EAAK2pD,mBAAmB3rD,MAAMgC,EAAMgqD,IAI5CnC,WAAY,SAASxuC,EAAIrc,EAAMktD,GAC3B,GAAIC,GAGA5U,EAFA6U,EAAe,EACfC,EAAcpsD,KAAKygB,SAASwjB,UAAU7oB,IAAOpb,KAAKpB,SAAS2Y,QAAQ80C,UAGnErsD,MAAKpB,SAASqE,QAAQqpD,eAClBtsD,KAAKylD,mBAAqB,GAAKzlD,KAAK0lD,uBAAyB,IAC7DyG,EAAensD,KAAK0lD,uBAAyB,GAGjDwG,GACIhqD,MAAOiqD,IAIVF,IACGjsD,KAAKpB,SAASy3B,8BAAgCt4B,GAAGiW,kBAAkBqC,eACnErW,KAAK+kD,YAAYwH,gBAMhBvsD,KAAKpB,SAASwM,WACfksC,EAASt3C,KAAKkjB,YAAY9H,GAAIA,IAE9Bpb,KAAKwsD,mBAAqBxsD,KAAKwsD,oBAAsBlV,EAAO76B,aAExD66B,EAAO76B,eAAiBzc,KAAKwsD,oBAAuBlV,EAAO76B,eAC3Dzc,KAAKygB,SAASC,YACd1gB,KAAKysD,aACLzsD,KAAKwsD,mBAAqB,QAKlCP,GACAjsD,KAAK+kD,YAAY2H,eAAetxC,EAAIpb,KAAKpB,SAASkyB,eAAe/xB,GAAOmtD,EAAaE,GACrFpsD,KAAK+kD,YAAY4H,gBAAgBvxC,EAAIpb,KAAKkiB,eAAe9G,IAAK,EAAMpb,KAAKpB,SAASguD,WAAWl0B,iBAG7F14B,KAAK+kD,YAAY5oC,QAAQf,EAAIpb,KAAKpB,SAASkyB,eAAe/xB,GAAOmtD,EAAaE,GAC9EpsD,KAAK+kD,YAAY8H,gBAAgBzxC,EAAIpb,KAAKoiB,QAAQhH,GAAKpb,KAAKpB,SAASguD,WAAWl0B,gBAGpF14B,KAAK0lD,wBAA0B,GAE3BuG,GACCjsD,KAAKpB,SAASqE,QAAQ6pD,kBAAoB/uD,GAAGiW,kBAAkBqC,gBAEhErW,KAAKkqD,iBAAiB9uC,IAI9BqxC,WAAY,WACRzsD,KAAK+kD,YAAYE,aACjBjlD,KAAK6gB,oBAGTqpC,iBAAkB,SAAS9uC,EAAI2xC,EAAYlR,GACvC,GAAIt/B,GAAOvc,KAAKojB,QAAQhI,GACpB4xC,EAAiBhtD,KAAK8sB,YAAYvQ,EAElCA,IAAQ,IACWle,SAAf0uD,GAA0C1uD,SAAdw9C,IAC5BmR,EAAiBhtD,KAAKitD,gBAAgBF,EAAYlR,IAGtD77C,KAAK+kD,YAAYxnC,WAAWnC,EAAI4xC,KAIxCC,gBAAiB,SAASC,EAAcrR,GAEpC,QAASrtC,GAAEzP,EAAMwxB,GAAenwB,EAAUA,EAAQ4E,QAAQjG,EAAMwxB,GADhE,GAAInwB,GAAUJ,KAAKpB,SAASkH,KAAKqnD,cAKjC,OAFA3+C,GAAE,YAAanK,KAAKC,MAAM4oD,EAAerR,EAAY,MACrDrtC,EAAE,eAAgBxO,KAAK8sB,YAAY+uB,IAC5Bz7C,GAGXqqD,2BAA4B,SAASrvC,EAAIqW,GACrC,GAAI27B,GAAMC,EAAkBC,CAE5BF,GAAOptD,KAAKpB,SAAS2uD,wBAAwBH,KAC7CC,EAAmBrtD,KAAKpB,SAAS2uD,wBAAwBF,iBAE5C,WAATD,GACAE,EAAgB77B,EAAS47B,GACpBC,IACDA,EAAgBttD,KAAKpB,SAASkH,KAAK0nD,YAGvCxtD,KAAK+kD,YAAYoE,cAAc/tC,EAAIkyC,GAE/BttD,KAAKpB,SAAS2uD,wBAAwBE,eACtCztD,KAAK0tD,aAAatyC,EAAIkyC,IAGZ,YAATF,EACLptD,KAAK+kD,YAAYoE,cAAc/tC,EAAIpb,KAAKpB,SAASkH,KAAK0nD,YAExC,SAATJ,GACLptD,KAAKG,IAAI,0CAA4CitD,EAAO,iBAAkB,SAItFM,aAAc,SAAStyC,EAAItV,GACvB9F,KAAK+kD,YAAYQ,iBAAiBnqC,GAAIhC,MAAQtT,GAGlDqlD,gBAAiB,SAAS/vC,GACjBpb,KAAKpB,SAASy3B,8BAA+Bt4B,GAAGiW,kBAAkBqC,eACnErW,KAAK+kD,YAAYuF,WAAWlvC,IAIpCgL,WAAY,SAASiK,EAAMtxB,EAAMkK,GAC7B,GAAI7I,GAAUJ,KAAK8kD,QAAQvlD,UAAU6mB,WAAWrmB,MAAMC,KAAMP,UAC5DO,MAAKpB,SAAS+uD,YAAYvtD,IAG9B2mB,YAAa,SAAS3mB,GAClBJ,KAAK8kD,QAAQvlD,UAAUwnB,YAAYhnB,MAAMC,KAAMP,WAC/CO,KAAKpB,SAAS+uD,YAAYvtD,IAG9BwtD,kBAAmB,WACf,GAAI7rD,GAAO/B,IAEXA,MAAKpB,SAASF,UAAU8pB,gBAAkB,WACtC,GAAIpoB,GAAU2B,EAAKnD,SAASypB,MAAMwlC,kBAC9BC,EAAa/rD,EAAKnD,SAASypB,MAAM5I,WAErC,OAAO1d,GAAKnD,SAASmvD,WAAW3tD,EAAS0tD,KAIjDjhC,oBAAqB,SAASzR,EAAIrc,GAC9BiB,KAAKylD,oBAAsB,EAC3BzlD,KAAK8kD,QAAQvlD,UAAUstB,oBAAoB9sB,MAAMC,KAAMP,YAG3D8gB,uBAAwB,SAAS3U,EAAOrO,EAAQshB,GAC5C7e,KAAKylD,mBAAqB75C,EAAMxJ,OAChCpC,KAAK0lD,uBAAyB,EAC9B1lD,KAAK8kD,QAAQvlD,UAAUghB,uBAAuBxgB,MAAMC,KAAMP,YAG9DorD,sBAAuB,SAASnpC,GAC5B,GAAIgF,GAAe1mB,KAAKkiB,eAAeR,GACnCssC,EAAahuD,KAAKkjB,YAAY9H,GAAIsG,IAAShG,MAE3CsyC,KAAejwD,GAAG2d,OAAO+C,UACxBiI,IACD1mB,KAAKpB,SAASguD,WAAWqB,aAAaC,mBACrCnwD,GAAGiW,kBAAkBiD,eAItBjX,KAAK+kD,YAAY4H,gBAAgBjrC,EAAQgF,EAAc1mB,KAAKpB,SAASguD,WAAWl0B,gBAIxFxZ,eAAgB,SAASqH,GACrB,GAAInL,GAAKpb,KAAK8kD,QAAQvlD,UAAU2f,eAAenf,MAAMC,KAAMP,UAO3D,OALAO,MAAK4pD,WAAWxuC,EAAIpb,KAAKkhB,QAAQ9F,IAAK,GACtCpb,KAAK+kD,YAAYyE,YAAYpuC,GAC7Bpb,KAAK+kD,YAAYgF,WAAW3uC,GAC5Bpb,KAAKoqD,sBAAsBhvC,GAEpBA,GAGXqR,SAAU,SAASrR,EAAIoC,GACnBxd,KAAK8kD,QAAQvlD,UAAUktB,SAAS1sB,MAAMC,KAAMP,WAE5CO,KAAK+kD,YAAYxnC,WAAWnC,EAAIpb,KAAK8sB,YAAYtP,KAGrDuX,wBAAyB,WACrB/0B,KAAK+kD,YAAYC,gBACjBhlD,KAAK8kD,QAAQvlD,UAAUw1B,wBAAwBh1B,MAAMC,KAAMP,gBC7sBvE1B,GAAGC,aAAe,SAASgb,EAAGtb,GAC1B,YAEA,IAAIqE,GAAO/B,IAKXA,MAAK8kD,QAAUpnD,EAAYK,GAAGL,GAAW04B,kBAAoBr4B,GAAGq4B,kBAChEp2B,KAAK8kD,QAAQ/kD,MAAMC,KAAMP,WAGzB1B,GAAGwG,OAAOvE,KAAKpB,UACX6B,QAAS,KAETyjB,OAAQ,KAERiqC,YAAa,KAEb/G,aACIC,kBACAqC,sBAAsB,GAG1B5jD,MACIqnD,eAAgB,6BAChBK,WAAY,gBACZvD,mBAAoB,gBACpBxiB,OAAQ,UAGZ2mB,SAAU,cAEV/jC,SACIg/B,SAAU,qBACVnN,UAAW,sBACX7uC,QAAS,oBACTg9C,KAAM,iBACNgE,SAAU,cACVtrD,KAAM,UACNg/C,WAAY,8BAGhBwL,yBACIH,KAAM,UACNC,iBAAkB,QAClBI,eAAe,GAGnB/8B,UACI49B,kBAAmB,6BACnBC,mBAAoB,kFAGxB5pC,OACIymC,mBAAmB,EACnBC,cAAe,oCAGnBjqC,YACIoqC,cAAc,EACdM,eAAgB,8CAChBD,mBAAoB,cACpBF,mBAAoB,iBAIxB1oD,SACI6pD,kBAAkB,EAClBR,cAAc,GAGlBjkC,OACImmC,eAAe,EACfX,kBAAmB,0BAGvBjB,YACIl0B,cAAe,KACf+1B,SAAU,EACVR,cACIC,mBAAmB,EACnBQ,iBAAkB,KAClBC,YAAa,MAEjBC,kBAAmB,KAGvBr3C,SACI80C,YAAY,GAGhBsB,YAAa,SAASvtD,GAClB,MAAI2B,GAAKgjD,YAAY8J,UAAU,SACpB9sD,EAAKgjD,YAAY+J,WAAW,QAAS1uD,OAG5CwpB,YAAW,WACPziB,OAAOmqB,MAAMlxB,IACd,IAIX4rD,YAAa,SAAS5rD,GAClB,MAAI2B,GAAKgjD,YAAY8J,UAAU,WACpB9sD,EAAKgjD,YAAY+J,WAAW,UAAW1uD,GAGvC+G,OAAO4nD,QAAQ3uD,IAI9B2tD,WAAY,SAAS3tD,EAAS4uD,GAC1B,MAAIjtD,GAAKgjD,YAAY8J,UAAU,UACpB9sD,EAAKgjD,YAAY+J,WAAW,SAAU1uD,EAAS4uD,GAG/C7nD,OAAO8nD,OAAO7uD,EAAS4uD,MAGvC,GAGHjxD,GAAGwG,OAAOvE,KAAKpB,SAAUoa,GAAG,GAE5BhZ,KAAK+kD,YAAc,GAAIhnD,IAAGmxD,YACtB/uD,IAAKpC,GAAGgT,KAAK/Q,KAAKG,IAAKH,MACvBmvD,eAAgBnvD,KAAKpB,SAASwvD,SAC9BgB,YAAapvD,KAAKpB,SAAS6B,QAC3B4uD,gBAAiBrvD,KAAKpB,SAASuvD,YAC/BjqC,OAAQlkB,KAAKpB,SAASslB,OACtBw0B,eAAgB14C,KAAKiiB,gBACrBoI,SACItnB,KAAM/C,KAAKpB,SAASyrB,QAAQtnB,KAC5BsrD,SAAUruD,KAAKpB,SAASyrB,QAAQgkC,UAEpC5Z,QACI6a,UAAWtvD,KAAKpB,SAASguD,WAAW6B,SACpCG,kBAAmB5uD,KAAKpB,SAASguD,WAAWgC,mBAEhDX,cACIsB,gBAAiBvvD,KAAKpB,SAASguD,WAAWqB,aAAaC,kBACvDsB,sBAAuBxvD,KAAKpB,SAASguD,WAAWqB,aAAaS,iBAC7De,oBAAqBzvD,KAAKpB,SAASguD,WAAWqB,aAAaU,aAE/D7oD,KAAM9F,KAAKpB,SAASkH,OAGpB9F,KAAKpB,SAASmrB,YAAYsH,mBAAqBtzB,GAAGgS,UAAYhS,GAAGkS,YACjEjQ,KAAK+kD,YAAY2K,cAAc1vD,KAAKpB,SAAS8xB,SAASa,+BAEhDxzB,GAAGiW,kBAAkB0D,WAAc1X,KAAKpB,SAAS+oB,KAAKoI,WAAahyB,GAAGiW,kBAAkB2D,WAC9F3X,KAAK+kD,YAAY2K,cAAc1vD,KAAKpB,SAAS8xB,SAAS69B,qBAGtDvuD,KAAK81B,iBAEL91B,KAAK+kD,YAAYzW,SAEjBtuC,KAAKopD,SAAWppD,KAAKpB,SAASyrB,SAEzBrqB,KAAKpB,SAASslB,QAAUlkB,KAAK+kD,YAAYtiC,cAC1CziB,KAAKytB,iBAAmBztB,KAAK6pB,qBACzBppB,QAAST,KAAK+kD,YAAYtiC,YAC1BrJ,MAAOpZ,KAAKpB,SAASkH,KAAK6kB,iBAC3BlQ,eAGPza,KAAK2lD,kCAED5nD,GAAGyE,aAAezE,GAAGiW,kBAAkB8C,WACvC9W,KAAKmlD,KAAOnlD,KAAKwlD,qBAGjBxlD,KAAKpB,SAASypB,MAAMD,eAAiBpoB,KAAKpB,SAASypB,MAAMmmC,gBACrDzwD,GAAGoqB,aACHnoB,KAAK4tD,oBAGL5tD,KAAKG,IAAI,kCAAmC,UAIpDH,KAAKylD,mBAAqB,EAC1BzlD,KAAK0lD,uBAAyB,IAKtC3nD,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAG2gB,eACxC3gB,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAGuoB,gBAGxCvoB,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAG8mD,aACxC9mD,GAAGwG,OAAOxG,GAAGC,aAAauB,UAAWxB,GAAGuoD,cC5LxCvoD,GAAGmxD,WAAa,SAAS9yC,GACrB,YAEA,IA4EIjc,GACAwvD,EACAC,EACAC,EACAxtC,EACA8M,EACA2gC,EACAC,EAnFAC,EAAe,aACfC,EAAoB,cACpBC,EAA0B,cAC1BC,EAA8B,kBAE9BC,EAAqB,mBACrBC,EAAsB,oBACtBC,EAAoB,iBACpBC,EAAuB,oBACvBC,GACIC,QAASvlD,SAASwlD,yBAClBC,QAEJC,GAAmB,EACnBC,EAAsB,EACtBC,GAA+B,EAC/BC,KACAC,GAAmB,EACnBj0D,GACIoD,IAAK,KACLs0C,QACI6a,UAAW,EACXV,kBAAmB,KAEvBO,eAAgB,cAChBC,YAAa,KACbC,gBAAiB,KACjBnrC,OAAQ,KACRw0B,eAAgB;AAChBruB,SACItnB,KAAM,UACNsrD,SAAU,eAEdJ,cACIsB,iBAAiB,EACjBC,sBAAuB,KACvBC,oBAAqB,MAEzB3pD,MACI2hC,OAAQ,WAGhBwpB,GACI/sC,OAAQ,4BACRgtC,YAAa,2BACbC,mBAAoB,4BACpBC,cAAe,6BACfC,cAAe,6BACfC,eAAgB,wBAChBC,aAAc,4BACdn0D,SAAU,uBACVo0D,KAAM,+BACNC,KAAM,0BACNC,qBAAsB,qCACtBr6C,YAAa,2BACbs6C,0BAA2B,2CAC3BC,iBAAkB,iCAClBxxC,KAAM,0BACNyxC,QAAS,6BACTt1C,KAAM,0BACNiE,OAAQ,4BACRpJ,MAAO,2BACP06C,eAAgB,8BAChBC,aAAc,4BACdptC,MAAO,2BACPqtC,WAAY,iCACZC,kBAAmB,4BACnBC,aAAc,iCACdC,SAAU,oCACVC,eAAgB,8BAChBC,sBAAuB,sCACvBC,UAAW,yBAEfC,KACAC,EAAiC,GAAIz0D,IAAGoP,QACxCslD,EAA+B,GAAI10D,IAAGoP,QAatCulD,EAA6B,WACzB,GAAIC,GAAmB51D,EAAQkxD,aAAauB,sBACxCoD,EAAa71D,EAAQkxD,aAAawB,oBAClCrzC,GACIwF,QAASovC,EACT7uC,MAAO4tC,EAGXD,KACI6C,EACA51D,EAAQ27C,eAAep2B,SAASqwC,EAAiB,GAAI5kB,OAAS3xB,GAAMnE,KAChE,SAAS46C,GACLL,EAA+BnlD,QAAQwlD,IAE3C,WACIL,EAA+BjlD,UAC/BpN,EAAI,wDAA0DwyD,EAAiB,WAKvFH,EAA+BjlD,UAG/BqlD,EACA71D,EAAQ27C,eAAep2B,SAASswC,EAAY,GAAI7kB,OAAS3xB,GAAMnE,KAC3D,SAAS46C,GACLJ,EAA6BplD,QAAQwlD,IAEzC,WACIJ,EAA6BllD,UAC7BpN,EAAI,gEAAkEyyD,EAAY,WAK1FH,EAA6BllD,YAOzCulD,EAAoB,SAASR,GACzB,GAAIS,GAAsB,GAAIh1D,IAAGoP,OAwBjC,OAtBAslD,GAA6Bx6C,KAAK,SAASoyB,GACvC2oB,EAA4B3oB,EAAKioB,GAE5BA,EAAUnkB,IASX4kB,EAAoB1lD,WARpBilD,EAAUnkB,IAAM9D,EAAI8D,IACpBmkB,EAAUllD,OAAS,WACfklD,EAAUllD,OAAS,KACnB6lD,GAAKX,GACLS,EAAoB1lD,aAM7B,WAICtK,EAAKuvD,GACLS,EAAoB1lD,YAGjB0lD,GAGXG,EAAqB,SAAS93C,EAAIvO,EAAMuP,GACpC,GAAIk2C,GAAYa,EAAa/3C,EAK7B,OAHAjb,GAAI,gCAAkCib,GACtCvO,EAAKumD,cAAgBh4C,EAEdre,EAAQ27C,eAAep2B,SAASzV,EAAMylD,EAAWl2C,GAAMnE,KAC1D,WACI44C,IACAoC,GAAKX,GACLC,EAAkBn3C,GAAI/N,WAE1B,WACIklD,EAAkBn3C,GAAI7N,UAIjBxQ,EAAQkxD,aAAasB,iBACtB8D,EAA+Bj4C,EAAIk3C,MAKnDgB,EAA4B,WACxB,GAAIvC,EAAqB3uD,OAAQ,CAC7B0uD,GAA+B,CAE/B,IAAIyC,GAAqBxC,EAAqBv9C,OAE1C+/C,GAAmBC,OACnBC,EAAkCF,GAGlCG,EAA+BH,OAInCzC,IAA+B,GAIvC6C,EAAY,SAASv4C,GACjB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBzwC,SAGtDqzC,EAAc,SAASz4C,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBa,iBAGtDgC,EAAY,SAAS3yD,GACjB,MAAOyyD,GAAcvxC,EAAW4uC,EAAgB9vD,EAAO,YAG3D4yD,EAAY,SAAS34C,GACjB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBc,eAGtDiC,EAAoB,WAChB,MAAOJ,GAAcvxC,EAAW4uC,EAAgBmB,iBAGpD6B,EAAc,SAAS74C,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBiB,eAGtD9vC,EAAU,SAAShH,GACf,MAAOo1C,GAAUG,IAAIv1C,IAAOrd,GAAGoxB,GAAU3pB,gBAAgByqD,EAAoB70C,IAGjFnI,EAAc,SAASmI,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB7wC,OAGtD8zC,EAAW,SAAS94C,GAChB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB75C,QAGtD+8C,EAAc,SAAS/4C,GAGnB,MAAU,OAANA,EACOw4C,EAAcvxC,EAAW4uC,EAAgBU,4BAC5CiC,EAAcvxC,EAAW4uC,EAAgBW,kBAI1CgC,EAAcxxC,EAAQhH,GAAK61C,EAAgBS,uBAC9CkC,EAAcxxC,EAAQhH,GAAK61C,EAAgB55C,cAGnD+8C,EAAW,SAASh5C,GAChB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBtsC,QAGtDvB,EAAU,SAAShI,GACf,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgB10C,OAGtD83C,EAAa,SAASj5C,GAClB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBY,UAGtD+B,EAAgB,SAAS3iD,EAASqjD,GAC9B,MAAOrjD,IAAWlT,GAAGkT,GAASzL,gBAAgB8uD,IAGlDnB,EAAe,SAAS/3C,GACpB,MAAO00C,IAAkB8D,EAAcxxC,EAAQhH,GAAK61C,EAAgBqB,YAGxEvvD,EAAO,SAASZ,GACZA,GAAMpE,GAAGoE,GAAI2C,SAAS/H,EAAQstB,QAAQtnB,OAM1CiwD,EAA8B,SAAS/hC,EAAaqhC,GAChD,GAAI37B,GAAW1F,EAAYjuB,MAAM2zB,SAC7BD,EAAYzF,EAAYjuB,MAAM0zB,SAE9BA,IAAaC,IAAa27B,EAAUtvD,MAAM2zB,WAAa27B,EAAUtvD,MAAM0zB,WACvE34B,GAAGu0D,GAAWtuD,KACV2yB,SAAUA,EACVD,UAAWA,KAQvB28B,EAAiC,SAASj4C,EAAIk3C,GAC1C,GAAIiC,GAAahC,EAAkBn3C,KAAO,GAAIrd,IAAGoP,SAAUI,UACvDinD,EAA2B,GAAIz2D,IAAGoP,OAqBtC,OAnBAqlD,GAA+Bv6C,KAAK,SAASoyB,GACzCkqB,EAAWt8C,KACP,WACIu8C,EAAyBnnD,WAE7B,WACI2lD,EAA4B3oB,EAAKioB,GAEjCA,EAAUllD,OAAS,WACfklD,EAAUllD,OAAS,KACnBonD,EAAyBnnD,WAG7BilD,EAAUnkB,IAAM9D,EAAI8D,IACpB8kB,GAAKX,OAKVkC,GAWXC,EAAsB,WAClB,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACArT,EACA4Q,EACAF,EACA4C,EACAC,CAKJ,IAHA90D,EAAI,oBAG0B,MAA1BpD,EAAQoyD,eACR,KAAM,IAAIjrD,OAAM,oDAIpB,IAAInG,GAAGoL,SAASpM,EAAQoyD,gBAAiB,CAGrC,GAFAuF,EAAWxpD,SAAS85B,eAAejoC,EAAQoyD,gBAE1B,OAAbuF,EACA,KAAM,IAAIxwD,OAAMnG,GAAG0L,OAAO,0CAA2C1M,EAAQoyD,gBAGjFwF,GAAaD,EAASjkD,cAErB,CACD,GAAyCpS,SAArCtB,EAAQoyD,eAAe1+C,UACvB,KAAM,IAAIvM,OAAM,gGAIpBywD,GAAa53D,EAAQoyD,eAAe1+C,UA4ExC,GAzEAkkD,EAAa52D,GAAGsL,QAAQsrD,GACxBE,EAAiB3pD,SAASC,cAAc,OACxC0pD,EAAeviD,YAAYvU,GAAGuS,UAAUqkD,IACxCM,EAAal3D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgB7zD,UAI5DL,EAAQmnB,SACR6wC,EAAgBh3D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgB/sC,QAC/D6wC,GACAh3D,GAAGg3D,GAAejxD,UASrB/F,GAAGyE,aAAgBzE,GAAGiW,kBAAkB8C,WACzCs7C,EAAiBr0D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBmB,gBAChEA,GACAr0D,GAAGq0D,GAAgBtuD,UAI3B49C,EAAW3jD,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBO,MAI1D9P,IAAa3jD,GAAGyE,cAChBrC,EAAI,0BAA2B,QAC/BpC,GAAG2jD,GAAU59C,UAGZ/F,GAAGiW,kBAAkB8C,SAajB/Y,GAAGk3D,GAAY/uD,aAAamqD,IAAwB3O,IACzDsT,EAAaj3D,GAAG2jD,GAAUl8C,gBAAgByrD,EAAgBkB,UAC1D6C,GAAcj3D,GAAGi3D,GAAYlxD,WAb7BmxD,EAAWr6C,gBAAgBy1C,GAEvB3O,GAAY3jD,GAAG2jD,GAAUx7C,aAAakqD,IAItCryD,GAAG2jD,GAAU19C,KACTf,QAAS,UAWrBqvD,EAAYv0D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBqB,WAC1DxC,EAGIwC,IACLtB,EAAmB3uB,SAASiwB,EAAUjsD,aAAa6pD,IAEnDc,EAAmBA,EAAmB,EAAIA,EAAmB,KAE7DjB,EAAchyD,GAAGu0D,GAAWpsD,aAAaiqD,IAPzCmC,GAAav0D,GAAGu0D,GAAWxuD,SAS/BgsD,EAAiBA,GAAkBwC,EAEnC3C,EAAsB5xD,GAAG82D,GAAgB5vD,WAAWgsD,EAAgBgB,mBAAmB7vD,OAAS,EAChGwtD,EAAsB7xD,GAAG82D,GAAgB5vD,WAAWgsD,EAAgBtsC,OAAOviB,OAAS,EAEpFwyD,EAAe72D,GAAG82D,GAAgBrvD,gBAAgByrD,EAAgBQ,MAE9C,MAAhBmD,EACA,KAAM,IAAI1wD,OAAM,0DAapB,OAVA4wD,GAAeF,EAAankD,UAC5BmkD,EAAankD,UAAY,GAGrBokD,EAAetvD,qBAAqB,UAAUnD,QAC9C8I,SAASC,cAAc,UAG3BhL,EAAI,8BAGAiuD,SAAUrwD,GAAGsL,QAAQwrD,EAAepkD,WACpCykD,aAAcn3D,GAAGsL,QAAQyrD,KAIjCK,EAAc,SAAShzD,EAAID,EAAOitB,GAC9B,GAAIimC,GAAWjmC,EACXkmC,EAAWD,EAASzvD,UAEpBzD,GAAQ,IACRmzD,EAAWt3D,GAAGq3D,GAAU3vD,WAAWvD,GAAO0D,aAI9CwvD,EAASzxD,aAAaxB,EAAIkzD,IAG9B3B,EAAiC,SAASH,GACtC,GAAIn4C,GAAKm4C,EAAmBn4C,GACxBk6C,EAAgB/B,EAAmB+B,cACnCC,EAAqBD,GAAiBA,EAAclC,cACpDd,EAAYa,EAAa/3C,GACzBgB,GACI0F,qBAAsByxC,EAAmBzxC,qBACzCF,QAASovC,EACTp4B,QAAQ,EACRzW,OAAO,EAGXpkB,IAAGiW,kBAAkBiD,cACjBq7C,EACIv1D,EAAQ03C,OAAO6a,WAAavyD,EAAQ03C,OAAO6a,WAAauB,GACxDwC,EAA+Bj4C,EAAIk3C,GACnCgB,KAGAR,EAAkBR,GAAW55C,KAAK,WAC9B65C,EAAkBn3C,GAAM,GAAIrd,IAAGoP,QAE/BolD,EAAkBn3C,GAAI1C,KAAK,WACvBkR,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,qBAM/B,MAAtB2G,EACAC,GAAiBp6C,EAAIm6C,GAGrBrC,EAAmB93C,EAAIk6C,EAAel5C,KAOlDk3C,IAGChB,IACLQ,EAAkBR,GAClBgB,MAIRG,EAAoC,SAASF,GACzC,GAAIn4C,GAAKm4C,EAAmBn4C,GACxBsL,EAAe6sC,EAAmB7sC,aAClC+uC,EAAiBlC,EAAmBkC,eACpCnD,EAAYa,EAAa/3C,GACzBgB,GACI0F,qBAAsByxC,EAAmBzxC,qBACzCK,MAAO4tC,EACPnuC,QAASovC,EAGjB,IAAIsB,EACA,GAAI5rC,EAAc,CACd,KAAI3pB,EAAQ03C,OAAO6a,WAAavyD,EAAQ03C,OAAO6a,WAAauB,GASxD,MAJI4E,IACA3C,EAAkBR,GAGfv1D,EAAQ27C,eAAep2B,SAASoE,EAAc4rC,EAAWl2C,GAAMnE,KAClE,WACIg7C,GAAKX,GACLzB,IACAjnC,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,oBAGzD,WACIyE,EAA+Bj4C,EAAIk3C,GACnC1oC,WAAW0pC,EAA2Bv2D,EAAQ03C,OAAOma,oBAjB7DyE,GAA+Bj4C,EAAIk3C,GACnCgB,QAsBJD,GAA+Bj4C,EAAIk3C,GACnCgB,KAKZoC,GAAsB,SAASt6C,EAAIu6C,GAC/B,GAAIC,GAAMzB,EAAY/4C,GAElBy6C,EAA4B,MAANz6C,EAAa61C,EAAgBW,iBAAmBX,EAAgB55C,WAEtFu+C,KAAQ73D,GAAG63D,GAAKpxD,SAASqxD,KACzBD,EAAM73D,GAAG63D,GAAKpwD,gBAAgBqwD,IAG9BD,IACA73D,GAAG63D,GAAK5xD,KAAK2mC,MAAOgrB,EAAU,MAC9BC,EAAIvjD,aAAa,gBAAiBsjD,KAI1C1C,GAAO,SAAS9wD,GACZA,GAAMpE,GAAGoE,GAAI4C,YAAYhI,EAAQstB,QAAQtnB,OAG7CyyD,GAAmB,SAASM,EAAmBC,GAC3C,GAAIC,GAAkB7C,EAAa2C,GAC/BG,EAAkB9C,EAAa4C,EAEnC51D,GAAIpC,GAAG0L,OAAO,qFAAsFqsD,EAAmBC,EAAmBA,IAG1IxD,EAAkBwD,GAAmB99C,KAAK,WACtC44C,IACA0B,EAAkBuD,GAAmBzoD,UACrClN,EAAIpC,GAAG0L,OAAO,uEAAwEssD,EAAmBD,IACzGE,EAAgB7nB,IAAM8nB,EAAgB9nB,IACtC8kB,GAAK+C,IAET,WACIzD,EAAkBuD,GAAmBvoD,UAChCxQ,EAAQkxD,aAAasB,iBACtB8D,EAA+ByC,EAAmBE,KAKlEj4D,IAAGwG,OAAOxH,EAASqf,GACnBjc,EAAMpD,EAAQoD,IAITpC,GAAGiW,kBAAkBiD,gBACtBla,EAAQ03C,OAAOma,kBAAoB,EACnC7xD,EAAQ03C,OAAO6a,UAAY,GAG/BjtC,EAAYtlB,EAAQqyD,YACpBU,EAA4CzxD,SAA3BtB,EAAQ27C,eACzBmX,EAAe4E,IAEf/B,IAEA30D,GAAGwG,OAAOvE,MACNsuC,OAAQ,WACJnuC,EAAI,8BAEJ0wD,EAAsB,EAEtBxuC,EAAU5R,UAAYo/C,EAAazB,SACnCrrD,EAAKixD,KACLh0D,KAAKk2D,oBACL/mC,EAAWpyB,EAAQsyD,iBAAmBuE,EAAcvxC,EAAW4uC,EAAgBQ,MAE/EtxD,EAAI,gCAGRuvD,cAAe,SAAStvD,GACpB,GAAI+1D,GAAep4D,GAAGuS,UAAUlQ,EAChCiiB,GAAU5R,UAAY,GACtB4R,EAAU/P,YAAY6jD,IAG1Br7C,MAAO,WACH9a,KAAKsuC,UAGT2W,WAAY,WACR91B,EAAS1e,UAAY,IAGzB87C,cAAe,WACXqE,GAAmB,GAGvBz0C,QAAS,SAASf,EAAIrc,EAAMq3D,EAAaC,EAAaC,GAClD,GAIIC,GAJAC,EAASz4D,GAAGuS,UAAUu/C,EAAaqF,cACnCuB,EAAa7C,EAAc4C,EAAQvF,EAAgB7wC,MACnD60C,EAAarB,EAAcvxC,EAAW4uC,EAAgB7zD,UACtDkjB,EAAgBg2C,EAAQ9F,EAAUC,QAAUthC,CAG5CmnC,KACA9F,EAAUG,IAAIv1C,GAAMo7C,GAGxBz4D,GAAGy4D,GAAQ1xD,SAASmrD,EAAoB70C,GACxC65C,EAAWr6C,gBAAgBy1C,GAEvBoG,IACA14D,GAAG04D,GAAY5wD,QAAQ9G,GACvB03D,EAAWpkD,aAAa,QAAStT,IAGrCy3D,EAAOnkD,aAAa29C,EAAc50C,GAE9Bg7C,EACAjB,EAAYqB,EAAQJ,EAAYl0D,MAAOoe,GAGvCA,EAAchO,YAAYkkD,GAG1BH,GACAG,EAAOxzD,MAAMC,QAAU,OACvBlF,GAAGy4D,GAAQ1xD,SAASyrD,KAGpBxtD,EAAKoxD,EAAY/4C,IACjBrY,EAAKqgB,EAAQhI,IACbrY,EAAKgxD,EAAU34C,IACfrY,EAAKqxD,EAASh5C,IACdrY,EAAKmxD,EAAS94C,IACdrY,EAAK8wD,EAAYz4C,IAEbw1C,GACA5wD,KAAK+pD,WAAW3uC,GAGpBm7C,EAAQpD,EAAa/3C,GACjBm7C,IAAUA,EAAMpoB,KAChBskB,EAA6Bx6C,KAAK,SAASy+C,GACvCH,EAAMpoB,IAAMuoB,EAAWvoB,IACnBuoB,EAAW1zD,MAAM0zB,WAAaggC,EAAW1zD,MAAM2zB,UAC/C54B,GAAGw4D,GAAOvyD,KACN0yB,UAAWggC,EAAW1zD,MAAM0zB,UAC5BC,SAAU+/B,EAAW1zD,MAAM2zB,WAInCs8B,GAAKsD,OAMrB7J,eAAgB,SAAStxC,EAAIrc,EAAMq3D,EAAaC,GAC5Cr2D,KAAKmc,QAAQf,EAAIrc,EAAMq3D,EAAaC,GAAa,IAGrDrR,cAAe,WACX71B,EAAS7c,YAAYk+C,EAAUC,SAC/BD,EAAUC,QAAUvlD,SAASwlD,yBAC7BF,EAAUG,QAGdnK,WAAY,SAASprC,GACjBrd,GAAGqkB,EAAQhH,IAAKtX,UAGpBqiD,UAAW,SAAShkD,GAChB,GAAIw0D,GAAcx0D,CAElB,IAAIw0D,EAAa,CAEb,KAAiD,MAA1CA,EAAYtwD,aAAa2pD,IAC5B2G,EAAcA,EAAY9yD,UAG9B,OAAOw+B,UAASs0B,EAAYtwD,aAAa2pD,MAIjD4G,YAAa,WACT,MAAOznC,IAGX85B,qBAAsB,SAAS7tC,GAC3B,GAAIvI,GAAWI,EAAYmI,EAE3BvI,IAAY9U,GAAG8U,GAAU/N,SAAS/H,EAAQstB,QAAQgkC,WAGtDxI,eAAgB,SAASzqC,EAAIrc,GACzB,GAAI83D,GAAa5jD,EAAYmI,EAEzBy7C,KACA94D,GAAG84D,GAAYhxD,QAAQ9G,GACvB83D,EAAWxkD,aAAa,QAAStT,KAIzC8pD,aAAc,SAASztC,GACnBrY,EAAKkQ,EAAYmI,KAGrB2tC,aAAc,SAAS3tC,GACnB63C,GAAKhgD,EAAYmI,KAGrB07C,WAAY,SAAS30D,GACjB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgB7wC,OAG3CqC,UAAW,WACP,MAAO1lB,GAAQmnB,QAAU0vC,EAAcvxC,EAAW4uC,EAAgB/sC,SAGtEwjC,mBAAoB,WAChB3kD,EAAKixD,MAGTvM,mBAAoB,WAChBwL,GAAKe,MAGTxM,YAAa,WACT,MAAOoM,GAAcvxC,EAAW4uC,EAAgBO,OAGpDtJ,uBAAwB,WACpB,MAAOyH,IAGXzG,UAAW,SAAS9tC,GAChBrY,EAAKqxD,EAASh5C,KAGlBmvC,gBAAiB,WACb,MAAOqF,IAGXpF,UAAW,SAASpvC,GAChB63C,GAAKmB,EAASh5C,KAGlBmqC,iBAAkB,SAASnqC,GACvB,MAAOgH,GAAQhH,IAGnB4tC,aAAc,SAAS5tC,GACnB,GAAI27C,GAAO9C,EAAY74C,EAEvB27C,IAAQh5D,GAAGg5D,GAAMjyD,SAAS/H,EAAQstB,QAAQgkC,WAG9C/I,gBAAiB,SAASlqC,GACtB,MAAOrd,IAAGqkB,EAAQhH,IAAK5W,SAAS+rD,IAGpCzH,aAAc,SAAS1tC,GACnB,GAAI27C,GAAO9C,EAAY74C,EAEvB27C,IAAQh5D,GAAGg5D,GAAMhyD,YAAYhI,EAAQstB,QAAQgkC,WAGjD2I,WAAY,SAAS70D,GACjB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBiB,cAAc,IAGzDvJ,aAAc,SAASvtC,GACnB,MAAOw4C,GAAcxxC,EAAQhH,GAAK61C,EAAgBgB,oBAGtDgF,YAAa,SAAS90D,GAClB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBgB,mBAAmB,IAG9DnI,eAAgB,SAAS1uC,EAAI+P,EAAQC,GACjC,GACIuqC,GADAC,EAAMzB,EAAY/4C,EAGlBw6C,IAAOxqC,EAAQ,IACfuqC,EAAUtxD,KAAKC,MAAM6mB,EAASC,EAAQ,KAEtB,MAAZuqC,EACA5yD,EAAK6yD,GAGL3C,GAAK2C,GAGTF,GAAoBt6C,EAAIu6C,KAIhCtZ,oBAAqB,SAASlxB,EAAQC,GAClCprB,KAAK8pD,eAAe,KAAM3+B,EAAQC,IAGtC4+B,aAAc,SAAS5uC,GACnB,GAAIw6C,GAAMzB,EAAY/4C,EAEtBw6C,IAAO7yD,EAAK6yD,IAGhBM,kBAAmB,WACfl2D,KAAKgqD,gBAGTsB,cAAe,SAASlwC,GACpBs6C,GAAoBt6C,EAAI,GACxBpb,KAAKk2D,kBAAkB96C,IAG3BquC,mBAAoB,WAChBzpD,KAAKsrD,iBAGThB,WAAY,SAASlvC,GACjB,IAAKw1C,EAAkB,CACnB,GAAIpwC,GAASmzC,EAAUv4C,EAEvBoF,IAAUziB,GAAGyiB,GAAQzb,YAAYhI,EAAQstB,QAAQtnB,QAIzDgnD,WAAY,SAAS3uC,GACjBrY,EAAK4wD,EAAUv4C,KAGnB87C,SAAU,SAAS/0D,GACf,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBzwC,QAAQ,IAGnDuqC,WAAY,SAAS3vC,GACjB63C,GAAKiB,EAAS94C,IACdrY,EAAK8wD,EAAYz4C,KAGrB0qC,aAAc,SAAS1qC,GACnBpb,KAAKmpD,cAAc/tC,EAAIre,EAAQ+I,KAAK2hC,QACpCznC,KAAKm3D,oBAAoB/7C,GACzBrY,EAAKsxD,EAAWj5C,KAGpBkuC,UAAW,SAASluC,GAChBrY,EAAKmxD,EAAS94C,KAGlBg8C,QAAS,SAASj1D,GACd,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgB75C,OAAO,IAGlDigD,iBAAkB,SAASl1D,GACvB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBa,gBAAgB,IAG3DqF,oBAAqB,SAAS/7C,GAC1B63C,GAAKY,EAAYz4C,IACjBrY,EAAKmxD,EAAS94C,KAGlB4qC,gBAAiB,SAAS5qC,GACtBpb,KAAKmpD,cAAc/tC,EAAI,IACvBpb,KAAK+qD,WAAW3vC,GAChB63C,GAAKoB,EAAWj5C,KAGpBwvC,iBAAkB,SAASxvC,GACvB63C,GAAKc,EAAU34C,KAGnBwwC,iBAAkB,SAASxwC,GACvBrY,EAAKgxD,EAAU34C,KAGnBk8C,eAAgB,SAASn1D,GACrB,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBc,cAAc,IAGzDwF,QAAS,SAASp1D,GACd,MAAOpE,IAAGoE,GAAIqC,SAASysD,EAAgBtsC,OAAO,IAGlDpH,WAAY,SAASnC,EAAItV,GACrB,GAAIyW,GAAO6G,EAAQhI,EAEfmB,KACA02C,GAAK12C,GACLxe,GAAGwe,GAAM1W,QAAQC,KAIzBqjD,cAAe,SAAS/tC,EAAItV,GACxB,GAAI0xD,GAAS5D,EAAcxxC,EAAQhH,GAAK61C,EAAgBe,WAEpDwF,KAEY,MAAR1xD,EACA/H,GAAGy5D,GAAQvxD,YAGXlI,GAAGy5D,GAAQ3xD,QAAQC,KAK/B0jD,YAAa,SAASpuC,GAClBrd,GAAGqkB,EAAQhH,IAAKrW,YAAYurD,GAC5BvtD,EAAKsxD,EAAWj5C,KAGpB0vC,YAAa,SAAS1vC,GAClBrd,GAAGqkB,EAAQhH,IAAKtW,SAASwrD,GACzB2C,GAAKoB,EAAWj5C,KAGpByxC,gBAAiB,SAASzxC,EAAIk6C,EAAexzC,GACpC9hB,KAAKslD,gBAAgBlqC,KACtB21C,EAAqBlxD,MAAMub,GAAIA,EAAI0G,qBAAsBA,EAAsBwzC,cAAeA,KAC7FxE,GAAgCwC,MAIzC3G,gBAAiB,SAASvxC,EAAIsL,EAAc+uC,EAAgB3zC,GACnD9hB,KAAKslD,gBAAgBlqC,KACtB21C,EAAqBlxD,MAAMiiB,qBAAsBA,EAAsB0xC,QAAQ,EAAMp4C,GAAIA,EAAIsL,aAAcA,EAAc+uC,eAAgBA,KACxI3E,GAAgCwC,MAIzCzE,UAAW,SAAS1tD,GAChB,MAAOpD,IAAGiW,kBAAkB4C,iBAAmBk9C,EAAU3yD,IAG7D2tD,WAAY,SAAS3tD,EAAMf,EAAS4uD,GAChC,GAAIyI,GAAS3D,EAAU3yD,GACnBu2D,EAAY9D,EAAc6D,EAAQxG,EAAgBI,eAClDsG,EAAUF,EAAOlyD,qBAAqB,SAAS,GAC/CqyD,EAAYhE,EAAc6D,EAAQxG,EAAgBE,oBAClD0G,EAAQjE,EAAc6D,EAAQxG,EAAgBK,gBAC9CpkD,EAAU,GAAInP,IAAGoP,QAEjB2qD,EAAe,WACXF,EAAUt0D,oBAAoB,QAASy0D,GACvCF,GAASA,EAAMv0D,oBAAoB,QAAS00D,GAC5C9qD,EAAQK,WAGZwqD,EAAqB,WACjBH,EAAUt0D,oBAAoB,QAASy0D,GACvCN,EAAOQ,SAGXD,EAAiB,WACbP,EAAOn0D,oBAAoB,QAASw0D,GACpCD,EAAMv0D,oBAAoB,QAAS00D,GACnCP,EAAOQ,QAEP/qD,EAAQG,QAAQsqD,GAAWA,EAAQjvD,OAc3C,OAXA+uD,GAAOt0D,iBAAiB,QAAS20D,GACjCF,EAAUz0D,iBAAiB,QAAS40D,GACpCF,GAASA,EAAM10D,iBAAiB,QAAS60D,GAErCL,IACAA,EAAQjvD,MAAQsmD,GAEpB0I,EAAU1xD,YAAc5F,EAExBq3D,EAAOS,YAEAhrD,MC/gCnBnP,GAAGo6D,eAAiB,SAASC,EAAGC,GAC5B,YAqBA,SAASxO,GAAWppD,GAChB8S,EAASrQ,OAAOzC,EAAS2b,EAAKk8C,UAAW,SAAS7jC,GAE9CA,EAAQA,GAASttB,OAAOstB,KAGxB,IAAI7mB,GAAS6mB,EAAM7mB,QAAU6mB,EAAM8jC,UAEnCn8C,GAAKo8C,UAAU5qD,EAAQ6mB,KA3B/B,GAAIlhB,GAAW,GAAIxV,IAAGqV,eAClBgJ,GACIk8C,UAAW,QACXG,SAAU,KACVD,UAAW,SAAS5qD,EAAQ6mB,KAKpC12B,IAAGwG,OAAOvE,MACN6pD,WAAY,SAASppD,GACjBopD,EAAWppD,IAGf6S,QAAS,WACLC,EAASD,aAiBjBvV,GAAGwG,OAAO8zD,GACNK,kBAAmB,SAASzvD,GACxB,MAAOA,GAAK0vD,UAGhBC,kBAAmB,WACf,MAAOrlD,MAIfxV,GAAGwG,OAAO6X,EAAMg8C,GAEZh8C,EAAKq8C,UACL5O,EAAWztC,EAAKq8C,WClDxB16D,GAAG2oD,wBAA0B,SAAS0R,GAClC,YAqBA,SAASS,GAAajrD,EAAQ6mB,GAC1B12B,GAAGY,KAAKm6D,EAAgB,SAASC,EAAYjqC,GACzC,GACIpN,GADAs3C,EAA2BD,EAAWp7D,OAAO,GAAGC,cAAgBm7D,EAAWl7D,MAAM,EAGrF,IAAIue,EAAKkrC,WAAW,KAAO0R,GAA0BprD,GAKjD,MAJA8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC7P,GAAGoS,eAAeskB,GAClBrY,EAAKjc,IAAIpC,GAAG0L,OAAO,+DAAgE2S,EAAK6rC,UAAUvmC,GAASA,IAC3GoN,EAAQpN,IACD,IA7BnB,GAAIu3C,MACA78C,GACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBC,aAAc,SAASnmC,KACvB8J,SAAU,SAAS9J,KACnBomC,QAAS,SAASpmC,KAClBqmC,QAAS,SAASrmC,KAClBsmC,WAAY,SAAStmC,KACrBumC,UAAW,SAASvmC,MAExBo3C,GACIt4C,OAAQ,SAASpF,GAAMgB,EAAKoP,SAASpQ,IACrCuJ,MAAQ,SAASvJ,GAAMgB,EAAK0rC,QAAQ1sC,IACpC22C,aAAc,SAAS32C,GAAMgB,EAAKyrC,aAAazsC,IAC/ChE,MAAO,SAASgE,GAAMgB,EAAK2rC,QAAQ3sC,IACnC02C,eAAgB,SAAS12C,GAAMgB,EAAK4rC,WAAW5sC,IAkBvDrd,IAAGwG,OAAO6X,EAAMg8C,GAEhBh8C,EAAKk8C,UAAY,QACjBl8C,EAAKo8C,UAAYK,EACjBz8C,EAAKq8C,SAAWr8C,EAAKkrC,WAAWsP,cAEhC74D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo6D,eAAe/7C,EAAM68C,KC1ChDl7D,GAAGoqD,qBAAuB,SAASiQ,GAC/B,YAiBA,SAASS,GAAajrD,EAAQ6mB,GAC1B,GAAIrY,EAAKkrC,WAAWwP,WAAWlpD,IAAWwO,EAAKkrC,WAAW0P,WAAWppD,GAAS,CAC1E,GAAI8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC8N,EAASU,EAAKksC,kBAAkB5mC,EAGhChG,KAAW3d,GAAG2d,OAAOoC,YACrB1B,EAAKjc,IAAIpC,GAAG0L,OAAO,4DAA6D2S,EAAK6rC,UAAUvmC,GAASA,IACxG3jB,GAAGoS,eAAeskB,GAElBwkC,EAAqBC,mBAAmBx3C,EAAQ9T,GAAQ,KAzBpE,GAAIqrD,MACA78C,GACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBv9B,SACIjK,KAAM,iBACN8xC,aAAc,yBAElB5J,kBAAmB,SAAS5mC,KAC5BumC,UAAW,SAASvmC,KAG5B3jB,IAAGwG,OAAO6X,EAAMg8C,GAkBhBh8C,EAAKk8C,UAAY,QACjBl8C,EAAKo8C,UAAYK,EAEjB96D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo7D,oBAAoB/8C,EAAM68C,KCpCrDl7D,GAAGwrD,4BAA8B,SAAS6O,EAAGa,GACzC,YAaA,SAASG,GAAiBxrD,EAAQ6mB,GAC9B,GAAIrY,EAAKkrC,WAAW2P,YAAYrpD,GAAS,CACrC,GAAI8T,GAAStF,EAAKkrC,WAAWnB,UAAUv4C,GACnC8N,EAASU,EAAKksC,kBAAkB5mC,EAEhChG,KAAW3d,GAAG2d,OAAOoC,YACrB1B,EAAKjc,IAAIpC,GAAG0L,OAAO,kEAAmE2S,EAAK6rC,UAAUvmC,GAASA,IAC9Gu3C,EAAqBC,mBAAmBx3C,EAAQ9T,KAlB5D,GAAIwO,IACIkrC,WAAY,KACZgB,kBAAmB,SAAS5mC,KAC5BvhB,IAAK,SAASC,EAASwnD,KAG1BqR,KACDA,MAgBJ78C,EAAKk8C,UAAY,UACjBl8C,EAAKo8C,UAAYY,EAEjBr7D,GAAGwG,OAAO6X,EAAMg8C,GAChBr6D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo7D,oBAAoB/8C,EAAM68C,KCzBrDl7D,GAAGqqD,0BAA4B,SAAShsC,GACpC,YAEAA,GAAKk8C,UAAY,QACjBl8C,EAAKq8C,SAAW,KAEhB16D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGwrD,4BAA4BntC,QCVvDre,GAAGo7D,oBAAsB,SAASf,EAAGa,GACjC,YAWA,SAASI,GAAyB33C,GAC9B,GAAI43C,GAAkBl9C,EAAK6rC,UAAUvmC,GACjC5O,EAASwmD,EAAgBvmD,YAAY,IAMzC,OAJID,GAAS,IACTwmD,EAAkBA,EAAgBtmD,OAAO,EAAGF,IAGzCwmD,EAGX,QAASC,GAAqB73C,GAC1B,GAAI83C,GAAWp9C,EAAK6rC,UAAUvmC,EAC9B,OAAO3jB,IAAG6U,aAAa4mD,GAI3B,QAASC,GAAiBC,EAAoBh4C,GAC1C,GACIi4C,GADAr8C,EAAUo8C,EAAmBhxD,KAGjBrK,UAAZif,GAAyBvf,GAAGsL,QAAQiU,GAASlb,OAAS,IACtDu3D,EAAgBJ,EAAqB73C,GAEfrjB,SAAlBs7D,IACAr8C,EAAUA,EAAU,IAAMq8C,GAG9Bv9C,EAAKmsC,UAAU7mC,EAAQpE,IAG3BlB,EAAKosC,sBAAsB9mC,GAAQ,GAIvC,QAASk4C,GAAyBjC,EAASj2C,GACvCu3C,EAAqBL,oBAAoB11D,OAAOy0D,EAAS,OAAQ,WAC7D8B,EAAiB9B,EAASj2C,KAKlC,QAASm4C,GAA6BlC,EAASj2C,GAC3Cu3C,EAAqBL,oBAAoB11D,OAAOy0D,EAAS,QAAS,SAASljC,GAEvE,GAAIpE,GAAOoE,EAAMqlC,SAAWrlC,EAAMslC,KAErB,MAAT1pC,GACAopC,EAAiB9B,EAASj2C,KAzDtC,GAAItF,IACIkrC,WAAY,KACZnnD,IAAK,SAASC,EAASwnD,KACvBU,kBAAmB,SAAS5mC,KAC5BumC,UAAW,SAASvmC,KACpB6mC,UAAW,SAAS7mC,EAAQpE,KAC5BkrC,sBAAuB,SAAS9mC,EAAQ+mC,KAwDhD1qD,IAAGwG,OAAO6X,EAAMg8C,GAEhBh8C,EAAKq8C,SAAWr8C,EAAKkrC,WAAWsP,cAEhC74D,GAAGwG,OAAOvE,KAAM,GAAIjC,IAAGo6D,eAAe/7C,EAAM68C,IAE5Cl7D,GAAGwG,OAAO00D,GACNC,mBAAoB,SAAS99C,EAAIxN,EAAQosD,GACrC,GAAIN,GAAqBt9C,EAAKkrC,WAAWqB,aAAavtC,EAEtDgB,GAAKosC,sBAAsBptC,GAAI,GAE/Bs+C,EAAmBhxD,MAAQ2wD,EAAyBj+C,GAEhD4+C,GACAN,EAAmBO,QAGvBL,EAAyBF,EAAoBt+C,GAC7Cy+C,EAA6BH,EAAoBt+C,Q7CvF9BjU","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js index 4d1ee506f..8ac83d6a9 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js @@ -1,7 +1,7 @@ -// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com -!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");return t?(void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n),void 0):void 0===n?null:n[e]}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function l(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function u(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&l(n)){if(a.push(u.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[l];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),l}function n(e,t){var n=l.data(u);return t?(void 0===n&&(n={}),n[e]=t,l.data(u,n),void 0):void 0===n?null:n[e]}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=l,n[e]=function(){var e=Array.prototype.slice.call(arguments),t=i.triggerHandler(o,e);return t}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[],n=Array.prototype.slice.call(arguments,1);return r(n,t),i()[e].apply(i(),t)}var l,u="fineUploaderDnd";e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,u=[];return this.each(function(c,d){if(l=e(d),i()&&a(n)){if(u.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===u.length?u[0]:u.length>1?u:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){var o=n.substring(0,i),r=n.substring(i+2);if(n=o+t+r,i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.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(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){var i=e.slice||e.mozSlice||e.webkitSlice;return i.call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function i(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function r(){return!!i()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function s(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function l(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,c,d,p,h,f,q,m,g,_,v,b,y,S,w;return u=e(),p=u&&qq.isXhrUploadSupported(),c=p&&!qq.androidStock(),d=p&&l(),h=d&&t(),f=p&&qq.isFileChunkingSupported(),q=p&&f&&s(),m=p&&n(),g=u&&(void 0!==window.postMessage||p),v=i(),_=o(),b=r(),y=a(),S=p&&void 0!==window.FileReader,w=function(){return!!p&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:p,blobUploading:c,canDetermineSize:p,chunking:f,deleteFileCors:b,deleteFileCorsXdr:_,deleteFileCorsXhr:v,dialogElement:!!window.HTMLDialogElement,fileDrop:d,folderDrop:h,folderSelection:y,imagePreviews:S,imageValidation:S,itemSizeValidation:p,pause:f,progressBar:w,resume:q,scaling:S&&c,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:g,uploadCustomHeaders:p,uploadNonMultipart:p,uploadViaPaste:m}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},l={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===l[t.batchId]&&(l[t.batchId]=[]),l[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},reset:function(){o=[],r={},a={},l={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){var t=o[e].batchId;return l[t]}})},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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),l=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),u=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(u(),qq.each(e,function(e,t){qq.isFileOrInput(t)?l(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){return this._handler.getFile(e)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"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(e,t){t.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(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL});return e.deleteFileEndpoint&&this.setDeleteFileEndpoint(e.deleteFileEndpoint,t),e.deleteFileParams&&this.setDeleteFileParams(e.deleteFileParams,t),e.thumbnailUrl&&(this._thumbnailUrls[t]=e.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,t},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},l=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),l(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t),n._options.callbacks.onUpload(e,t)},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i),n._options.callbacks.onUploadChunk(e,t,i)},onUploadChunkSuccess:function(e,t,i,o){n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i){return n._options.callbacks.onResume(e,t,i)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999); -return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e="image/*;capture=camera",t=this._options.camera.button,n=t?this._getButtonId(t):this._defaultButtonId,i=this._options;n&&n!==this._defaultButtonId&&(i=this._extraButtonSpecs[n]),i.multiple=!1,null===i.validation.acceptFiles?i.validation.acceptFiles=e:i.validation.acceptFiles+=","+e,qq.each(this._buttons,function(e,t){if(t.getButtonId()===n)return t.setMultiple(i.multiple),t.setAcceptFiles(i.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,l=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),l(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],l=[].concat(t),u=l[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(u)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,l[e])}),this._options.callbacks.onError(null,u,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){var i=this.getName(e);n?(this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+i+"' has failed.","error"),void 0===t.withCredentials?this._options.callbacks.onError(e,i,"Delete request failed",t):this._options.callbacks.onError(e,i,"Delete request failed with response code "+t.status,t)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+i+"' has succeeded."))},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e,t,n){var i=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&i.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),l.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},l=S.method,u={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==l&&"PUT"!==l||o.setRequestHeader("Content-Type",S.contentType),qq.extend(u,qq.isFunction(a)?a(e):a),qq.extend(u,s),qq.each(u,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a};var s=b.push(e);if(s<=S.maxConnections)return u(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise,a=i(e,o(e),r);a.then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,l={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){}},u={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,l.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=l.getSize(e),n=l.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);l.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),r.reset&&u.reset(e),l.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=l.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);h.reset?u.reset(t):(d=qq.indexOf(o._getFileState(t).chunking.inProgress,e),d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))),o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),l.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0},sendNext:function(e){var t=l.getSize(e),n=l.getName(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e).attemptingResume,h=o._getFileState(e).chunking.inProgress||[];null==o._getFileState(e).loaded&&(o._getFileState(e).loaded=0),d&&l.onResume(e,n,a)===!1&&(u.reset(e),r=u.nextPart(e),a=o._getChunkData(e,r),d=!1),null==r&&0===h.length?u.finalize(e):(i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t)),l.onUploadChunk(e,n,o._getChunkDataForCallback(a)),h.push(r),o._getFileState(e).chunking.inProgress=h,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&u.sendNext(e),0===a.blob.size?(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),u.handleFailure(r,e,"File is no longer available",null)):o.uploadChunk(e,r,d).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),l=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),u.done(e,r,s,n),l>=0&&a.splice(l,1),o._maybePersistChunkedState(e),u.hasMoreParts(e)||0!==a.length?u.hasMoreParts(e)?u.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):u.finalize(e)},function(t,n){u.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)}))}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=l.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0; -},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):!function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){o._getFileState(e).loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=l.getSize(e);l.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);l.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),l.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=l.getName(e);l.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){var e=t?qq[t]:qq.traditional,n=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";o=new e[n+"UploadHandler"](l,{getDataByUuid:l.getDataByUuid,getName:l.getName,getSize:l.getSize,getUuid:l.getUuid,log:i,onCancel:l.onCancel,onProgress:l.onProgress,onUuidChanged:l.onUuidChanged}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return l.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(l.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),l.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),l.onComplete(e,l.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=l.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&l.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=l.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");l.onUpload(e,t),a&&o._shouldChunkThisFile(e)?u.sendNext(e):d.send(e,t)},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(l,e),i=l.log,a=l.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&l.chunking.concurrent.enabled,n=function(){var e={};return e[l.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i),r=f(o);u[r]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&u[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=u[r],delete u[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,l=qq.getUniqueId(),u={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){var t=a._getIframeName(e);return i(t)},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+l},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=e.options.resume,s=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=a&&e.options.resume.enabled&&s&&qq.supportedFeatures.resume,u=o.getName,c=o.getSize,d=o.getUuid,p=o.getEndpoint,h=o.getDataByUuid,f=o.onUuidChanged,q=o.onProgress,m=o.log;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){delete n._getFileState(e).temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),e.push(o)}),e},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=t||n._getFileState(e).chunking.inProgress,r=i||n._getFileState(e).chunking.remaining;o&&(m(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(o))),o.reverse(),qq.each(o,function(e,t){r.unshift(t)}),o.length=0)},pause:function(e){if(n.isValid(e))return m(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,u(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,u=n._getTotalChunks(e),d=this._getFileState(e).temp.cachedChunks,p=d[t]||qq.sliceBlob(a,s,l);return d[t]=p,{part:t,start:s,end:l,count:u,blob:p,size:l-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t="5.0",n=u(e),o=c(e),a=r.partSize,s=p(e);return qq.format("qq{}resume{}-{}-{}-{}-{}",i,t,n,o,a,s)},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=c(e),n=r.partSize;return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){var o=JSON.parse(n);e(t,o)}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),h(i.uuid)?n._markNotResumable(e):(m(qq.format("Identified file with ID {} and name of {} as resumable.",e,u(e))),f(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){t=n._getLocalStorageId(e),i={name:u(e),size:c(e),uuid:d(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()};try{localStorage.setItem(t,JSON.stringify(i))}catch(t){m(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=u(e),a={simple:function(t,n){var i=c(e);t===n?q(e,r,i,i):q(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,l=n._getFileState(e).loaded,u=o,d=a,p=c(e),h=u-(d-i),f=l;s[t]=h,qq.each(s,function(e,t){f+=t}),q(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){var t=null==i?"simple":"chunked";a[t](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=a.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(m("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),l=0,u=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>l;)r=o[4*(c-1)+3],0===r?u=c:l=c,c=u+l>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){var t=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>t)return{newHeight:Math.round(Math.sqrt(t*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(t*(e.origWidth/e.origHeight)))}}function o(n,o,s,l,u){var c,d=n.naturalWidth,p=n.naturalHeight,h=l.width,f=l.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),l.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:l.orientation,resize:l.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,l.orientation),qq.ios()?!function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),l=u?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/l),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
c&&(l=c,u=s*l/a<<0),d&&u>d&&(u=d,l=a*u/s<<0),i={width:l,height:u},qq.each(t,function(e,t){i[e]=t}),"img"===h?!function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),void("function"==typeof this.onrender&&this.onrender(e)))},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function l(e,t){e.qqImageRendered=function(){t.success(e)}}function u(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?l(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,l=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,l);u(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,l=new qq.Promise;u(s,l),a(e)&&(s.crossOrigin="anonymous"),s.src=e,l.then(function(){u(t,n);var a=new qq.MegaPixImage(s);a.render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){u(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var l=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,l,h):d(e,r,l,h):p(e,r,l,h):n(r)?d(e,r,l,h):u(r,l)&&(r.src=e),l}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){return i?o.success(n(e)):void o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function l(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function u(e,t){var i=16,o=qq.extend([],c),r={};return qq.each(t,function(t,a){var s,l,u,c=a.slice(0,4),p=e?n(c):parseInt(c,16),h=o.indexOf(p);if(h>=0&&(l=d[p].name,u=d[p].bytes,s=a.slice(i,i+2*u),r[l]=e?n(s):parseInt(s,16),o.splice(h,1)),0===o.length)return!1}),r}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=l(i),r=u(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){return!!qq.isArray(e)||void i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i),r=new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t}));return r.queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,l=e.includeExif,u=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&u.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d,q=new qq.Identify(f,t);return q.isPreviewableSync()?(qq.each(u,function(e,i){var u=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:u,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:u,quality:a,failedText:s,includeExif:l,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var l=this,u=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(l.getFileRecords(n,t,e),function(e,t){var n,i=t.size;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?u.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(u,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),u.length&&!function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,l=a&&a.uuid,u={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(u,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(l,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", -e.encode64=function(e){var t,n,i,o,r,a="",s="",l="",u=0;do t=e[u++],n=e[u++],s=e[u++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,l=63&s,isNaN(n)?r=l=64:isNaN(s)&&(l=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(l),t=n=s="",i=o=r=l="";while(ue.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",l=0,u=[],c=/[^A-Za-z0-9\+\/\=]/g;if(c.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(l++)),o=this.KEY_STR.indexOf(e.charAt(l++)),r=this.KEY_STR.indexOf(e.charAt(l++)),s=this.KEY_STR.indexOf(e.charAt(l++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,u.push(t),64!=r&&u.push(n),64!=s&&u.push(a),t=n=a="",i=o=r=s="";while(l=0)return n=!1,!1}),n},u=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||l(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,l=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=l):(t&&(i+=t-a),r&&(o+=r-l)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?u(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){return!(e.checkValidity&&!e.checkValidity())||(n("Form did not pass validation checks - will not upload.","error"),void t())}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),l&&r(e))),e}var s=this,l=e.interceptSubmit,u=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==u?null:s._form2Obj(u)}}),u=a(u),this.attachedToForm=!!u},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1&&!u.allowMultipleItems?(u.callbacks.processingDroppedFilesComplete([]),u.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(h=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?h.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):h=e.files,0===i.length&&o.success()),o}function r(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:c,element:e,onEnter:function(t){qq(e).addClass(u.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(u.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,n).then(function(){t(h,n)},function(){u.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return f.addDisposer(function(){n.dispose()}),qq(e).hasAttribute(d)&&qq(e).hide(),p.push(n),n}function a(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function s(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=u.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute(d)&&qq(t).hide(),qq(t).removeClass(u.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=r(n);e.length&&qq.supportedFeatures.fileDrop&&f.attach(document,"dragenter",function(t){!i.dropDisabled()&&a(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute(d)&&qq(t).css({display:"block"})})})}),f.attach(document,"dragleave",function(e){s(e)&&t()}),f.attach(qq(document).children()[0],"mouseenter",function(e){t()}),f.attach(document,"drop",function(e){e.preventDefault(),t()}),f.attach(document,c,t)}var u,c="qq-hidezones",d="qq-hide-dropzone",p=[],h=[],f=new qq.DisposeSupport;u={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(u,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){u.dropZoneElements.push(e),r(e)},removeDropzone:function(e){var t,n=u.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){f.dispose(),qq.each(p,function(e,t){t.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files||!i&&n.types.contains&&n.types.contains("Files"))}function o(e){return void 0!==e&&(u=e),u}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(l,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===t||"linkMove"===t?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),d.attach(l,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(l,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(l,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,l,u,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),l=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return l}})},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){var t=this.getFile(e);return t.qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(l._classes.retrying),a.hideProgress(e),l.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?l._markFileAsSuccessful(e):(qq(s).addClass(l._classes.fail),a.showCancel(e),a.isRetryPossible()&&!l._preventRetries[e]&&(qq(s).addClass(l._classes.retryable),a.showRetry(e)),l._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),l=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e],n=this.getUploads({id:e}).status;n===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){return n._templating.hasDialog("alert")?n._templating.showDialog("alert",e):void setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,l,u="qq-file-id",c="qq-file-id-",d="qq-max-size",p="qq-server-scale",h="qq-hide-dropzone",f="qq-drop-area-text",q="qq-in-progress",m="qq-hidden-forever",g={content:document.createDocumentFragment(),map:{}},_=!1,v=0,b=!1,y=[],S=-1,w={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null, -classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},F={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},x={},C=new qq.Promise,E=new qq.Promise,I=function(){var e=w.placeholders.thumbnailNotAvailable,n=w.placeholders.waitingForThumbnail,i={maxSize:S,scale:l};s&&(e?w.imageGenerator.generate(e,new Image,i).then(function(e){C.success(e)},function(){C.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):C.failure(),n?w.imageGenerator.generate(n,new Image,i).then(function(e){E.success(e)},function(){E.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):E.failure())},P=function(e){var t=new qq.Promise;return E.then(function(n){Q(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,te(e),t.success()})},function(){W(e),t.success()}),t},D=function(e,n,i){var o=X(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,w.imageGenerator.generate(n,o,i).then(function(){v++,te(o),x[e].success()},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,o)})},T=function(){if(y.length){b=!0;var e=y.shift();e.update?$(e):K(e)}else b=!1},U=function(e){return V(L(e),F.cancel)},k=function(e){return V(L(e),F.continueButton)},A=function(e){return V(r,F[e+"Dialog"])},R=function(e){return V(L(e),F.deleteButton)},B=function(){return V(r,F.dropProcessing)},N=function(e){return V(L(e),F.editNameIcon)},L=function(e){return g.map[e]||qq(a).getFirstByClass(c+e)},O=function(e){return V(L(e),F.file)},H=function(e){return V(L(e),F.pause)},z=function(e){return null==e?V(r,F.totalProgressBarContainer)||V(r,F.totalProgressBar):V(L(e),F.progressBarContainer)||V(L(e),F.progressBar)},M=function(e){return V(L(e),F.retry)},j=function(e){return V(L(e),F.size)},G=function(e){return V(L(e),F.spinner)},V=function(e,t){return e&&qq(e).getFirstByClass(t)},X=function(e){return s&&V(L(e),F.thumbnail)},W=function(e){e&&qq(e).addClass(w.classes.hide)},Q=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},Y=function(e,t){var n=x[e]||(new qq.Promise).failure(),i=new qq.Promise;return C.then(function(e){n.then(function(){i.success()},function(){Q(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,te(t)})}),i},J=function(){var e,o,r,a,u,c,q,m,g,_,v;if(t("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(e=document.getElementById(w.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));o=e.innerHTML}else{if(void 0===w.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=w.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),v=qq(a).getFirstByClass(F.uploader),w.button&&(c=qq(a).getFirstByClass(F.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(g=qq(a).getFirstByClass(F.dropProcessing),g&&qq(g).remove()),q=qq(a).getFirstByClass(F.drop),q&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(q).remove()),qq.supportedFeatures.fileDrop?qq(v).hasAttribute(f)&&q&&(_=qq(q).getFirstByClass(F.dropText),_&&qq(_).remove()):(v.removeAttribute(f),q&&qq(q).hasAttribute(h)&&qq(q).css({display:"none"})),m=qq(a).getFirstByClass(F.thumbnail),s?m&&(S=parseInt(m.getAttribute(d)),S=S>0?S:null,l=qq(m).hasAttribute(p)):m&&qq(m).remove(),s=s&&m,n=qq(a).getByClass(F.editFilenameInput).length>0,i=qq(a).getByClass(F.retry).length>0,r=qq(a).getFirstByClass(F.list),null==r)throw new Error("Could not find the file list container in the template!");return u=r.innerHTML,r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:qq.trimStr(a.innerHTML),fileTemplate:qq.trimStr(u)}},Z=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},K=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=X(t),r={customResizeFunction:e.customResizeFunction,maxSize:S,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?w.limits.maxThumbs&&w.limits.maxThumbs<=v?(Y(t,o),T()):P(o).done(function(){x[t]=new qq.Promise,x[t].done(function(){setTimeout(T,w.limits.timeBetweenThumbs)}),null!=i?ne(t,i):D(t,n,r)}):T():o&&(P(o),T())},$=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=X(t),r={customResizeFunction:e.customResizeFunction,scale:l,maxSize:S};if(o)if(n){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=v))return i&&P(o),w.imageGenerator.generate(n,o,r).then(function(){te(o),v++,setTimeout(T,w.limits.timeBetweenThumbs)},function(){Y(t,o),setTimeout(T,w.limits.timeBetweenThumbs)});Y(t,o),T()}else Y(t,o),T()},ee=function(e,t){var n=z(e),i=null==e?F.totalProgressBar:F.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},te=function(e){e&&qq(e).removeClass(w.classes.hide)},ne=function(e,n){var i=X(e),o=X(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),x[n].then(function(){v++,x[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,te(i)},function(){x[e].failure(),w.placeholders.waitUntilUpdate||Y(e,i)})};qq.extend(w,e),t=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),r=w.containerEl,s=void 0!==w.imageGenerator,o=J(),I(),qq.extend(this,{render:function(){t("Rendering template in DOM."),v=0,r.innerHTML=o.template,W(B()),this.hideTotalProgress(),a=w.fileContainerEl||V(r,F.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){_=!0},addFile:function(e,t,n,i,s){var l,d=qq.toElement(o.fileTemplate),p=V(d,F.file),h=V(r,F.uploader),q=s?g.content:a;s&&(g.map[e]=d),qq(d).addClass(c+e),h.removeAttribute(f),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute(u,e),n?Z(d,n.index,q):q.appendChild(d),i?(d.style.display="none",qq(d).addClass(m)):(W(z(e)),W(j(e)),W(R(e)),W(M(e)),W(H(e)),W(k(e)),_&&this.hideCancel(e),l=X(e),l&&!l.src&&E.then(function(e){l.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(l).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),te(l)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(g.content),g.content=document.createDocumentFragment(),g.map={}},removeFile:function(e){qq(L(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute(u);)t=t.parentNode;return parseInt(t.getAttribute(u))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=O(e);t&&qq(t).addClass(w.classes.editable)},updateFilename:function(e,t){var n=O(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){W(O(e))},showFilename:function(e){te(O(e))},isFileName:function(e){return qq(e).hasClass(F.file)},getButton:function(){return w.button||V(r,F.button)},hideDropProcessing:function(){W(B())},showDropProcessing:function(){te(B())},getDropZone:function(){return V(r,F.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){W(M(e))},isRetryPossible:function(){return i},showRetry:function(e){te(M(e))},getFileContainer:function(e){return L(e)},showEditIcon:function(e){var t=N(e);t&&qq(t).addClass(w.classes.editable)},isHiddenForever:function(e){return qq(L(e)).hasClass(m)},hideEditIcon:function(e){var t=N(e);t&&qq(t).removeClass(w.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(F.editNameIcon,!0)},getEditInput:function(e){return V(L(e),F.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(F.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=z(e);o&&n>0&&(i=Math.round(t/n*100),100===i?W(o):te(o),ee(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=z(e);t&&W(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){ee(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!_){var t=U(e);t&&qq(t).removeClass(w.classes.hide)}},hideCancel:function(e){W(U(e))},isCancel:function(e){return qq(e).hasClass(F.cancel,!0)},allowPause:function(e){te(H(e)),W(k(e))},uploadPaused:function(e){this.setStatusText(e,w.text.paused),this.allowContinueButton(e),W(G(e))},hidePause:function(e){W(H(e))},isPause:function(e){return qq(e).hasClass(F.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(F.continueButton,!0)},allowContinueButton:function(e){te(k(e)),W(H(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),te(G(e))},showDeleteButton:function(e){te(R(e))},hideDeleteButton:function(e){W(R(e))},isDeleteButton:function(e){return qq(e).hasClass(F.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(F.retry,!0)},updateSize:function(e,t){var n=j(e);n&&(te(n),qq(n).setText(t))},setStatusText:function(e,t){var n=V(L(e),F.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(L(e)).removeClass(q),W(G(e))},showSpinner:function(e){qq(L(e)).addClass(q),te(G(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(y.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!b&&T())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(y.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!b&&T())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!A(e)},showDialog:function(e,t,n){var i=A(e),o=V(i,F.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=V(i,F.dialogCancelButton),s=V(i,F.dialogOkButton),l=new qq.Promise,u=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),l.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",u),s.removeEventListener("click",d),i.close(),l.success(r&&r.value)};return i.addEventListener("close",u),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),l}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e),r=i.onGetUploadStatus(o);r===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){var i=t.keyCode||t.which;13===i&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); +// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com +!function(global){!function(e){"use strict";function t(e){var t=s(e||{}),i=n(t);return o(i),a(t,i),d}function n(e){var t=r("uploaderType"),n=r("endpointType");return t?(t=t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),n?new qq[n]["FineUploader"+t](e):new qq["FineUploader"+t](e)):n?new qq[n].FineUploader(e):new qq.FineUploader(e)}function i(e,t){var n=d.data("fineuploader");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,d.data("fineuploader",n)}function o(e){return i("uploader",e)}function r(e,t){return i(e,t)}function a(t,n){var i=t.callbacks={};e.each(n._options.callbacks,function(t,n){var o,r;o=/^on(\w+)/.exec(t)[1],o=o.substring(0,1).toLowerCase()+o.substring(1),r=d,i[t]=function(){var t,i,a=Array.prototype.slice.call(arguments),s=[];e.each(a,function(e,t){s.push(c(t))}),t=n.apply(this,a);try{i=r.triggerHandler(o,s)}catch(e){qq.log("Caught error in Fine Uploader jQuery event handler: "+e.message,"error")}return null!=t?t:i}}),n._options.callbacks=i}function s(t,n){var i,o;if(i=void 0===n?"basic"!==t.uploaderType?{element:d[0]}:{}:n,e.each(t,function(t,n){e.inArray(t,p)>=0?r(t,n):n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},s(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){var i={};n instanceof e?e.merge(o,n):e.isPlainObject(n)?(s(n,i),o.push(i)):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function u(t){return"string"===e.type(t)&&!t.match(/^_/)&&void 0!==o()[t]}function l(e){var t,n=[],i=Array.prototype.slice.call(arguments,1);return s(i,n),t=o()[e].apply(o(),n),c(t)}function c(t){var n=t;return null==t||"object"!=typeof t||1!==t.nodeType&&9!==t.nodeType||!t.cloneNode||(n=e(t)),n}var d,p=["uploaderType","endpointType"];e.fn.fineUploader=function(n){var i=this,r=arguments,a=[];return this.each(function(s,c){if(d=e(c),o()&&u(n)){if(a.push(l.apply(i,r)),1===i.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist on jQuery.fineUploader"):t.apply(i,r)}),1===a.length?a[0]:a.length>1?a:this}}(jQuery),function(e){"use strict";function t(e){e||(e={}),e.dropZoneElements=[u];var t=r(e);return o(t),i(new qq.DragAndDrop(t)),u}function n(e,t){var n=u.data("fineUploaderDnd");if(!t)return void 0===n?null:n[e];void 0===n&&(n={}),n[e]=t,u.data("fineUploaderDnd",n)}function i(e){return n("dndInstance",e)}function o(t){var n=t.callbacks={};e.each(new qq.DragAndDrop.callbacks,function(e,t){var i,o=e;i=u,n[e]=function(){var e=Array.prototype.slice.call(arguments);return i.triggerHandler(o,e)}})}function r(t,n){var i,o;if(i=void 0===n?{}:n,e.each(t,function(t,n){n instanceof e?i[t]=n[0]:e.isPlainObject(n)?(i[t]={},r(n,i[t])):e.isArray(n)?(o=[],e.each(n,function(t,n){n instanceof e?e.merge(o,n):o.push(n)}),i[t]=o):i[t]=n}),void 0===n)return i}function a(t){return"string"===e.type(t)&&"dispose"===t&&void 0!==i()[t]}function s(e){var t=[];return r(Array.prototype.slice.call(arguments,1),t),i()[e].apply(i(),t)}var u;e.fn.fineUploaderDnd=function(n){var o=this,r=arguments,l=[];return this.each(function(c,d){if(u=e(d),i()&&a(n)){if(l.push(s.apply(o,r)),1===o.length)return!1}else"object"!=typeof n&&n?e.error("Method "+n+" does not exist in Fine Uploader's DnD module."):t.apply(o,r)}),1===l.length?l[0]:l.length>1?l:this}}(jQuery);var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(t,n){return e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on"+t,n),function(){qq(e).detach(t,n)}},detach:function(t,n){return e.removeEventListener?e.removeEventListener(t,n,!1):e.attachEvent&&e.detachEvent("on"+t,n),this},contains:function(t){return!!t&&(e===t||(e.contains?e.contains(t):!!(8&t.compareDocumentPosition(e))))},insertBefore:function(t){return t.parentNode.insertBefore(e,t),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(t){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=t.opacity&&"string"!=typeof e.style.opacity&&void 0!==e.filters&&(t.filter="alpha(opacity="+Math.round(100*t.opacity)+")"),qq.extend(e.style,t),this},hasClass:function(t,n){var i=new RegExp("(^| )"+t+"( |$)");return i.test(e.className)||!(!n||!i.test(e.parentNode.className))},addClass:function(t){return qq(e).hasClass(t)||(e.className+=" "+t),this},removeClass:function(t){var n=new RegExp("(^| )"+t+"( |$)");return e.className=e.className.replace(n," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(t,n){var i,o=[];return n&&e.querySelector?e.querySelector("."+t):e.querySelectorAll?e.querySelectorAll("."+t):(i=e.getElementsByTagName("*"),qq.each(i,function(e,n){qq(n).hasClass(t)&&o.push(n)}),n?o[0]:o)},getFirstByClass:function(t){return qq(e).getByClass(t,!0)},children:function(){for(var t=[],n=e.firstChild;n;)1===n.nodeType&&t.push(n),n=n.nextSibling;return t},setText:function(t){return e.innerText=t,e.textContent=t,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(t){var n;return e.hasAttribute?!!e.hasAttribute(t)&&null==/^false$/i.exec(e.getAttribute(t)):(n=e[t],void 0!==n&&null==/^false$/i.exec(n))}}};!function(){"use strict";qq.canvasToBlob=function(e,t,n){return qq.dataUriToBlob(e.toDataURL(t,n))},qq.dataUriToBlob=function(e){var t,n,i,o,r=function(e,t){var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})};return n=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],t=new ArrayBuffer(n.length),i=new Uint8Array(t),qq.each(n,function(e,t){i[e]=t.charCodeAt(0)}),r(t,o)},qq.log=function(e,t){window.console&&(t&&"info"!==t?window.console[t]?window.console[t](e):window.console.log("<"+t+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var t=Array.prototype.slice.call(arguments,1),n=e,i=n.indexOf("{}");return qq.each(t,function(e,t){if(n=n.substring(0,i)+t+n.substring(i+2),i=n.indexOf("{}",i+t.length),i<0)return!1}),n},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,t){var n=function(e){var n=e.toLowerCase();return t?"file"!==n:"file"===n};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&n(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&n(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&void 0!==qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.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(e,t,n){return(e.slice||e.mozSlice||e.webkitSlice).call(e,t,n)},qq.arrayBufferToHex=function(e){var t="",n=new Uint8Array(e);return qq.each(n,function(e,n){var i=n.toString(16);i.length<2&&(i="0"+i),t+=i}),t},qq.readBlobToHex=function(e,t,n){var i=qq.sliceBlob(e,t,t+n),o=new FileReader,r=new qq.Promise;return o.onload=function(){r.success(qq.arrayBufferToHex(o.result))},o.onerror=r.failure,o.readAsArrayBuffer(i),r},qq.extend=function(e,t,n){return qq.each(t,function(t,i){n&&qq.isObject(i)?(void 0===e[t]&&(e[t]={}),qq.extend(e[t],i,!0)):e[t]=i}),e},qq.override=function(e,t){var n={},i=t(n);return qq.each(i,function(t,i){void 0!==e[t]&&(n[t]=e[t]),e[t]=i}),e},qq.indexOf=function(e,t,n){if(e.indexOf)return e.indexOf(t,n);n=n||0;var i=e.length;for(n<0&&(n+=i);n=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(t){e.innerHTML=t;var n=e.firstChild;return e.removeChild(n),n}}(),qq.each=function(e,t){var n,i;if(e)if(window.Storage&&e.constructor===window.Storage)for(n=0;n0)return e.substr(t,e.length-t)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var t;do t=e.shift(),t&&t();while(t)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(t){e.push(t)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),function(){"use strict";qq.Error=function(e){this.message="[Fine Uploader "+qq.version+"] "+e},qq.Error.prototype=new Error}(),qq.version="5.16.2",qq.supportedFeatures=function(){"use strict";function e(){var e,t=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(t=!1)}catch(e){t=!1}return t}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function n(){if(window.XMLHttpRequest){return void 0!==qq.createXhrInstance().withCredentials}return!1}function i(){return void 0!==window.XDomainRequest}function o(){return!!n()||i()}function r(){return void 0!==document.createElement("input").webkitdirectory}function a(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function s(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var u,l,c,d,p,h,f,q,m,g,_,v,b,y,S;return u=e(),d=u&&qq.isXhrUploadSupported(),l=d&&!qq.androidStock(),c=d&&s(),p=c&&function(){var e=document.createElement("input");return e.type="file",!!("webkitdirectory"in(e||document.querySelectorAll("input[type=file]")[0]))}(),h=d&&qq.isFileChunkingSupported(),f=d&&h&&a(),q=d&&t(),m=u&&(void 0!==window.postMessage||d),_=n(),g=i(),v=o(),b=r(),y=d&&void 0!==window.FileReader,S=function(){return!!d&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:d,blobUploading:l,canDetermineSize:d,chunking:h,deleteFileCors:v,deleteFileCorsXdr:g,deleteFileCorsXhr:_,dialogElement:!!window.HTMLDialogElement,fileDrop:c,folderDrop:p,folderSelection:b,imagePreviews:y,imageValidation:y,itemSizeValidation:d,pause:h,progressBar:S,resume:f,scaling:y&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:u,uploadCors:m,uploadCustomHeaders:d,uploadNonMultipart:d,uploadViaPaste:q}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,t,n=[],i=[],o=[],r=0;qq.extend(this,{then:function(o,a){return 0===r?(o&&n.push(o),a&&i.push(a)):r===-1?a&&a.apply(null,t):o&&o.apply(null,e),this},done:function(n){return 0===r?o.push(n):n.apply(null,void 0===t?e:t),this},success:function(){return r=1,e=arguments,n.length&&qq.each(n,function(t,n){n.apply(null,e)}),o.length&&qq.each(o,function(t,n){n.apply(null,e)}),this},failure:function(){return r=-1,t=arguments,i.length&&qq.each(i,function(e,n){n.apply(null,t)}),o.length&&qq.each(o,function(e,n){n.apply(null,t)}),this}})},qq.BlobProxy=function(e,t){"use strict";qq.extend(this,{referenceBlob:e,create:function(){return t(e)}})},qq.UploadButton=function(e){"use strict";function t(){var e=document.createElement("input");return e.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,i),e.setAttribute("title",a.title),o.setMultiple(a.multiple,e),a.folders&&qq.supportedFeatures.folderSelection&&e.setAttribute("webkitdirectory",""),a.acceptFiles&&e.setAttribute("accept",a.acceptFiles),e.setAttribute("type","file"),e.setAttribute("name",a.name),qq(e).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(e).css({height:"100%"}),a.element.appendChild(e),r.attach(e,"change",function(){a.onChange(e)}),r.attach(e,"mouseover",function(){qq(a.element).addClass(a.hoverClass)}),r.attach(e,"mouseout",function(){qq(a.element).removeClass(a.hoverClass)}),r.attach(e,"focus",function(){qq(a.element).addClass(a.focusClass)}),r.attach(e,"blur",function(){qq(a.element).removeClass(a.focusClass)}),e}var n,i,o=this,r=new qq.DisposeSupport,a={acceptFiles:null,element:null,focusClass:"qq-upload-button-focus",folders:!1,hoverClass:"qq-upload-button-hover",ios8BrowserCrashWorkaround:!1,multiple:!1,name:"qqfile",onChange:function(e){},title:null};qq.extend(a,e),i=qq.getUniqueId(),qq(a.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return n},getButtonId:function(){return i},setMultiple:function(e,t){var n=t||this.getInput();a.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?n.setAttribute("multiple",""):e?n.setAttribute("multiple",""):n.removeAttribute("multiple")},setAcceptFiles:function(e){e!==a.acceptFiles&&n.setAttribute("accept",e)},reset:function(){n.parentNode&&qq(n).remove(),qq(a.element).removeClass(a.focusClass),n=null,n=t()}}),n=t()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(e){"use strict";function t(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[n])}),t}return o[e]}function n(e){if(qq.isArray(e)){var t=[];return qq.each(e,function(e,n){t.push(o[r[n]])}),t}return o[r[e]]}function i(e){var t=[],n=[].concat(e);return qq.each(n,function(e,n){var i=a[n];void 0!==i&&qq.each(i,function(e,n){t.push(o[n])})}),t}var o=[],r={},a={},s={},u={};qq.extend(this,{addFile:function(t){var n=t.status||qq.status.SUBMITTING,i=o.push({name:t.name,originalName:t.name,uuid:t.uuid,size:null==t.size?-1:t.size,status:n,file:t.file})-1;return t.batchId&&(o[i].batchId=t.batchId,void 0===u[t.batchId]&&(u[t.batchId]=[]),u[t.batchId].push(i)),t.proxyGroupId&&(o[i].proxyGroupId=t.proxyGroupId,void 0===s[t.proxyGroupId]&&(s[t.proxyGroupId]=[]),s[t.proxyGroupId].push(i)),o[i].id=i,r[t.uuid]=i,void 0===a[n]&&(a[n]=[]),a[n].push(i),t.onBeforeStatusChange&&t.onBeforeStatusChange(i),e.onStatusChange(i,null,n),i},retrieve:function(e){return qq.isObject(e)&&o.length?void 0!==e.id?t(e.id):void 0!==e.uuid?n(e.uuid):e.status?i(e.status):void 0:qq.extend([],o,!0)},removeFileRef:function(e){var n=t(e);n&&delete n.file},reset:function(){o=[],r={},a={},u={}},setStatus:function(t,n){var i=o[t].status,r=qq.indexOf(a[i],t);a[i].splice(r,1),o[t].status=n,void 0===a[n]&&(a[n]=[]),a[n].push(t),e.onStatusChange(t,i,n)},uuidChanged:function(e,t){var n=o[e].uuid;o[e].uuid=t,r[t]=e,delete r[n]},updateName:function(e,t){o[e].name=t},updateSize:function(e,t){o[e].size=t},setParentId:function(e,t){o[e].parentId=t},getIdsInProxyGroup:function(e){var t=o[e].proxyGroupId;return t?s[t]:[]},getIdsInBatch:function(e){return u[o[e].batchId]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_FINALIZING:"upload finalizing",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(e,t,n){this.addFiles(e,t,n)},addInitialFiles:function(e){var t=this;qq.each(e,function(e,n){t._addCannedFile(n)})},addFiles:function(e,t,n){this._maybeHandleIos8SafariWorkaround();var i=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,o=qq.bind(function(e){this._handleNewFile({blob:e,name:this._options.blobs.defaultName},i,d)},this),r=qq.bind(function(e){this._handleNewFile(e,i,d)},this),a=qq.bind(function(e){var t=qq.canvasToBlob(e);this._handleNewFile({blob:t,name:this._options.blobs.defaultName+".png"},i,d)},this),s=qq.bind(function(e){var t=e.quality&&e.quality/100,n=qq.canvasToBlob(e.canvas,e.type,t);this._handleNewFile({blob:n,name:e.name},i,d)},this),u=qq.bind(function(e){if(qq.isInput(e)&&qq.supportedFeatures.ajaxUploading){var t=Array.prototype.slice.call(e.files),n=this;qq.each(t,function(e,t){n._handleNewFile(t,i,d)})}else this._handleNewFile(e,i,d)},this),l=function(){qq.isFileList(e)&&(e=Array.prototype.slice.call(e)),e=[].concat(e)},c=this,d=[];this._currentBatchId=i,e&&(l(),qq.each(e,function(e,t){qq.isFileOrInput(t)?u(t):qq.isBlob(t)?o(t):qq.isObject(t)?t.blob&&t.name?r(t):t.canvas&&t.name&&s(t):t.tagName&&"canvas"===t.tagName.toLowerCase()?a(t):c.log(t+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+d.length+" files."),this._prepareItemsForUpload(d,t,n))},cancel:function(e){var t=this._uploadData.retrieve({id:e});t&&t.status===qq.status.UPLOAD_FINALIZING?this.log(qq.format("Ignoring cancel for file ID {} ({}). Finalizing upload.",e,this.getName(e)),"error"):this._handler.cancel(e)},cancelAll:function(){var e=[],t=this;qq.extend(e,this._storedIds),qq.each(e,function(e,n){t.cancel(n)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(e){var t=this._uploadData.retrieve({id:e});return!(!qq.supportedFeatures.pause||!this._options.chunking.enabled)&&(t.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",e,this.getName(e))),this._uploadFile(e),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",e,this.getName(e)),"error"),!1))},deleteFile:function(e){return this._onSubmitDelete(e)},doesExist:function(e){return this._handler.isValid(e)},drawThumbnail:function(e,t,n,i,o){var r,a,s=new qq.Promise;return this._imageGenerator?(r=this._thumbnailUrls[e],a={customResizeFunction:o,maxSize:n>0?n:null,scale:n>0},!i&&qq.supportedFeatures.imagePreviews&&(r=this.getFile(e)),null==r?s.failure({container:t,error:"File or URL not found."}):this._imageGenerator.generate(r,t,a).then(function(e){s.success(e)},function(e,t){s.failure({container:e,error:t||"Problem generating thumbnail"})})):s.failure({container:t,error:"Missing image generator module"}),s},getButton:function(e){return this._getButton(this._buttonIdsForFileIds[e])},getEndpoint:function(e){return this._endpointStore.get(e)},getFile:function(e){var t,n=this._handler.getFile(e);return n||(t=this._uploadData.retrieve({id:e}),t&&(n=t.file)),n||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(e){return this._uploadData.retrieve({id:e}).name},getParentId:function(e){var t=this.getUploads({id:e}),n=null;return t&&void 0!==t.parentId&&(n=t.parentId),n},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(e){return this._uploadData.retrieve({id:e}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var e=this._currentItemLimit;return e>0?e-this._netUploadedOrQueued:null},getUploads:function(e){return this._uploadData.retrieve(e)},getUuid:function(e){return this._uploadData.retrieve({id:e}).uuid},isResumable:function(e){return this._handler.hasResumeRecord(e)},log:function(e,t){!this._options.debug||t&&"info"!==t?t&&"info"!==t&&qq.log("[Fine Uploader "+qq.version+"] "+e,t):qq.log("[Fine Uploader "+qq.version+"] "+e)},pauseUpload:function(e){var t=this._uploadData.retrieve({id:e});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],t.status)>=0){if(this._handler.pause(e))return this._uploadData.setStatus(e,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",e,this.getName(e)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",e,this.getName(e)),"error");return!1},removeFileRef:function(e){this._handler.expunge(e),this._uploadData.removeFileRef(e)},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(e,t){t.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(),this._customResumeDataStore.reset()},retry:function(e){return this._manualRetry(e)},scaleImage:function(e,t){var n=this;return qq.Scaler.prototype.scaleImage(e,t,{log:qq.bind(n.log,n),getFile:qq.bind(n.getFile,n),uploadData:n._uploadData})},setCustomHeaders:function(e,t){this._customHeadersStore.set(e,t)},setCustomResumeData:function(e,t){this._customResumeDataStore.set(t,e)},setDeleteFileCustomHeaders:function(e,t){this._deleteFileCustomHeadersStore.set(e,t)},setDeleteFileEndpoint:function(e,t){this._deleteFileEndpointStore.set(e,t)},setDeleteFileParams:function(e,t){this._deleteFileParamsStore.set(e,t)},setEndpoint:function(e,t){this._endpointStore.set(e,t)},setForm:function(e){this._updateFormSupportAndParams(e)},setItemLimit:function(e){this._currentItemLimit=e},setName:function(e,t){this._uploadData.updateName(e,t)},setParams:function(e,t){this._paramsStore.set(e,t)},setUuid:function(e,t){return this._uploadData.uuidChanged(e,t)},setStatus:function(e,t){if(!this.getUploads({id:e}))throw new qq.Error(e+" is not a valid file ID.");switch(t){case qq.status.DELETED:this._onDeleteComplete(e,null,!1);break;case qq.status.DELETE_FAILED:this._onDeleteComplete(e,null,!0);break;default:var n="Method setStatus called on '"+name+"' not implemented yet for "+t;throw this.log(n),new qq.Error(n)}},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(e){var t=this;return this._uploadData.addFile({uuid:e.uuid,name:e.name,size:e.size,status:qq.status.UPLOAD_SUCCESSFUL,onBeforeStatusChange:function(n){e.deleteFileEndpoint&&t.setDeleteFileEndpoint(e.deleteFileEndpoint,n),e.deleteFileParams&&t.setDeleteFileParams(e.deleteFileParams,n),e.thumbnailUrl&&(t._thumbnailUrls[n]=e.thumbnailUrl),t._netUploaded++,t._netUploadedOrQueued++}})},_annotateWithButtonId:function(e,t){qq.isFile(e)&&(e.qqButtonId=this._getButtonId(t))},_batchError:function(e){this._options.callbacks.onError(null,null,e,void 0)},_createDeleteHandler:function(){var e=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(e.log,e),onDelete:function(t){e._onDelete(t),e._options.callbacks.onDelete(t)},onDeleteComplete:function(t,n,i){e._onDeleteComplete(t,n,i),e._options.callbacks.onDeleteComplete(t,n,i)}})},_createPasteHandler:function(){var e=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(e.log,e),pasteReceived:function(t){e._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(e._options.callbacks.onPasteReceived,e,t),onSuccess:qq.bind(e._handlePasteSuccess,e,t),identifier:"pasted image"})}}})},_createStore:function(e,t){var n={},i=e,o={},r=t,a=function(e){return qq.isObject(e)?qq.extend({},e):e},s=function(){return qq.isFunction(r)?r():r},u=function(e,t){r&&qq.isObject(t)&&qq.extend(t,s()),o[e]&&qq.extend(t,o[e])};return{set:function(e,t){null==t?(n={},i=a(e)):n[t]=a(e)},get:function(e){var t;return t=null!=e&&n[e]?n[e]:a(i),u(e,t),a(t)},addReadOnly:function(e,t){qq.isObject(n)&&(null===e?qq.isFunction(t)?r=t:(r=r||{},qq.extend(r,t)):(o[e]=o[e]||{},qq.extend(o[e],t)))},remove:function(e){return delete n[e]},reset:function(){n={},o={},i=e}}},_createUploadDataTracker:function(){var e=this;return new qq.UploadData({getName:function(t){return e.getName(t)},getUuid:function(t){return e.getUuid(t)},getSize:function(t){return e.getSize(t)},onStatusChange:function(t,n,i){e._onUploadStatusChange(t,n,i),e._options.callbacks.onStatusChange(t,n,i),e._maybeAllComplete(t,i),e._totalProgress&&setTimeout(function(){e._totalProgress.onStatusChange(t,n,i)},0)}})},_createUploadButton:function(e){function t(){return!!qq.supportedFeatures.ajaxUploading&&(!(i._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&i._isAllowedExtension(r,".mov"))&&(void 0===e.multiple?i._options.multiple:e.multiple))}var n,i=this,o=e.accept||this._options.validation.acceptFiles,r=e.allowedExtensions||this._options.validation.allowedExtensions;return n=new qq.UploadButton({acceptFiles:o,element:e.element,focusClass:this._options.classes.buttonFocus,folders:e.folders,hoverClass:this._options.classes.buttonHover,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash,multiple:t(),name:this._options.request.inputName,onChange:function(e){i._onInputChange(e)},title:null==e.title?this._options.text.fileInputTitle:e.title}),this._disposeSupport.addDisposer(function(){n.dispose()}),i._buttons.push(n),n},_createUploadHandler:function(e,t){var n=this,i={},o={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(n.log,n),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(e,t,o,r){o<0||r<0||(i[e]?i[e].loaded===o&&i[e].total===r||(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)):(n._onProgress(e,t,o,r),n._options.callbacks.onProgress(e,t,o,r)),i[e]={loaded:o,total:r})},onComplete:function(e,t,o,r){delete i[e];var a,s=n.getUploads({id:e}).status;s!==qq.status.UPLOAD_SUCCESSFUL&&s!==qq.status.UPLOAD_FAILED&&(a=n._onComplete(e,t,o,r),a instanceof qq.Promise?a.done(function(){n._options.callbacks.onComplete(e,t,o,r)}):n._options.callbacks.onComplete(e,t,o,r))},onCancel:function(e,t,i){var o=new qq.Promise;return n._handleCheckedCallback({name:"onCancel",callback:qq.bind(n._options.callbacks.onCancel,n,e,t),onFailure:o.failure,onSuccess:function(){i.then(function(){n._onCancel(e,t)}),o.success()},identifier:e}),o},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(e,t){n._onUpload(e,t);var i=n._options.callbacks.onUpload(e,t);return qq.isGenericPromise(i)?(n.log(qq.format("onUpload for {} returned a Promise - waiting for resolution.",e)),i):(new qq.Promise).success()},onUploadChunk:function(e,t,i){n._onUploadChunk(e,i);var o=n._options.callbacks.onUploadChunk(e,t,i) +;return qq.isGenericPromise(o)?(n.log(qq.format("onUploadChunk for {}.{} returned a Promise - waiting for resolution.",e,i.partIndex)),o):(new qq.Promise).success()},onUploadChunkSuccess:function(e,t,i,o){n._onUploadChunkSuccess(e,t),n._options.callbacks.onUploadChunkSuccess.apply(n,arguments)},onResume:function(e,t,i,o){return n._options.callbacks.onResume(e,t,i,o)},onAutoRetry:function(e,t,i,o){return n._onAutoRetry.apply(n,arguments)},onUuidChanged:function(e,t){n.log("Server requested UUID change from '"+n.getUuid(e)+"' to '"+t+"'"),n.setUuid(e,t)},getName:qq.bind(n.getName,n),getUuid:qq.bind(n.getUuid,n),getSize:qq.bind(n.getSize,n),setSize:qq.bind(n._setSize,n),getDataByUuid:function(e){return n.getUploads({uuid:e})},isQueued:function(e){var t=n.getUploads({id:e}).status;return t===qq.status.QUEUED||t===qq.status.SUBMITTED||t===qq.status.UPLOAD_RETRYING||t===qq.status.PAUSED},getIdsInProxyGroup:n._uploadData.getIdsInProxyGroup,getIdsInBatch:n._uploadData.getIdsInBatch,isInProgress:function(e){return n.getUploads({id:e}).status===qq.status.UPLOADING},getCustomResumeData:qq.bind(n._getCustomResumeData,n),setStatus:function(e,t){n._uploadData.setStatus(e,t)}};return qq.each(this._options.request,function(e,t){o[e]=t}),o.customHeaders=this._customHeadersStore,e&&qq.each(e,function(e,t){o[e]=t}),new qq.UploadHandlerController(o,t)},_fileOrBlobRejected:function(e){this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.REJECTED)},_formatSize:function(e){if(0===e)return e+this._options.text.sizeSymbols[0];var t=-1;do e/=1e3,t++;while(e>999);return Math.max(e,.1).toFixed(1)+this._options.text.sizeSymbols[t]},_generateExtraButtonSpecs:function(){var e=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(t,n){var i=n.multiple,o=qq.extend({},e._options.validation,!0),r=qq.extend({},n);void 0===i&&(i=e._options.multiple),r.validation&&qq.extend(o,n.validation,!0),qq.extend(r,{multiple:i,validation:o},!0),e._initExtraButton(r)})},_getButton:function(e){var t=this._extraButtonSpecs[e];return t?t.element:e===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(e){var t,n,i=e;if(i instanceof qq.BlobProxy&&(i=i.referenceBlob),i&&!qq.isBlob(i)){if(qq.isFile(i))return i.qqButtonId;if("input"===i.tagName.toLowerCase()&&"file"===i.type.toLowerCase())return i.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(t=i.getElementsByTagName("input"),qq.each(t,function(e,t){if("file"===t.getAttribute("type"))return n=t,!1}),n)return n.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getCustomResumeData:function(e){return this._customResumeDataStore.get(e)},_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(e){var t=this._extraButtonSpecs[e];return t?t.validation:this._options.validation},_getValidationDescriptor:function(e){return e.file instanceof qq.BlobProxy?{name:qq.getFilename(e.file.referenceBlob),size:e.file.referenceBlob.size}:{name:this.getUploads({id:e.id}).name,size:this.getUploads({id:e.id}).size}},_getValidationDescriptors:function(e){var t=this,n=[];return qq.each(e,function(e,i){n.push(t._getValidationDescriptor(i))}),n},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var e=this._options.camera.button,t=e?this._getButtonId(e):this._defaultButtonId,n=this._options;t&&t!==this._defaultButtonId&&(n=this._extraButtonSpecs[t]),n.multiple=!1,null===n.validation.acceptFiles?n.validation.acceptFiles="image/*;capture=camera":n.validation.acceptFiles+=",image/*;capture=camera",qq.each(this._buttons,function(e,i){if(i.getButtonId()===t)return i.setMultiple(n.multiple),i.setAcceptFiles(n.acceptFiles),!1})}},_handleCheckedCallback:function(e){var t=this,n=e.callback();return qq.isGenericPromise(n)?(this.log(e.name+" - waiting for "+e.name+" promise to be fulfilled for "+e.identifier),n.then(function(n){t.log(e.name+" promise success for "+e.identifier),e.onSuccess(n)},function(){e.onFailure?(t.log(e.name+" promise failure for "+e.identifier),e.onFailure()):t.log(e.name+" promise failure for "+e.identifier)})):(n!==!1?e.onSuccess(n):e.onFailure?(this.log(e.name+" - return value was 'false' for "+e.identifier+". Invoking failure callback."),e.onFailure()):this.log(e.name+" - return value was 'false' for "+e.identifier+". Will not proceed."),n)},_handleNewFile:function(e,t,n){var i=this,o=qq.getUniqueId(),r=-1,a=qq.getFilename(e),s=e.blob||e,u=this._customNewFileHandler?this._customNewFileHandler:qq.bind(i._handleNewFileGeneric,i);!qq.isInput(s)&&s.size>=0&&(r=s.size),u(s,a,o,r,n,t,this._options.request.uuidName,{uploadData:i._uploadData,paramsStore:i._paramsStore,addFileToHandler:function(e,t){i._handler.add(e,t),i._netUploadedOrQueued++,i._trackButton(e)}})},_handleNewFileGeneric:function(e,t,n,i,o,r){var a=this._uploadData.addFile({uuid:n,name:t,size:i,batchId:r,file:e});this._handler.add(a,e),this._trackButton(a),this._netUploadedOrQueued++,o.push({id:a,file:e})},_handlePasteSuccess:function(e,t){var n=e.type.split("/")[1],i=t;null==i&&(i=this._options.paste.defaultName),i+="."+n,this.addFiles({name:i,blob:e})},_handleDeleteSuccess:function(e){if(this.getUploads({id:e}).status!==qq.status.DELETED){var t=this.getName(e);this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(e),this._uploadData.setStatus(e,qq.status.DELETED),this.log("Delete request for '"+t+"' has succeeded.")}},_handleDeleteFailed:function(e,t){var n=this.getName(e);this._uploadData.setStatus(e,qq.status.DELETE_FAILED),this.log("Delete request for '"+n+"' has failed.","error"),t&&void 0!==t.withCredentials?this._options.callbacks.onError(e,n,"Delete request failed with response code "+t.status,t):this._options.callbacks.onError(e,n,"Delete request failed",t)},_initExtraButton:function(e){var t=this._createUploadButton({accept:e.validation.acceptFiles,allowedExtensions:e.validation.allowedExtensions,element:e.element,folders:e.folders,multiple:e.multiple,title:e.fileInputTitle});this._extraButtonSpecs[t.getButtonId()]=e},_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||!(!qq.supportedFeatures.deleteFileCorsXdr||!this._options.cors.allowXdr)))},_isAllowedExtension:function(e,t){var n=!1;return!e.length||(qq.each(e,function(e,i){if(qq.isString(i)){var o=new RegExp("\\."+i+"$","i");if(null!=t.match(o))return n=!0,!1}}),n)},_itemError:function(e,t,n){function i(e,t){a=a.replace(e,t)}var o,r,a=this._options.messages[e],s=[],u=[].concat(t),l=u[0],c=this._getButtonId(n),d=this._getValidationBase(c);return qq.each(d.allowedExtensions,function(e,t){qq.isString(t)&&s.push(t)}),o=s.join(", ").toLowerCase(),i("{file}",this._options.formatFileName(l)),i("{extensions}",o),i("{sizeLimit}",this._formatSize(d.sizeLimit)),i("{minSizeLimit}",this._formatSize(d.minSizeLimit)),r=a.match(/(\{\w+\})/g),null!==r&&qq.each(r,function(e,t){i(t,u[e])}),this._options.callbacks.onError(null,l,a,void 0),a},_manualRetry:function(e,t){if(this._onBeforeManualRetry(e))return this._netUploadedOrQueued++,this._uploadData.setStatus(e,qq.status.UPLOAD_RETRYING),t?t(e):this._handler.retry(e),!0},_maybeAllComplete:function(e,t){var n=this,i=this._getNotFinished();t===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(e):t===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(e),0===i&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){n._onAllComplete(n._succeededSinceLastAllComplete,n._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var e=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(e._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(e,t,n,i){if(!n.success)if(i&&200!==i.status&&!n.error)this._options.callbacks.onError(e,t,"XHR returned response code "+i.status,i);else{var o=n.error?n.error:this._options.text.defaultResponseError;this._options.callbacks.onError(e,t,o,i)}},_maybeProcessNextItemAfterOnValidateCallback:function(e,t,n,i,o){var r=this;if(t.length>n)if(e||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var e=r._getValidationDescriptor(t[n]),a=r._getButtonId(t[n].file),s=r._getButton(a);r._handleCheckedCallback({name:"onValidate",callback:qq.bind(r._options.callbacks.onValidate,r,e,s),onSuccess:qq.bind(r._onValidateCallbackSuccess,r,t,n,i,o),onFailure:qq.bind(r._onValidateCallbackFailure,r,t,n,i,o),identifier:"Item '"+e.name+"', size: "+e.size})},0);else if(!e)for(;n0&&this._netUploadedOrQueued+1>n?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+t+"' (id: "+e+")..."),!0))):(this.log("'"+e+"' is not a valid file ID","error"),!1)},_onCancel:function(e,t){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[e]);var n=qq.indexOf(this._storedIds,e);!this._options.autoUpload&&n>=0&&this._storedIds.splice(n,1),this._uploadData.setStatus(e,qq.status.CANCELED)},_onComplete:function(e,t,n,i){return n.success?(n.thumbnailUrl&&(this._thumbnailUrls[e]=n.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(e,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(e,qq.status.UPLOAD_FAILED),n[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[e]=!0)),this._maybeParseAndSendUploadError(e,t,n,i),!!n.success},_onDelete:function(e){this._uploadData.setStatus(e,qq.status.DELETING)},_onDeleteComplete:function(e,t,n){this.getName(e);n?this._handleDeleteFailed(e,t):this._handleDeleteSuccess(e)},_onInputChange:function(e){var t;if(qq.supportedFeatures.ajaxUploading){for(t=0;t0&&this.addFiles(e);qq.each(this._buttons,function(e,t){t.reset()})},_onProgress:function(e,t,n,i){this._totalProgress&&this._totalProgress.onIndividualProgress(e,n,i)},_onSubmit:function(e,t){},_onSubmitCallbackSuccess:function(e,t){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(e,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(e)):(this._storeForLater(e),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(e,t,n){var i,o=this.getUuid(e);return t&&(i=qq.bind(t,this,e,o,n)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,e),onSuccess:i||qq.bind(this._deleteHandler.sendDelete,this,e,o,n),identifier:e}),!0):(this.log("Delete request ignored for ID "+e+", 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(e){},_onTotalProgress:function(e,t){this._options.callbacks.onTotalProgress(e,t)},_onUploadPrep:function(e){},_onUpload:function(e,t){this._uploadData.setStatus(e,qq.status.UPLOADING)},_onUploadChunk:function(e,t){},_onUploadChunkSuccess:function(e,t){!this._preventRetries[e]&&this._options.retry.enableAuto&&(this._autoRetries[e]=0)},_onUploadStatusChange:function(e,t,n){n===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[e])},_onValidateBatchCallbackFailure:function(e){var t=this;qq.each(e,function(e,n){t._fileOrBlobRejected(n.id)})},_onValidateBatchCallbackSuccess:function(e,t,n,i,o){var r,a=this._currentItemLimit,s=this._netUploadedOrQueued;0===a||s<=a?t.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,e[0],o),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,t,0,n,i),onFailure:qq.bind(this._onValidateCallbackFailure,this,t,0,n,i),identifier:"Item '"+t[0].file.name+"', size: "+t[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(t),r=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,s).replace(/\{itemLimit\}/g,a),this._batchError(r))},_onValidateCallbackFailure:function(e,t,n,i){var o=t+1;this._fileOrBlobRejected(e[t].id,e[t].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,e,o,n,i)},_onValidateCallbackSuccess:function(e,t,n,i){var o=this,r=t+1,a=this._getValidationDescriptor(e[t]);this._validateFileOrBlobData(e[t],a).then(function(){o._upload(e[t].id,n,i),o._maybeProcessNextItemAfterOnValidateCallback(!0,e,r,n,i)},function(){o._maybeProcessNextItemAfterOnValidateCallback(!1,e,r,n,i)})},_prepareItemsForUpload:function(e,t,n){if(0===e.length)return void this._itemError("noFilesError");var i=this._getValidationDescriptors(e),o=this._getButtonId(e[0].file),r=this._getButton(o);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,i,r),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,i,e,t,n,r),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,e),identifier:"batch validation"})},_preventLeaveInProgress:function(){var e=this;this._disposeSupport.attach(window,"beforeunload",function(t){if(e.getInProgress())return t=t||window.event,t.returnValue=e._options.messages.onLeave,e._options.messages.onLeave})},_refreshSessionData:function(){var e=this,t=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(t,{cors:this._options.cors}),t.log=qq.bind(this.log,this),t.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(t)),setTimeout(function(){e._session.refresh().then(function(t,n){e._sessionRequestComplete(),e._options.callbacks.onSessionRequestComplete(t,!0,n)},function(t,n){e._options.callbacks.onSessionRequestComplete(t,!1,n)})},0))},_sessionRequestComplete:function(){},_setSize:function(e,t){this._uploadData.updateSize(e,t),this._totalProgress&&this._totalProgress.onNewSize(e)},_shouldAutoRetry:function(e){var t=this._uploadData.retrieve({id:e});return!!(!this._preventRetries[e]&&this._options.retry.enableAuto&&t.status!==qq.status.PAUSED&&(void 0===this._autoRetries[e]&&(this._autoRetries[e]=0),this._autoRetries[e]0&&s.sizeLimit&&r>s.sizeLimit?(this._itemError("sizeError",o,i),u.failure()):r>0&&r=0}function n(e){var t=!1;return qq.each(t,function(e,n){if(qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],n)<0)return t=!0,!1}),t}function i(e){return S.cors.expected&&void 0===e.withCredentials}function o(){var e;return(window.XMLHttpRequest||window.ActiveXObject)&&(e=qq.createXhrInstance(),void 0===e.withCredentials&&(e=new XDomainRequest,e.onload=function(){},e.onerror=function(){},e.ontimeout=function(){},e.onprogress=function(){})),e}function r(e,t){var n=y[e]&&y[e].xhr;return n||(n=t?t:S.cors.expected?o():qq.createXhrInstance(),y[e].xhr=n),n}function a(e){var t,n=qq.indexOf(b,e),i=S.maxConnections;delete y[e],b.splice(n,1),b.length>=i&&n=0?o.send(qq.obj2url(s,"")):s&&S.contentType&&S.contentType.toLowerCase().indexOf("application/json")>=0?o.send(JSON.stringify(s)):o.send(s),o}function c(e,t,n){var i=S.endpointStore.get(e),o=y[e].addToPath;return void 0!=o&&(i+="/"+o),v&&t&&(i=qq.obj2url(t,i)),n&&(i=qq.obj2url(n,i)),i}function d(e){return function(){4===r(e).readyState&&s(e)}}function p(e){var t=S.onProgress;t&&(r(e).upload.onprogress=function(n){n.lengthComputable&&t(e,n.loaded,n.total)})}function h(e){return function(){s(e)}}function f(e){return function(){s(e,!0)}}function q(e){var o=r(e),a=S.customHeaders,s=y[e].additionalHeaders||{},u=S.method,l={};i(o)||(S.acceptHeader&&o.setRequestHeader("Accept",S.acceptHeader),S.allowXRequestedWithAndCacheControl&&(S.cors.expected&&t()&&!n(a)||(o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Cache-Control","no-cache"))),!S.contentType||"POST"!==u&&"PUT"!==u||o.setRequestHeader("Content-Type",S.contentType),qq.extend(l,qq.isFunction(a)?a(e):a),qq.extend(l,s),qq.each(l,function(e,t){o.setRequestHeader(e,t)}))}function m(e){return qq.indexOf(S.successfulResponseCodes[S.method],e)>=0}function g(e,t,n,i,o,r,a){if(y[e]={addToPath:n,additionalParams:i,additionalQueryParams:o,additionalHeaders:r,payload:a},b.push(e)<=S.maxConnections)return l(e,t)}var _,v,b=[],y={},S={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(e,t){},onSend:function(e){},onComplete:function(e,t,n){},onProgress:null};if(qq.extend(S,e),_=S.log,qq.indexOf(S.validMethods,S.method)<0)throw new Error("'"+S.method+"' is not a supported method for this type of request!");v="GET"===S.method||"DELETE"===S.method,qq.extend(this,{initTransport:function(e){var t,n,i,o,r,a;return{withPath:function(e){return t=e,this},withParams:function(e){return n=e,this},withQueryParams:function(e){return a=e,this},withHeaders:function(e){return i=e,this},withPayload:function(e){return o=e,this},withCacheBuster:function(){return r=!0,this},send:function(s){return r&&qq.indexOf(["GET","DELETE"],S.method)>=0&&(n.qqtimestamp=(new Date).getTime()),g(e,s,t,n,a,i,o)}}},canceled:function(e){a(e)}})},qq.UploadHandler=function(e){"use strict";var t=e.proxy,n={},i=t.onCancel,o=t.getName;qq.extend(this,{add:function(e,t){n[e]=t,n[e].temp={}},cancel:function(e){var t=this,r=new qq.Promise;i(e,o(e),r).then(function(){t.isValid(e)&&(n[e].canceled=!0,t.expunge(e)),r.success()})},expunge:function(e){delete n[e]},getThirdPartyFileId:function(e){return n[e].key},isValid:function(e){return void 0!==n[e]},reset:function(){n={}},_getFileState:function(e){return n[e]},_setThirdPartyFileId:function(e,t){n[e].key=t},_wasCanceled:function(e){return!!n[e].canceled}})},qq.UploadHandlerController=function(e,t){"use strict";var n,i,o,r=this,a=!1,s=!1,u={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(e,t){},onProgress:function(e,t,n,i){},onComplete:function(e,t,n,i){},onCancel:function(e,t){},onUploadPrep:function(e){},onUpload:function(e,t){},onUploadChunk:function(e,t,n){},onUploadChunkSuccess:function(e,t,n,i){},onAutoRetry:function(e,t,n,i){},onResume:function(e,t,n,i){},onUuidChanged:function(e,t){},getName:function(e){},setSize:function(e,t){},isQueued:function(e){},getIdsInProxyGroup:function(e){},getIdsInBatch:function(e){},isInProgress:function(e){}},l={done:function(e,t,n,i){var r=o._getChunkData(e,t);o._getFileState(e).attemptingResume=!1,delete o._getFileState(e).temp.chunkProgress[t],o._getFileState(e).loaded+=r.size,u.onUploadChunkSuccess(e,o._getChunkDataForCallback(r),n,i)},finalize:function(e){var t=u.getSize(e),n=u.getName(e);i("All chunks have been uploaded for "+e+" - finalizing...."),o.finalizeChunks(e).then(function(r,a){i("Finalize successful for "+e);var s=p.normalizeResponse(r,!0);u.onProgress(e,n,t,t),o._maybeDeletePersistedChunkData(e),p.cleanup(e,s,a)},function(t,o){var r=p.normalizeResponse(t,!1);i("Problem finalizing chunks for file ID "+e+" - "+r.error,"error"),(r.reset||o&&u.chunking.success.resetOnStatus.indexOf(o.status)>=0)&&l.reset(e),u.onAutoRetry(e,n,r,o)||p.cleanup(e,r,o)})},handleFailure:function(e,t,n,r){var a=u.getName(t);i("Chunked upload request failed for "+t+", chunk "+e),o.clearCachedChunk(t,e);var d,h=p.normalizeResponse(n,!1);if(h.reset)l.reset(t);else{var f=o._getFileState(t).chunking.inProgress;d=f?qq.indexOf(f,e):-1,d>=0&&(o._getFileState(t).chunking.inProgress.splice(d,1),o._getFileState(t).chunking.remaining.unshift(e))}o._getFileState(t).temp.ignoreFailure||(s&&(o._getFileState(t).temp.ignoreFailure=!0,i(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.",JSON.stringify(Object.keys(o._getXhrs(t))),JSON.stringify(o._getFileState(t).chunking.inProgress))),qq.each(o._getXhrs(t),function(e,n){i(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ",t,e,n.readyState)),n.abort(),n._cancelled=!0}),o.moveInProgressToRemaining(t),c.free(t,!0)),u.onAutoRetry(t,a,h,r)||p.cleanup(t,h,r))},hasMoreParts:function(e){return!!o._getFileState(e).chunking.remaining.length},nextPart:function(e){var t=o._getFileState(e).chunking.remaining.shift();return t>=o._getTotalChunks(e)&&(t=null),t},reset:function(e){ +i("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+e,"error"),o._maybeDeletePersistedChunkData(e),o.reevaluateChunking(e),o._getFileState(e).loaded=0,o._getFileState(e).attemptingResume=!1},sendNext:function(e){var t=u.getSize(e),n=u.getName(e),r=l.nextPart(e),a=o._getChunkData(e,r),d=o._getFileState(e),h=d.attemptingResume,f=d.chunking.inProgress||[];if(null==d.loaded&&(d.loaded=0),h&&u.onResume(e,n,a,d.customResumeData)===!1&&(l.reset(e),r=l.nextPart(e),a=o._getChunkData(e,r),h=!1),null==r&&0===f.length)l.finalize(e);else{f.push(r),o._getFileState(e).chunking.inProgress=f,s&&c.open(e,r),s&&c.available()&&o._getFileState(e).chunking.remaining.length&&l.sendNext(e),0===a.blob.size&&(i(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.",r,e),"error"),l.handleFailure(r,e,"File is no longer available",null));u.onUploadChunk(e,n,o._getChunkDataForCallback(a)).then(function(n){if(u.isInProgress(e)){i(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.",e,r,a.start+1,a.end,t));var s={chunkIdx:r,id:e,overrides:n,resuming:h};o.uploadChunk(s).then(function(t,n){i("Chunked upload request succeeded for "+e+", chunk "+r),o.clearCachedChunk(e,r);var a=o._getFileState(e).chunking.inProgress||[],s=p.normalizeResponse(t,!0),u=qq.indexOf(a,r);i(qq.format("Chunk {} for file {} uploaded successfully.",r,e)),l.done(e,r,s,n),u>=0&&a.splice(u,1),o._maybePersistChunkedState(e),l.hasMoreParts(e)||0!==a.length?l.hasMoreParts(e)?l.sendNext(e):i(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}",e,JSON.stringify(a))):l.finalize(e)},function(t,n){l.handleFailure(r,e,t,n)}).done(function(){o.clearXhr(e,r)})}else i(qq.format("Not sending chunked upload request for item {}.{} - no longer in progress.",e,r))},function(t){l.handleFailure(r,e,t,null)})}}},c={_open:[],_openChunks:{},_waiting:[],available:function(){var e=u.maxConnections,t=0,n=0;return qq.each(c._openChunks,function(e,i){t++,n+=i.length}),e-(c._open.length-t+n)},free:function(e,t){var n,r=!t,a=qq.indexOf(c._waiting,e),s=qq.indexOf(c._open,e);delete c._openChunks[e],p.getProxyOrBlob(e)instanceof qq.BlobProxy&&(i("Generated blob upload has ended for "+e+", disposing generated blob."),delete o._getFileState(e).file),a>=0?c._waiting.splice(a,1):r&&s>=0&&(c._open.splice(s,1),n=c._waiting.shift(),n>=0&&(c._open.push(n),p.start(n)))},getWaitingOrConnected:function(){var e=[];return qq.each(c._openChunks,function(t,n){n&&n.length&&e.push(parseInt(t))}),qq.each(c._open,function(t,n){c._openChunks[n]||e.push(parseInt(n))}),e=e.concat(c._waiting)},isUsingConnection:function(e){return qq.indexOf(c._open,e)>=0},open:function(e,t){return null==t&&c._waiting.push(e),!!c.available()&&(null==t?(c._waiting.pop(),c._open.push(e)):function(){var n=c._openChunks[e]||[];n.push(t),c._openChunks[e]=n}(),!0)},reset:function(){c._waiting=[],c._open=[]}},d={send:function(e,t){var n=o._getFileState(e);if(!n)return void i("Ignoring send request as this upload may have been cancelled, File ID "+e,"warn");n.loaded=0,i("Sending simple upload request for "+e),o.uploadFile(e).then(function(n,o){i("Simple upload request succeeded for "+e);var r=p.normalizeResponse(n,!0),a=u.getSize(e);u.onProgress(e,t,a,a),p.maybeNewUuid(e,r),p.cleanup(e,r,o)},function(n,o){i("Simple upload request failed for "+e);var r=p.normalizeResponse(n,!1);u.onAutoRetry(e,t,r,o)||p.cleanup(e,r,o)})}},p={cancel:function(e){i("Cancelling "+e),u.paramsStore.remove(e),c.free(e)},cleanup:function(e,t,n){var i=u.getName(e);u.onComplete(e,i,t,n),o._getFileState(e)&&o._clearXhrs&&o._clearXhrs(e),c.free(e)},getProxyOrBlob:function(e){return o.getProxy&&o.getProxy(e)||o.getFile&&o.getFile(e)},initHandler:function(){o=new(t?qq[t]:qq.traditional)[(qq.supportedFeatures.ajaxUploading?"Xhr":"Form")+"UploadHandler"](u,{getCustomResumeData:u.getCustomResumeData,getDataByUuid:u.getDataByUuid,getName:u.getName,getSize:u.getSize,getUuid:u.getUuid,log:i,onCancel:u.onCancel,onProgress:u.onProgress,onUuidChanged:u.onUuidChanged,onFinalizing:function(e){u.setStatus(e,qq.status.UPLOAD_FINALIZING)}}),o._removeExpiredChunkingRecords&&o._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(e){return u.isQueued(e)},maybeDefer:function(e,t){return t&&!o.getFile(e)&&t instanceof qq.BlobProxy?(u.onUploadPrep(e),i("Attempting to generate a blob on-demand for "+e),t.create().then(function(t){i("Generated an on-demand blob for "+e),o.updateBlob(e,t),u.setSize(e,t.size),o.reevaluateChunking(e),p.maybeSendDeferredFiles(e)},function(t){var o={};t&&(o.error=t),i(qq.format("Failed to generate blob for ID {}. Error message: {}.",e,t),"error"),u.onComplete(e,u.getName(e),qq.extend(o,n),null),p.maybeSendDeferredFiles(e),c.free(e)}),!1):p.maybeSendDeferredFiles(e)},maybeSendDeferredFiles:function(e){var t=u.getIdsInProxyGroup(e),n=!1;return t&&t.length?(i("Maybe ready to upload proxy group file "+e),qq.each(t,function(t,i){if(p.isDeferredEligibleForUpload(i)&&o.getFile(i))n=i===e,p.now(i);else if(p.isDeferredEligibleForUpload(i))return!1})):(n=!0,p.now(e)),n},maybeNewUuid:function(e,t){void 0!==t.newUuid&&u.onUuidChanged(e,t.newUuid)},normalizeResponse:function(e,t){var n=e;return qq.isObject(e)||(n={},qq.isString(e)&&!t&&(n.error=e)),n.success=t,n},now:function(e){var t=u.getName(e);if(!r.isValid(e))throw new qq.Error(e+" is not a valid file ID to upload!");u.onUpload(e,t).then(function(n){n&&n.pause?(u.setStatus(e,qq.status.PAUSED),o.pause(e),c.free(e)):a&&o._shouldChunkThisFile(e)?l.sendNext(e):d.send(e,t)},function(n){if(n=n||{},i(e+" upload start aborted due to rejected onUpload Promise - details: "+n,"error"),!u.onAutoRetry(e,t,n.responseJSON||{})){var o=p.normalizeResponse(n.responseJSON,!1);p.cleanup(e,o)}})},start:function(e){var t=p.getProxyOrBlob(e);return t?p.maybeDefer(e,t):(p.now(e),!0)}};qq.extend(this,{add:function(e,t){o.add.apply(this,arguments)},upload:function(e){return!!c.open(e)&&p.start(e)},retry:function(e){return s&&(o._getFileState(e).temp.ignoreFailure=!1),c.isUsingConnection(e)?p.start(e):r.upload(e)},cancel:function(e){var t=o.cancel(e);qq.isGenericPromise(t)?t.then(function(){p.cancel(e)}):t!==!1&&p.cancel(e)},cancelAll:function(){var e,t=c.getWaitingOrConnected();if(t.length)for(e=t.length-1;e>=0;e--)r.cancel(t[e]);c.reset()},getFile:function(e){return o.getProxy&&o.getProxy(e)?o.getProxy(e).referenceBlob:o.getFile&&o.getFile(e)},isProxied:function(e){return!(!o.getProxy||!o.getProxy(e))},getInput:function(e){if(o.getInput)return o.getInput(e)},reset:function(){i("Resetting upload handler"),r.cancelAll(),c.reset(),o.reset()},expunge:function(e){if(r.isValid(e))return o.expunge(e)},isValid:function(e){return o.isValid(e)},hasResumeRecord:function(e){var t=o.isValid(e)&&o._getLocalStorageId&&o._getLocalStorageId(e);return!!t&&!!localStorage.getItem(t)},getResumableFilesData:function(){return o.getResumableFilesData?o.getResumableFilesData():[]},getThirdPartyFileId:function(e){if(r.isValid(e))return o.getThirdPartyFileId(e)},pause:function(e){return!!(r.isResumable(e)&&o.pause&&r.isValid(e)&&o.pause(e))&&(c.free(e),o.moveInProgressToRemaining(e),!0)},isAttemptingResume:function(e){return!!o.isAttemptingResume&&o.isAttemptingResume(e)},isResumable:function(e){return!!o.isResumable&&o.isResumable(e)}}),qq.extend(u,e),i=u.log,a=u.chunking.enabled&&qq.supportedFeatures.chunking,s=a&&u.chunking.concurrent.enabled,n=function(){var e={};return e[u.preventRetryParam]=!0,e}(),p.initHandler()},qq.WindowReceiveMessage=function(e){"use strict";var t={log:function(e,t){}},n={};qq.extend(t,e),qq.extend(this,{receiveMessage:function(e,t){var i=function(e){t(e.data)};window.postMessage?n[e]=qq(window).attach("message",i):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(e){if(window.postMessage){var t=n[e];t&&t()}}})},qq.FormUploadHandler=function(e){"use strict";function t(e){delete c[e],p&&(clearTimeout(d[e]),delete d[e],m.stopReceivingMessages(e));var t=document.getElementById(a._getIframeName(e));t&&(t.setAttribute("src","javascript:false;"),qq(t).remove())}function n(e){return e.split("_")[0]}function i(e){var t=qq.toElement("");return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t}function o(e,t){var i=e.id,o=n(i);l[f(o)]=t,c[o]=qq(e).attach("load",function(){a.getInput(o)&&(q("Received iframe load event for CORS upload request (iframe name "+i+")"),d[i]=setTimeout(function(){var e="No valid message received from loaded iframe for iframe name "+i;q(e,"error"),t({error:e})},1e3))}),m.receiveMessage(i,function(e){q("Received the following window message: '"+e+"'");var t,o=(n(i),a._parseJsonResponse(e)),r=o.uuid;r&&l[r]?(q("Handling response for iframe name "+i),clearTimeout(d[i]),delete d[i],a._detachLoadEvent(i),t=l[r],delete l[r],m.stopReceivingMessages(i),t(o)):r||q("'"+e+"' does not contain a UUID - ignoring.")})}var r=e.options,a=this,s=e.proxy,u=qq.getUniqueId(),l={},c={},d={},p=r.isCors,h=r.inputName,f=s.getUuid,q=s.log,m=new qq.WindowReceiveMessage({log:q});qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,n){e.add(t,{input:n}),n.setAttribute("name",h),n.parentNode&&qq(n).remove()},expunge:function(n){t(n),e.expunge(n)},isValid:function(t){return e.isValid(t)&&void 0!==a._getFileState(t).input}}}),qq.extend(this,{getInput:function(e){return a._getFileState(e).input},_attachLoadEvent:function(e,t){var n;p?o(e,t):c[e.id]=qq(e).attach("load",function(){if(q("Received response for "+e.id),e.parentNode){try{if(e.contentDocument&&e.contentDocument.body&&"false"==e.contentDocument.body.innerHTML)return}catch(e){q("Error when attempting to access iframe during handling of upload response ("+e.message+")","error"),n={success:!1}}t(n)}})},_createIframe:function(e){return i(a._getIframeName(e))},_detachLoadEvent:function(e){void 0!==c[e]&&(c[e](),delete c[e])},_getIframeName:function(e){return e+"_"+u},_initFormForUpload:function(e){var t=e.method,n=e.endpoint,i=e.params,o=e.paramsInBody,r=e.targetName,a=qq.toElement(""),s=n;return o?qq.obj2Inputs(i,a):s=qq.obj2url(i,n),a.setAttribute("action",s),a.setAttribute("target",r),a.style.display="none",document.body.appendChild(a),a},_parseJsonResponse:function(e){var t={};try{t=qq.parseJson(e)}catch(e){q("Error when attempting to parse iframe upload response ("+e.message+")","error")}return t}})},qq.XhrUploadHandler=function(e){"use strict";function t(e){qq.each(n._getXhrs(e),function(t,i){var o=n._getAjaxRequester(e,t);i.onreadystatechange=null,i.upload.onprogress=null,i.abort(),o&&o.canceled&&o.canceled(e)})}var n=this,i=e.options.namespace,o=e.proxy,r=e.options.chunking,a=function(e){var t=n._getFileState(e);if(t.chunkSize)return t.chunkSize;var i=r.partSize;return qq.isFunction(i)&&(i=i(e,d(e))),t.chunkSize=i,i},s=e.options.resume,u=r&&e.options.chunking.enabled&&qq.supportedFeatures.chunking,l=s&&e.options.resume.enabled&&u&&qq.supportedFeatures.resume,c=o.getName,d=o.getSize,p=o.getUuid,h=o.getEndpoint,f=o.getDataByUuid,q=o.onUuidChanged,m=o.onProgress,g=o.log,_=o.getCustomResumeData;qq.extend(this,new qq.UploadHandler(e)),qq.override(this,function(e){return{add:function(t,i){if(qq.isFile(i)||qq.isBlob(i))e.add(t,{file:i});else{if(!(i instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");e.add(t,{proxy:i})}n._initTempState(t),l&&n._maybePrepareForResume(t)},expunge:function(i){t(i),n._maybeDeletePersistedChunkData(i),n._clearXhrs(i),e.expunge(i)}}}),qq.extend(this,{clearCachedChunk:function(e,t){var i=n._getFileState(e);i&&delete i.temp.cachedChunks[t]},clearXhr:function(e,t){var i=n._getFileState(e).temp;i.xhrs&&delete i.xhrs[t],i.ajaxRequesters&&delete i.ajaxRequesters[t]},finalizeChunks:function(e,t){var i=n._getTotalChunks(e)-1,o=n._getXhr(e,i);return t?(new qq.Promise).success(t(o),o):(new qq.Promise).success({},o)},getFile:function(e){return n.isValid(e)&&n._getFileState(e).file},getProxy:function(e){return n.isValid(e)&&n._getFileState(e).proxy},getResumableFilesData:function(){var e=[];return n._iterateResumeRecords(function(t,i){n.moveInProgressToRemaining(null,i.chunking.inProgress,i.chunking.remaining);var o={name:i.name,remaining:i.chunking.remaining,size:i.size,uuid:i.uuid};i.key&&(o.key=i.key),i.customResumeData&&(o.customResumeData=i.customResumeData),e.push(o)}),e},isAttemptingResume:function(e){return n._getFileState(e).attemptingResume},isResumable:function(e){return!!r&&n.isValid(e)&&!n._getFileState(e).notResumable},moveInProgressToRemaining:function(e,t,i){var o=n._getFileState(e)||{},r=o.chunking||{},a=t||r.inProgress,s=i||r.remaining;a&&(g(qq.format("Moving these chunks from in-progress {}, to remaining.",JSON.stringify(a))),a.reverse(),qq.each(a,function(e,t){s.unshift(t)}),a.length=0)},pause:function(e){if(n.isValid(e))return g(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",e,c(e))),n._getFileState(e).paused=!0,t(e),!0},reevaluateChunking:function(e){if(r&&n.isValid(e)){var t,i,o=n._getFileState(e);if(delete o.chunking,o.chunking={},t=n._getTotalChunks(e),t>1||r.mandatory){for(o.chunking.enabled=!0,o.chunking.parts=t,o.chunking.remaining=[],i=0;i=o?o:s+i,l=n._getTotalChunks(e),c=this._getFileState(e).temp.cachedChunks,p=c[t]||qq.sliceBlob(r,s,u);return c[t]=p,{part:t,start:s,end:u,count:l,blob:p,size:u-s}},_getChunkDataForCallback:function(e){return{partIndex:e.part,startByte:e.start+1,endByte:e.end,totalParts:e.count}},_getLocalStorageId:function(e){var t=c(e),n=d(e),o=a(e),r=h(e),u=s.customKeys(e),l=qq.format("qq{}resume{}-{}-{}-{}-{}",i,"5.0",t,n,o,r);return u.forEach(function(e){l+="-"+e}),l},_getMimeType:function(e){return n.getFile(e).type},_getPersistableData:function(e){return n._getFileState(e).chunking},_getTotalChunks:function(e){if(r){var t=d(e),n=a(e);return Math.ceil(t/n)}},_getXhr:function(e,t){var i=null==t?-1:t;return n._getFileState(e).temp.xhrs[i]},_getXhrs:function(e){return n._getFileState(e).temp.xhrs},_iterateResumeRecords:function(e){l&&qq.each(localStorage,function(t,n){if(0===t.indexOf(qq.format("qq{}resume",i))){e(t,JSON.parse(n))}})},_initTempState:function(e){n._getFileState(e).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(e){n._getFileState(e).notResumable=!0},_maybeDeletePersistedChunkData:function(e){var t;return!!(l&&n.isResumable(e)&&(t=n._getLocalStorageId(e),t&&localStorage.getItem(t)))&&(localStorage.removeItem(t),!0)},_maybePrepareForResume:function(e){var t,i,o=n._getFileState(e);l&&void 0===o.key&&(t=n._getLocalStorageId(e),i=localStorage.getItem(t),i&&(i=JSON.parse(i),f(i.uuid)?n._markNotResumable(e):(g(qq.format("Identified file with ID {} and name of {} as resumable.",e,c(e))),q(e,i.uuid),o.key=i.key,o.chunking=i.chunking,o.loaded=i.loaded,o.customResumeData=i.customResumeData,o.attemptingResume=!0,n.moveInProgressToRemaining(e))))},_maybePersistChunkedState:function(e){var t,i,o=n._getFileState(e);if(l&&n.isResumable(e)){var r=_(e);t=n._getLocalStorageId(e),i={name:c(e),size:d(e),uuid:p(e),key:o.key,chunking:o.chunking,loaded:o.loaded,lastUpdated:Date.now()},r&&(i.customResumeData=r);try{localStorage.setItem(t,JSON.stringify(i))}catch(t){g(qq.format("Unable to save resume data for '{}' due to error: '{}'.",e,t.toString()),"warn")}}},_registerProgressHandler:function(e,t,i){var o=n._getXhr(e,t),r=c(e),a={simple:function(t,n){var i=d(e);t===n?m(e,r,i,i):m(e,r,t>=i?i-1:t,i)},chunked:function(o,a){var s=n._getFileState(e).temp.chunkProgress,u=n._getFileState(e).loaded,l=o,c=a,p=d(e),h=l-(c-i),f=u;s[t]=h,qq.each(s,function(e,t){f+=t}),m(e,r,f,p)}};o.upload.onprogress=function(e){if(e.lengthComputable){a[null==i?"simple":"chunked"](e.loaded,e.total)}}},_registerXhr:function(e,t,i,o){var r=null==t?-1:t,a=n._getFileState(e).temp;return a.xhrs=a.xhrs||{},a.ajaxRequesters=a.ajaxRequesters||{},a.xhrs[r]=i,o&&(a.ajaxRequesters[r]=o),i},_removeExpiredChunkingRecords:function(){var e=s.recordsExpireIn;n._iterateResumeRecords(function(t,n){var i=new Date(n.lastUpdated);i.setDate(i.getDate()+e),i.getTime()<=Date.now()&&(g("Removing expired resume record with key "+t),localStorage.removeItem(t))})},_shouldChunkThisFile:function(e){var t=n._getFileState(e);if(t)return t.chunking||n.reevaluateChunking(e),t.chunking.enabled}})},qq.DeleteFileAjaxRequester=function(e){"use strict";function t(){return"POST"===i.method.toUpperCase()?{_method:"DELETE"}:{}}var n,i={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(e){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(e,t){},onDelete:function(e){},onDeleteComplete:function(e,t,n){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:i.method,endpointStore:i.endpointStore,paramsStore:i.paramsStore,mandatedParams:t(),maxConnections:i.maxConnections,customHeaders:function(e){return i.customHeaders.get(e)},log:i.log,onSend:i.onDelete,onComplete:i.onDeleteComplete,cors:i.cors})),qq.extend(this,{sendDelete:function(e,t,o){var r=o||{};i.log("Submitting delete file request for "+e),"DELETE"===i.method?n.initTransport(e).withPath(t).withParams(r).send():(r[i.uuidParamName]=t,n.initTransport(e).withParams(r).send())}})},function(){function e(e){var t,n=e.naturalWidth,i=e.naturalHeight,o=document.createElement("canvas");return n*i>1048576&&(o.width=o.height=1,t=o.getContext("2d"),t.drawImage(e,-n+1,0),0===t.getImageData(0,0,1,1).data[3])}function t(e,t,n){var i,o,r,a,s=document.createElement("canvas"),u=0,l=n,c=n;for(s.width=1,s.height=n,i=s.getContext("2d"),i.drawImage(e,0,0),o=i.getImageData(0,0,1,n).data;c>u;)r=o[4*(c-1)+3],0===r?l=c:u=c,c=l+u>>1;return a=c/n,0===a?1:a}function n(e,t,n,i){var r=document.createElement("canvas"),a=n.mime||"image/jpeg",s=new qq.Promise;return o(e,t,r,n,i).then(function(){s.success(r.toDataURL(a,n.quality||.8))}),s}function i(e){if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");if(e.origHeight*e.origWidth>5241e3)return{newHeight:Math.round(Math.sqrt(5241e3*(e.origHeight/e.origWidth))),newWidth:Math.round(Math.sqrt(5241e3*(e.origWidth/e.origHeight)))}}function o(n,o,s,u,l){var c,d=n.naturalWidth,p=n.naturalHeight,h=u.width,f=u.height,q=s.getContext("2d"),m=new qq.Promise;return q.save(),u.resize?r({blob:o,canvas:s,image:n,imageHeight:p,imageWidth:d,orientation:u.orientation,resize:u.resize,targetHeight:f,targetWidth:h}):(qq.supportedFeatures.unlimitedScaledImageSize||(c=i({origWidth:h,origHeight:f}),c&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",h,f,c.newWidth,c.newHeight),"warn"),h=c.newWidth,f=c.newHeight)),a(s,h,f,u.orientation),qq.ios()?function(){e(n)&&(d/=2,p/=2);var i,o,r,a=1024,s=document.createElement("canvas"),u=l?t(n,d,p):1,c=Math.ceil(a*h/d),m=Math.ceil(a*f/p/u),g=0,_=0;for(s.width=s.height=a,i=s.getContext("2d");gc&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
c&&(u=c,l=s*u/a<<0),d&&l>d&&(l=d,u=a*l/s<<0),i={width:u,height:l},qq.each(t,function(e,t){i[e]=t}),"img"===h?function(){var t=e.src;n(r.srcImage,r.blob,i,p).then(function(n){e.src=n,t===e.src&&e.onload()})}():"canvas"===h&&o(this.srcImage,this.blob,e,i,p),"function"==typeof this.onrender&&this.onrender(e)},qq.MegaPixImage=s}(),qq.ImageGenerator=function(e){"use strict";function t(e){return"img"===e.tagName.toLowerCase()}function n(e){return"canvas"===e.tagName.toLowerCase()}function i(){return void 0!==(new Image).crossOrigin}function o(){var e=document.createElement("canvas");return e.getContext&&e.getContext("2d")}function r(e){var t=e.split("/"),n=t[t.length-1].split("?")[0],i=qq.getExtension(n);switch(i=i&&i.toLowerCase()){case"jpeg":case"jpg":return"image/jpeg";case"png":return"image/png";case"bmp":return"image/bmp";case"gif":return"image/gif";case"tiff":case"tif":return"image/tiff"}}function a(e){var t,n,i,o=document.createElement("a");return o.href=e,t=o.protocol,i=o.port,n=o.hostname,t.toLowerCase()!==window.location.protocol.toLowerCase()||(n.toLowerCase()!==window.location.hostname.toLowerCase()||i!==window.location.port&&!qq.ie())}function s(t,n){t.onload=function(){t.onload=null,t.onerror=null,n.success(t)},t.onerror=function(){t.onload=null,t.onerror=null,e("Problem drawing thumbnail!","error"),n.failure(t,"Problem drawing thumbnail!")}}function u(e,t){e.qqImageRendered=function(){t.success(e)}}function l(i,o){var r=t(i)||n(i);return t(i)?s(i,o):n(i)?u(i,o):(o.failure(i),e(qq.format("Element container of type {} is not supported!",i.tagName),"error")),r}function c(t,n,i){var o=new qq.Promise,r=new qq.Identify(t,e),a=i.maxSize,s=null==i.orient||i.orient,u=function(){n.onerror=null,n.onload=null,e("Could not render preview, file may be too large!","error"),o.failure(n,"Browser cannot render image!")};return r.isPreviewable().then(function(r){var c={parse:function(){return(new qq.Promise).success()}},d=s?new qq.Exif(t,e):c,p=new qq.MegaPixImage(t,u);l(n,o)&&d.parse().then(function(e){var t=e&&e.Orientation;p.render(n,{maxWidth:a,maxHeight:a,orientation:t,mime:r,resize:i.customResizeFunction})},function(t){e(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",t)),p.render(n,{maxWidth:a,maxHeight:a,mime:r,resize:i.customResizeFunction})})},function(){e("Not previewable"),o.failure(n,"Not previewable")}),o}function d(e,t,n,i,o){var s=new Image,u=new qq.Promise;l(s,u),a(e)&&(s.crossOrigin="anonymous"),s.src=e,u.then(function(){l(t,n),new qq.MegaPixImage(s).render(t,{maxWidth:i,maxHeight:i,mime:r(e),resize:o})},n.failure)}function p(e,t,n,i){l(t,n),qq(t).css({maxWidth:i+"px",maxHeight:i+"px"}),t.src=e}function h(e,r,s){var u=new qq.Promise,c=s.scale,h=c?s.maxSize:null;return c&&t(r)?o()?a(e)&&!i()?p(e,r,u,h):d(e,r,u,h):p(e,r,u,h):n(r)?d(e,r,u,h):l(r,u)&&(r.src=e),u}qq.extend(this,{generate:function(t,n,i){return qq.isString(t)?(e("Attempting to update thumbnail based on server response."),h(t,n,i||{})):(e("Attempting to draw client-side image preview."),c(t,n,i||{}))}}),this._testing={},this._testing.isImg=t,this._testing.isCanvas=n,this._testing.isCrossOrigin=a,this._testing.determineMimeOfFileName=r},qq.Exif=function(e,t){"use strict";function n(e){for(var t=0,n=0;e.length>0;)t+=parseInt(e.substring(0,2),16)*Math.pow(2,n),e=e.substring(2,e.length),n+=8;return t}function i(t,n){var o=t,r=n;return void 0===o&&(o=2,r=new qq.Promise),qq.readBlobToHex(e,o,4).then(function(e){var t,n=/^ffe([0-9])/.exec(e);n?"1"!==n[1]?(t=parseInt(e.slice(4,8),16),i(o+t+2,r)):r.success(o):r.failure("No EXIF header to be found!")}),r}function o(){var t=new qq.Promise;return qq.readBlobToHex(e,0,6).then(function(e){0!==e.indexOf("ffd8")?t.failure("Not a valid JPEG!"):i().then(function(e){t.success(e)},function(e){t.failure(e)})}),t}function r(t){var n=new qq.Promise;return qq.readBlobToHex(e,t+10,2).then(function(e){n.success("4949"===e)}),n}function a(t,i){var o=new qq.Promise;return qq.readBlobToHex(e,t+18,2).then(function(e){if(i)return o.success(n(e));o.success(parseInt(e,16))}),o}function s(t,n){var i=t+20,o=12*n;return qq.readBlobToHex(e,i,o)}function u(e){for(var t=[],n=0;n+24<=e.length;)t.push(e.slice(n,n+24)),n+=24;return t}function l(e,t){var i=qq.extend([],c),o={};return qq.each(t,function(t,r){var a,s,u,l=r.slice(0,4),c=e?n(l):parseInt(l,16),p=i.indexOf(c);if(p>=0&&(s=d[c].name,u=d[c].bytes,a=r.slice(16,16+2*u),o[s]=e?n(a):parseInt(a,16),i.splice(p,1)),0===i.length)return!1}),o}var c=[274],d={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var n=new qq.Promise,i=function(e){t(qq.format("EXIF header parse failed: '{}' ",e)),n.failure(e)};return o().then(function(o){t(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===e.name?"blob":e.name)),r(o).then(function(e){t(qq.format("EXIF Byte order is {} endian",e?"little":"big")),a(o,e).then(function(r){t(qq.format("Found {} APP1 directory entries",r)),s(o,r).then(function(i){var o=u(i),r=l(e,o);t("Successfully parsed some EXIF tags"),n.success(r)},i)},i)},i)},i),n}}),this._testing={},this._testing.parseLittleEndian=n},qq.Identify=function(e,t){"use strict";function n(e,t){var n=!1,i=[].concat(e);return qq.each(i,function(e,i){if(0===t.indexOf(i))return n=!0,!1}),n}qq.extend(this,{isPreviewable:function(){var i=this,o=new qq.Promise,r=!1,a=void 0===e.name?"blob":e.name;return t(qq.format("Attempting to determine if {} can be rendered in this browser",a)),t("First pass: check type attribute of blob object."),this.isPreviewableSync()?(t("Second pass: check for magic bytes in file header."),qq.readBlobToHex(e,0,4).then(function(e){qq.each(i.PREVIEWABLE_MIME_TYPES,function(t,i){if(n(i,e))return("image/tiff"!==t||qq.supportedFeatures.tiffPreviews)&&(r=!0,o.success(t)),!1}),t(qq.format("'{}' is {} able to be rendered in this browser",a,r?"":"NOT")),r||o.failure()},function(){t("Error reading file w/ name '"+a+"'. Not able to be rendered in this browser."),o.failure()})):o.failure(),o},isPreviewableSync:function(){var n=e.type,i=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),n)>=0,o=!1,r=void 0===e.name?"blob":e.name;return i&&(o="image/tiff"!==n||qq.supportedFeatures.tiffPreviews),!o&&t(r+" is not previewable in this browser per the blob's type attr"),o}})},qq.Identify.prototype.PREVIEWABLE_MIME_TYPES={"image/jpeg":"ffd8ff","image/gif":"474946","image/png":"89504e","image/bmp":"424d","image/tiff":["49492a00","4d4d002a"]},qq.ImageValidation=function(e,t){"use strict";function n(e){var t=!1;return qq.each(e,function(e,n){if(n>0)return t=!0,!1}),t}function i(){var n=new qq.Promise;return new qq.Identify(e,t).isPreviewable().then(function(){var i=new Image,o=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;o?(i.onerror=function(){t("Cannot determine dimensions for image. May be too large.","error"),n.failure()},i.onload=function(){n.success({width:this.width,height:this.height})},i.src=o.createObjectURL(e)):(t("No createObjectURL function available to generate image URL!","error"),n.failure())},n.failure),n}function o(e,t){var n;return qq.each(e,function(e,i){if(i>0){var o=/(max|min)(Width|Height)/.exec(e),r=o[2].charAt(0).toLowerCase()+o[2].slice(1),a=t[r];switch(o[1]){case"min":if(ai)return n=e,!1}}}),n}this.validate=function(e){var r=new qq.Promise;return t("Attempting to validate image."),n(e)?i().then(function(t){var n=o(e,t);n?r.failure(n):r.success()},r.success):r.success(),r}},qq.Session=function(e){"use strict";function t(e){if(qq.isArray(e))return!0;i.log("Session response is not an array.","error")}function n(e,n,o,r){var a=!1;n=n&&t(e),n&&qq.each(e,function(e,t){if(null==t.uuid)a=!0,i.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",e),"error");else if(null==t.name)a=!0,i.log(qq.format("Session response item {} did not include a valid name - ignoring.",e),"error");else try{return i.addFileRecord(t),!0}catch(e){a=!0,i.log(e.message,"error")}return!1}),r[n&&!a?"success":"failure"](e,o)}var i={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(e){},log:function(e,t){}};qq.extend(i,e,!0),this.refresh=function(){var e=new qq.Promise,t=function(t,i,o){n(t,i,o,e)},o=qq.extend({},i);return new qq.SessionAjaxRequester(qq.extend(o,{onComplete:t})).queryServer(),e}},qq.SessionAjaxRequester=function(e){"use strict";function t(e,t,n){var o=null;if(null!=t.responseText)try{o=qq.parseJson(t.responseText)}catch(e){i.log("Problem parsing session response: "+e.message,"error"),n=!0}i.onComplete(o,!n,t)}var n,i={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(e,t,n){},log:function(e,t){}};qq.extend(i,e),n=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return i.endpoint}},customHeaders:i.customHeaders,log:i.log,onComplete:t,cors:i.cors})),qq.extend(this,{queryServer:function(){var e=qq.extend({},i.params);i.log("Session query request."),n.initTransport("sessionRefresh").withParams(e).withCacheBuster().send()}})},qq.Scaler=function(e,t){"use strict";var n=e.customResizer,i=e.sendOriginal,o=e.orient,r=e.defaultType,a=e.defaultQuality/100,s=e.failureText,u=e.includeExif,l=this._getSortedSizes(e.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&l.length>0,getFileRecords:function(e,c,d){var p=this,h=[],f=d.blob?d.blob:d;return new qq.Identify(f,t).isPreviewableSync()?(qq.each(l,function(e,i){var l=p._determineOutputType({defaultType:r,requestedType:i.type,refType:f.type});h.push({uuid:qq.getUniqueId(),name:p._getName(c,{name:i.name,type:l,refType:f.type}),blob:new qq.BlobProxy(f,qq.bind(p._generateScaledImage,p,{customResizeFunction:n,maxSize:i.maxSize,orient:o,type:l,quality:a,failedText:s,includeExif:u,log:t}))})}),h.push({uuid:e,name:c,size:f.size,blob:i?f:null})):h.push({uuid:e,name:c,size:f.size,blob:f}),h},handleNewFile:function(e,t,n,i,o,r,a,s){var u=this,l=(e.qqButtonId||e.blob&&e.blob.qqButtonId,[]),c=null,d=s.addFileToHandler,p=s.uploadData,h=s.paramsStore,f=qq.getUniqueId();qq.each(u.getFileRecords(n,t,e),function(e,t){var n,i=t.size +;t.blob instanceof qq.BlobProxy&&(i=-1),n=p.addFile({uuid:t.uuid,name:t.name,size:i,batchId:r,proxyGroupId:f}),t.blob instanceof qq.BlobProxy?l.push(n):c=n,t.blob?(d(n,t.blob),o.push({id:n,file:t.blob})):p.setStatus(n,qq.status.REJECTED)}),null!==c&&(qq.each(l,function(e,t){var n={qqparentuuid:p.retrieve({id:c}).uuid,qqparentsize:p.retrieve({id:c}).size};n[a]=p.retrieve({id:t}).uuid,p.setParentId(t,c),h.addReadOnly(t,n)}),l.length&&function(){var e={};e[a]=p.retrieve({id:c}).uuid,h.addReadOnly(c,e)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(e,t,n){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var i=new qq.Promise,o=n.log,r=n.getFile(e),a=n.uploadData.retrieve({id:e}),s=a&&a.name,u=a&&a.uuid,l={customResizer:t.customResizer,sendOriginal:!1,orient:t.orient,defaultType:t.type||null,defaultQuality:t.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:t.maxSize}]},c=new qq.Scaler(l,o);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&r?qq.bind(function(){var t=c.getFileRecords(u,s,r)[0];t&&t.blob instanceof qq.BlobProxy?t.blob.create().then(i.success,i.failure):(o(e+" is not a scalable image!","error"),i.failure())},this)():(i.failure(),o("Could not generate requested scaled image for "+e+". Scaling is either not possible in this browser, or the file could not be located.","error")),i},_determineOutputType:function(e){"use strict";var t=e.requestedType,n=e.defaultType,i=e.refType;return n||t?t&&qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),t)>=0?"image/tiff"===t?qq.supportedFeatures.tiffPreviews?t:n:t:n:"image/jpeg"!==i?"image/png":i},_getName:function(e,t){"use strict";var n=e.lastIndexOf("."),i=t.type||"image/png",o=t.refType,r="",a=qq.getExtension(e),s="";return t.name&&t.name.trim().length&&(s=" ("+t.name+")"),n>=0?(r=e.substr(0,n),o!==i&&(a=i.split("/")[1]),r+=s+"."+a):r=e+s,r},_getSortedSizes:function(e){"use strict";return e=qq.extend([],e),e.sort(function(e,t){return e.maxSize>t.maxSize?1:e.maxSize=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),n=e.split(",")[0].split(":")[1].split(";")[0],i=new ArrayBuffer(t.length),o=new Uint8Array(i),qq.each(t,function(e,t){o[e]=t.charCodeAt(0)}),this._createBlob(i,n)},_createBlob:function(e,t){"use strict";var n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,i=n&&new n;return i?(i.append(e),i.getBlob(t)):new Blob([e],{type:t})}}),qq.ExifRestorer=function(){var e={};return e.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e.encode64=function(e){var t,n,i,o,r,a="",s="",u="",l=0;do t=e[l++],n=e[l++],s=e[l++],i=t>>2,o=(3&t)<<4|n>>4,r=(15&n)<<2|s>>6,u=63&s,isNaN(n)?r=u=64:isNaN(s)&&(u=64),a=a+this.KEY_STR.charAt(i)+this.KEY_STR.charAt(o)+this.KEY_STR.charAt(r)+this.KEY_STR.charAt(u),t=n=s="",i=o=r=u="";while(le.length)break}return n},e.decode64=function(e){var t,n,i,o,r,a="",s="",u=0,l=[];if(/[^A-Za-z0-9\+\/\=]/g.exec(e))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");do i=this.KEY_STR.indexOf(e.charAt(u++)),o=this.KEY_STR.indexOf(e.charAt(u++)),r=this.KEY_STR.indexOf(e.charAt(u++)),s=this.KEY_STR.indexOf(e.charAt(u++)),t=i<<2|o>>4,n=(15&o)<<4|r>>2,a=(3&r)<<6|s,l.push(t),64!=r&&l.push(n),64!=s&&l.push(a),t=n=a="",i=o=r=s="";while(u=0)return n=!1,!1}),n},l=function(e){p(e,-1,-1),delete n[e]},c=function(e,t,n){(0===t.length||u(t,n))&&(s(o,o),this.reset())},d=function(e){var i=t(e);i>0&&(p(e,0,i),n[e]={loaded:0,total:i})},p=function(e,t,r){var a=n[e]?n[e].loaded:0,u=n[e]?n[e].total:0;t===-1&&r===-1?(i-=a,o-=u):(t&&(i+=t-a),r&&(o+=r-u)),s(i,o)};qq.extend(this,{onAllComplete:c,onStatusChange:function(e,t,n){n===qq.status.CANCELED||n===qq.status.REJECTED?l(e):n===qq.status.SUBMITTING&&d(e)},onIndividualProgress:function(e,t,i){p(e,t,i),n[e]={loaded:t,total:i}},onNewSize:function(e){d(e)},reset:function(){n={},i=0,o=0}})},qq.PasteSupport=function(e){"use strict";function t(e){return e.type&&0===e.type.indexOf("image/")}function n(){r=qq(o.targetElement).attach("paste",function(e){var n=e.clipboardData;n&&qq.each(n.items,function(e,n){if(t(n)){var i=n.getAsFile();o.callbacks.pasteReceived(i)}})})}function i(){r&&r()}var o,r;o={targetElement:null,callbacks:{log:function(e,t){},pasteReceived:function(e){}}},qq.extend(o,e),n(),qq.extend(this,{reset:function(){i()}})},qq.FormSupport=function(e,t,n){"use strict";function i(e){e.getAttribute("action")&&(s.newEndpoint=e.getAttribute("action"))}function o(e,t){if(!e.checkValidity||e.checkValidity())return!0;n("Form did not pass validation checks - will not upload.","error"),t()}function r(e){var n=e.submit;qq(e).attach("submit",function(i){i=i||window.event,i.preventDefault?i.preventDefault():i.returnValue=!1,o(e,n)&&t()}),e.submit=function(){o(e,n)&&t()}}function a(e){return e&&(qq.isString(e)&&(e=document.getElementById(e)),e&&(n("Attaching to form element."),i(e),u&&r(e))),e}var s=this,u=e.interceptSubmit,l=e.element,c=e.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:c,attachedToForm:!1,getFormInputsAsObject:function(){return null==l?null:s._form2Obj(l)}}),l=a(l),this.attachedToForm=!!l},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(e){"use strict";var t={},n=function(e){var t=["button","image","reset","submit"];return qq.indexOf(t,e.toLowerCase())<0},i=function(e){return qq.indexOf(["checkbox","radio"],e.toLowerCase())>=0},o=function(e){return!(!i(e.type)||e.checked)||e.disabled&&"hidden"!==e.type.toLowerCase()},r=function(e){var t=null;return qq.each(qq(e).children(),function(e,n){if("option"===n.tagName.toLowerCase()&&n.selected)return t=n.value,!1}),t};return qq.each(e.elements,function(e,i){if(!qq.isInput(i,!0)&&"textarea"!==i.tagName.toLowerCase()||!n(i.type)||o(i)){if("select"===i.tagName.toLowerCase()&&!o(i)){var a=r(i);null!==a&&(t[i.name]=a)}}else t[i.name]=i.value}),t}}),qq.traditional=qq.traditional||{},qq.traditional.FormUploadHandler=function(e,t){"use strict";function n(e,t){var n,i,r;try{i=t.contentDocument||t.contentWindow.document,r=i.body.innerHTML,s("converting iframe's innerHTML to JSON"),s("innerHTML = "+r),r&&r.match(/^1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n delete handler._getFileState(id).temp.cachedChunks[chunkIdx];\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) && !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var inProgress = optInProgress || handler._getFileState(id).chunking.inProgress,\n remaining = optRemaining || handler._getFileState(id).chunking.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = chunking.partSize,\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/Widen/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = chunking.partSize,\n endpoint = getEndpoint(id);\n\n return qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = chunking.partSize;\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now()\n };\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1&&!c.allowMultipleItems?(c.callbacks.processingDroppedFilesComplete([]),c.callbacks.dropError("tooManyFilesError",""),t.dropDisabled(!1),o.failure()):(p=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,t){var r=t.webkitGetAsEntry();r&&(r.isFile?p.push(t.getAsFile()):i.push(n(r).done(function(){i.pop(),0===i.length&&o.success()})))}):p=e.files,0===i.length&&o.success()),o}function a(e){var n=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:"qq-hidezones",element:e,onEnter:function(t){qq(e).addClass(c.classes.dropActive),t.stopPropagation()},onLeaveNotDescendants:function(t){qq(e).removeClass(c.classes.dropActive)},onDrop:function(e){r(e.dataTransfer,n).then(function(){t(p,n)},function(){c.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return h.addDisposer(function(){n.dispose()}),qq(e).hasAttribute("qq-hide-dropzone")&&qq(e).hide(),d.push(n),n}function s(e){var t;return qq.each(e.dataTransfer.types,function(e,n){if("Files"===n)return t=!0,!1}),t}function u(e){return qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function l(){var e=c.dropZoneElements,t=function(){setTimeout(function(){qq.each(e,function(e,t){qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).hide(),qq(t).removeClass(c.classes.dropActive)})},10)};qq.each(e,function(t,n){var i=a(n);e.length&&qq.supportedFeatures.fileDrop&&h.attach(document,"dragenter",function(t){!i.dropDisabled()&&s(t)&&qq.each(e,function(e,t){t instanceof HTMLElement&&qq(t).hasAttribute("qq-hide-dropzone")&&qq(t).css({display:"block"})})})}),h.attach(document,"dragleave",function(e){u(e)&&t()}),h.attach(qq(document).children()[0],"mouseenter",function(e){t()}),h.attach(document,"drop",function(e){s(e)&&(e.preventDefault(),t())}),h.attach(document,"qq-hidezones",t)}var c,d=[],p=[],h=new qq.DisposeSupport;c={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(c,e,!0),l(),qq.extend(this,{setupExtraDropzone:function(e){c.dropZoneElements.push(e),a(e)},removeDropzone:function(e){var t,n=c.dropZoneElements;for(t in n)if(n[t]===e)return n.splice(t,1)},dispose:function(){h.dispose(),qq.each(d,function(e,t){t.dispose()})}}),this._testing={},this._testing.extractDirectoryPath=i},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,t){},dropError:function(e,t){qq.log("Drag & drop error code '"+e+" with these specifics: '"+t+"'","error")},dropLog:function(e,t){qq.log(e,t)}}},qq.UploadDropZone=function(e){"use strict";function t(){return qq.safari()||qq.firefox()&&qq.windows()}function n(e){c||(t?d.attach(document,"dragover",function(e){e.preventDefault()}):d.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),c=!0)}function i(e){if(!qq.supportedFeatures.fileDrop)return!1;var t,n=e.dataTransfer,i=qq.safari();return t=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==n.effectAllowed,n&&t&&(n.files&&n.files.length||!i&&n.types.contains&&n.types.contains("Files")||n.types.includes&&n.types.includes("Files"))}function o(e){return void 0!==e&&(l=e),l}function r(){function e(){t=document.createEvent("Event"),t.initEvent(s.HIDE_ZONES_EVENT_NAME,!0,!0)}var t;if(window.CustomEvent)try{t=new CustomEvent(s.HIDE_ZONES_EVENT_NAME)}catch(t){e()}else e();document.dispatchEvent(t)}function a(){d.attach(u,"dragover",function(e){if(i(e)){var t=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;e.dataTransfer.dropEffect="move"===t||"linkMove"===t?"move":"copy",e.stopPropagation(),e.preventDefault()}}),d.attach(u,"dragenter",function(e){if(!o()){if(!i(e))return;s.onEnter(e)}}),d.attach(u,"dragleave",function(e){if(i(e)){s.onLeave(e);var t=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(t)||s.onLeaveNotDescendants(e)}}),d.attach(u,"drop",function(e){if(!o()){if(!i(e))return;e.preventDefault(),e.stopPropagation(),s.onDrop(e),r()}})}var s,u,l,c,d=new qq.DisposeSupport;s={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(s,e),u=s.element,n(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){d.dispose()},getElement:function(){return u}}),this._testing={},this._testing.isValidFileDrag=i},function(){"use strict";qq.uiPublicApi={addInitialFiles:function(e){this._parent.prototype.addInitialFiles.apply(this,arguments),this._templating.addCacheToDom()},clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(e){this._dnd&&this._dnd.setupExtraDropzone(e)},removeExtraDropzone:function(e){if(this._dnd)return this._dnd.removeDropzone(e)},getItemByFileId:function(e){if(!this._templating.isHiddenForever(e))return this._templating.getFileContainer(e)},reset:function(){this._parent.prototype.reset.apply(this,arguments),this._templating.reset(),!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(e,t){var n=this._options.formatFileName(t);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(e,n)},pauseUpload:function(e){var t=this._parent.prototype.pauseUpload.apply(this,arguments);return t&&this._templating.uploadPaused(e),t},continueUpload:function(e){var t=this._parent.prototype.continueUpload.apply(this,arguments);return t&&this._templating.uploadContinued(e),t},getId:function(e){return this._templating.getFileId(e)},getDropTarget:function(e){return this.getFile(e).qqDropTarget}},qq.uiPrivateApi={_getButton:function(e){var t=this._parent.prototype._getButton.apply(this,arguments);return t||e===this._defaultButtonId&&(t=this._templating.getButton()),t},_removeFileItem:function(e){this._templating.removeFile(e)},_setupClickAndEditEventHandlers:function(){this._fileButtonsClickHandler=qq.FileButtonsClickHandler&&this._bindFileButtonsClickEvent(),this._focusinEventSupported=!qq.firefox(),this._isEditFilenameEnabled()&&(this._filenameClickHandler=this._bindFilenameClickEvent(),this._filenameInputFocusInHandler=this._bindFilenameInputFocusInEvent(),this._filenameInputFocusHandler=this._bindFilenameInputFocusEvent())},_setupDragAndDrop:function(){var e=this,t=this._options.dragAndDrop.extraDropzones,n=this._templating,i=n.getDropZone();return i&&t.push(i),new qq.DragAndDrop({dropZoneElements:t,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){n.showDropProcessing()},processingDroppedFilesComplete:function(t,i){n.hideDropProcessing(),qq.each(t,function(e,t){t.qqDropTarget=i}),t.length&&e.addFiles(t,null,null)},dropError:function(t,n){e._itemError(t,n)},dropLog:function(t,n){e.log(t,n)}}})},_bindFileButtonsClickEvent:function(){var e=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(t,n){e.log(t,n)},onDeleteFile:function(t){e.deleteFile(t)},onCancel:function(t){e.cancel(t)},onRetry:function(t){e.retry(t)},onPause:function(t){e.pauseUpload(t)},onContinue:function(t){e.continueUpload(t)},onGetName:function(t){return e.getName(t)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var e=this,t=this._templating;return{templating:t,log:function(t,n){e.log(t,n)},onGetUploadStatus:function(t){return e.getUploads({id:t}).status},onGetName:function(t){return e.getName(t)},onSetName:function(t,n){e.setName(t,n)},onEditingStatusChange:function(e,n){var i=qq(t.getEditInput(e)),o=qq(t.getFileContainer(e));n?(i.addClass("qq-editing"),t.hideFilename(e),t.hideEditIcon(e)):(i.removeClass("qq-editing"),t.showFilename(e),t.showEditIcon(e)),o.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(e,t,n){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(e)&&n!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(e),this._templating.hideEditIcon(e)),t===qq.status.UPLOAD_RETRYING&&n===qq.status.UPLOADING?(this._templating.hideRetry(e),this._templating.setStatusText(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.retrying)):n===qq.status.UPLOAD_FAILED&&this._templating.hidePause(e)},_bindFilenameInputFocusInEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(e)},_bindFilenameInputFocusEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(e)},_bindFilenameClickEvent:function(){var e=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(e)},_storeForLater:function(e){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(e)},_onAllComplete:function(e,t){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(e,t){var n=this.getFile(e);n&&n.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(e,{qqpath:n.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(e,t)},_onSubmitted:function(e){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(e),this._templating.showEditIcon(e),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(e)))},_onProgress:function(e,t,n,i){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(e,n,i),0===i||100===Math.round(n/i*100)?(this._templating.hideCancel(e),this._templating.hidePause(e),this._templating.hideProgress(e),this._templating.setStatusText(e,this._options.text.waitingForResponse),this._displayFileSize(e)):this._displayFileSize(e,n,i)},_onTotalProgress:function(e,t){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(e,t)},_onComplete:function(e,t,n,i){function o(t){s&&(a.setStatusText(e),qq(s).removeClass(u._classes.retrying),a.hideProgress(e),u.getUploads({id:e}).status!==qq.status.UPLOAD_FAILED&&a.hideCancel(e),a.hideSpinner(e),t.success?u._markFileAsSuccessful(e):(qq(s).addClass(u._classes.fail),a.showCancel(e),a.isRetryPossible()&&!u._preventRetries[e]&&(qq(s).addClass(u._classes.retryable),a.showRetry(e)),u._controlFailureTextDisplay(e,t)))}var r=this._parent.prototype._onComplete.apply(this,arguments),a=this._templating,s=a.getFileContainer(e),u=this;return r instanceof qq.Promise?r.done(function(e){o(e)}):o(n),r},_markFileAsSuccessful:function(e){var t=this._templating;this._isDeletePossible()&&t.showDeleteButton(e),qq(t.getFileContainer(e)).addClass(this._classes.success),this._maybeUpdateThumbnail(e)},_onUploadPrep:function(e){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(e)},_onUpload:function(e,t){var n=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(e),n},_onUploadChunk:function(e,t){this._parent.prototype._onUploadChunk.apply(this,arguments),t.partIndex>0&&this._handler.isResumable(e)&&this._templating.allowPause(e)},_onCancel:function(e,t){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(e),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(e){var t,n,i;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(e),this._options.retry.showAutoRetryNote&&(t=this._autoRetries[e],n=this._options.retry.maxAutoAttempts,i=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,t),i=i.replace(/\{maxAuto\}/g,n),this._templating.setStatusText(e,i),qq(this._templating.getFileContainer(e)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(e){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(e),qq(this._templating.getFileContainer(e)).removeClass(this._classes.fail),this._templating.setStatusText(e),this._templating.showSpinner(e),this._showCancelLink(e),!0):(qq(this._templating.getFileContainer(e)).addClass(this._classes.retryable),this._templating.showRetry(e),!1)},_onSubmitDelete:function(e){var t=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,e,t)},_onSubmitDeleteSuccess:function(e,t,n){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(e,t,n){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(e),n?(this._templating.setStatusText(e,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(e)):this._removeFileItem(e)},_sendDeleteRequest:function(e,t,n){this._templating.hideDeleteButton(e),this._templating.showSpinner(e),this._templating.setStatusText(e,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(e,t,n){var i,o=this.getName(e),r=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,o),a=(this.getUuid(e),arguments),s=this;i=this._options.showConfirm(r),qq.isGenericPromise(i)?i.then(function(){s._sendDeleteRequest.apply(s,a)}):i!==!1&&s._sendDeleteRequest.apply(s,a)},_addToList:function(e,t,n){var i,o,r=0,a=this._handler.isProxied(e)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(r=this._filesInBatchAddedToUi-1),i={index:r}),n||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(o=this.getUploads({id:e}),this._handledProxyGroup=this._handledProxyGroup||o.proxyGroupId,o.proxyGroupId===this._handledProxyGroup&&o.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),n?(this._templating.addFileToCache(e,this._options.formatFileName(t),i,a),this._templating.updateThumbnail(e,this._thumbnailUrls[e],!0,this._options.thumbnails.customResizer)):(this._templating.addFile(e,this._options.formatFileName(t),i,a),this._templating.generatePreview(e,this.getFile(e),this._options.thumbnails.customResizer)),this._filesInBatchAddedToUi+=1,(n||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(e)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(e,t,n){var i=this.getSize(e),o=this._formatSize(i);i>=0&&(void 0!==t&&void 0!==n&&(o=this._formatProgress(t,n)),this._templating.updateSize(e,o))},_formatProgress:function(e,t){function n(e,t){i=i.replace(e,t)}var i=this._options.text.formatProgress;return n("{percent}",Math.round(e/t*100)),n("{total_size}",this._formatSize(t)),i},_controlFailureTextDisplay:function(e,t){var n,i,o;n=this._options.failedUploadTextDisplay.mode,i=this._options.failedUploadTextDisplay.responseProperty,"custom"===n?(o=t[i],o||(o=this._options.text.failUpload),this._templating.setStatusText(e,o),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(e,o)):"default"===n?this._templating.setStatusText(e,this._options.text.failUpload):"none"!==n&&this.log("failedUploadTextDisplay.mode value of '"+n+"' is not valid","warn")},_showTooltip:function(e,t){this._templating.getFileContainer(e).title=t},_showCancelLink:function(e){this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading||this._templating.showCancel(e)},_itemError:function(e,t,n){var i=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(i)},_batchError:function(e){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(e)},_setupPastePrompt:function(){var e=this;this._options.callbacks.onPasteReceived=function(){var t=e._options.paste.namePromptMessage,n=e._options.paste.defaultName;return e._options.showPrompt(t,n)}},_fileOrBlobRejected:function(e,t){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(e,t,n){ +this._totalFilesInBatch=e.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(e){var t=this._thumbnailUrls[e];this.getUploads({id:e}).status===qq.status.DELETED||!t&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(e,t,this._options.thumbnails.customResizer)},_addCannedFile:function(e){var t=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(t,this.getName(t),!0),this._templating.hideSpinner(t),this._templating.hideCancel(t),this._markFileAsSuccessful(t),t},_setSize:function(e,t){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(e,this._formatSize(t))},_sessionRequestComplete:function(){this._templating.addCacheToDom(),this._parent.prototype._sessionRequestComplete.apply(this,arguments)}}}(),qq.FineUploader=function(e,t){"use strict";var n=this;this._parent=t?qq[t].FineUploaderBasic:qq.FineUploaderBasic,this._parent.apply(this,arguments),qq.extend(this._options,{element:null,button:null,listElement:null,dragAndDrop:{extraDropzones:[],reportDirectoryPaths:!1},text:{formatProgress:"{percent}% of {total_size}",failUpload:"Upload failed",waitingForResponse:"Processing...",paused:"Paused"},template:"qq-template",classes:{retrying:"qq-upload-retrying",retryable:"qq-upload-retryable",success:"qq-upload-success",fail:"qq-upload-fail",editable:"qq-editable",hide:"qq-hide",dropActive:"qq-upload-drop-area-active"},failedUploadTextDisplay:{mode:"default",responseProperty:"error",enableTooltip:!0},messages:{tooManyFilesError:"You may only drop one file",unsupportedBrowser:"Unrecoverable error - this browser does not permit file uploading of any kind."},retry:{showAutoRetryNote:!0,autoRetryNote:"Retrying {retryNum}/{maxAuto}..."},deleteFile:{forceConfirm:!1,confirmMessage:"Are you sure you want to delete {filename}?",deletingStatusText:"Deleting...",deletingFailedText:"Delete failed"},display:{fileSizeOnSubmit:!1,prependFiles:!1},paste:{promptForName:!1,namePromptMessage:"Please name this image"},thumbnails:{customResizer:null,maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(e){if(n._templating.hasDialog("alert"))return n._templating.showDialog("alert",e);setTimeout(function(){window.alert(e)},0)},showConfirm:function(e){return n._templating.hasDialog("confirm")?n._templating.showDialog("confirm",e):window.confirm(e)},showPrompt:function(e,t){return n._templating.hasDialog("prompt")?n._templating.showDialog("prompt",e,t):window.prompt(e,t)}},!0),qq.extend(this._options,e,!0),this._templating=new qq.Templating({log:qq.bind(this.log,this),templateIdOrEl:this._options.template,containerEl:this._options.element,fileContainerEl:this._options.listElement,button:this._options.button,imageGenerator:this._imageGenerator,classes:{hide:this._options.classes.hide,editable:this._options.classes.editable},limits:{maxThumbs:this._options.thumbnails.maxCount,timeBetweenThumbs:this._options.thumbnails.timeBetweenThumbs},placeholders:{waitUntilUpdate:this._options.thumbnails.placeholders.waitUntilResponse,thumbnailNotAvailable:this._options.thumbnails.placeholders.notAvailablePath,waitingForThumbnail:this._options.thumbnails.placeholders.waitingPath},text:this._options.text}),this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari()?this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari):!qq.supportedFeatures.uploading||this._options.cors.expected&&!qq.supportedFeatures.uploadCors?this._templating.renderFailure(this._options.messages.unsupportedBrowser):(this._wrapCallbacks(),this._templating.render(),this._classes=this._options.classes,!this._options.button&&this._templating.getButton()&&(this._defaultButtonId=this._createUploadButton({element:this._templating.getButton(),title:this._options.text.fileInputTitle}).getButtonId()),this._setupClickAndEditEventHandlers(),qq.DragAndDrop&&qq.supportedFeatures.fileDrop&&(this._dnd=this._setupDragAndDrop()),this._options.paste.targetElement&&this._options.paste.promptForName&&(qq.PasteSupport?this._setupPastePrompt():this.log("Paste support module not found.","error")),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0)},qq.extend(qq.FineUploader.prototype,qq.basePublicApi),qq.extend(qq.FineUploader.prototype,qq.basePrivateApi),qq.extend(qq.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.FineUploader.prototype,qq.uiPrivateApi),qq.Templating=function(e){"use strict";var t,n,i,o,r,a,s,u,l={content:document.createDocumentFragment(),map:{}},c=!1,d=0,p=!1,h=[],f=-1,q={log:null,limits:{maxThumbs:0,timeBetweenThumbs:750},templateIdOrEl:"qq-template",containerEl:null,fileContainerEl:null,button:null,imageGenerator:null,classes:{hide:"qq-hide",editable:"qq-editable"},placeholders:{waitUntilUpdate:!1,thumbnailNotAvailable:null,waitingForThumbnail:null},text:{paused:"Paused"}},m={button:"qq-upload-button-selector",alertDialog:"qq-alert-dialog-selector",dialogCancelButton:"qq-cancel-button-selector",confirmDialog:"qq-confirm-dialog-selector",dialogMessage:"qq-dialog-message-selector",dialogOkButton:"qq-ok-button-selector",promptDialog:"qq-prompt-dialog-selector",uploader:"qq-uploader-selector",drop:"qq-upload-drop-area-selector",list:"qq-upload-list-selector",progressBarContainer:"qq-progress-bar-container-selector",progressBar:"qq-progress-bar-selector",totalProgressBarContainer:"qq-total-progress-bar-container-selector",totalProgressBar:"qq-total-progress-bar-selector",file:"qq-upload-file-selector",spinner:"qq-upload-spinner-selector",size:"qq-upload-size-selector",cancel:"qq-upload-cancel-selector",pause:"qq-upload-pause-selector",continueButton:"qq-upload-continue-selector",deleteButton:"qq-upload-delete-selector",retry:"qq-upload-retry-selector",statusText:"qq-upload-status-text-selector",editFilenameInput:"qq-edit-filename-selector",editNameIcon:"qq-edit-filename-icon-selector",dropText:"qq-upload-drop-area-text-selector",dropProcessing:"qq-drop-processing-selector",dropProcessingSpinner:"qq-drop-processing-spinner-selector",thumbnail:"qq-thumbnail-selector"},g={},_=new qq.Promise,v=new qq.Promise,b=function(){var e=q.placeholders.thumbnailNotAvailable,n=q.placeholders.waitingForThumbnail,i={maxSize:f,scale:u};s&&(e?q.imageGenerator.generate(e,new Image,i).then(function(e){_.success(e)},function(){_.failure(),t("Problem loading 'not available' placeholder image at "+e,"error")}):_.failure(),n?q.imageGenerator.generate(n,new Image,i).then(function(e){v.success(e)},function(){v.failure(),t("Problem loading 'waiting for thumbnail' placeholder image at "+n,"error")}):v.failure())},y=function(e){var t=new qq.Promise;return v.then(function(n){z(n,e),e.src?t.success():(e.src=n.src,e.onload=function(){e.onload=null,W(e),t.success()})},function(){L(e),t.success()}),t},S=function(e,n,i){var o=O(e);return t("Generating new thumbnail for "+e),n.qqThumbnailId=e,q.imageGenerator.generate(n,o,i).then(function(){d++,W(o),g[e].success()},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,o)})},w=function(){if(h.length){p=!0;var e=h.shift();e.update?V(e):G(e)}else p=!1},F=function(e){return N(P(e),m.cancel)},x=function(e){return N(P(e),m.continueButton)},C=function(e){return N(r,m[e+"Dialog"])},I=function(e){return N(P(e),m.deleteButton)},E=function(){return N(r,m.dropProcessing)},D=function(e){return N(P(e),m.editNameIcon)},P=function(e){return l.map[e]||qq(a).getFirstByClass("qq-file-id-"+e)},U=function(e){return N(P(e),m.file)},T=function(e){return N(P(e),m.pause)},R=function(e){return null==e?N(r,m.totalProgressBarContainer)||N(r,m.totalProgressBar):N(P(e),m.progressBarContainer)||N(P(e),m.progressBar)},k=function(e){return N(P(e),m.retry)},A=function(e){return N(P(e),m.size)},B=function(e){return N(P(e),m.spinner)},N=function(e,t){return e&&qq(e).getFirstByClass(t)},O=function(e){return s&&N(P(e),m.thumbnail)},L=function(e){e&&qq(e).addClass(q.classes.hide)},z=function(e,t){var n=e.style.maxWidth,i=e.style.maxHeight;i&&n&&!t.style.maxWidth&&!t.style.maxHeight&&qq(t).css({maxWidth:n,maxHeight:i})},H=function(e,t){var n=g[e]||(new qq.Promise).failure(),i=new qq.Promise;return _.then(function(e){n.then(function(){i.success()},function(){z(e,t),t.onload=function(){t.onload=null,i.success()},t.src=e.src,W(t)})}),i},j=function(){var e,o,r,a,l,c,d,p,h,g,_;if(t("Parsing template"),null==q.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(q.templateIdOrEl)){if(e=document.getElementById(q.templateIdOrEl),null===e)throw new Error(qq.format("Cannot find template script at ID '{}'!",q.templateIdOrEl));o=e.innerHTML}else{if(void 0===q.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");o=q.templateIdOrEl.innerHTML}if(o=qq.trimStr(o),a=document.createElement("div"),a.appendChild(qq.toElement(o)),_=qq(a).getFirstByClass(m.uploader),q.button&&(c=qq(a).getFirstByClass(m.button),c&&qq(c).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(h=qq(a).getFirstByClass(m.dropProcessing),h&&qq(h).remove()),d=qq(a).getFirstByClass(m.drop),d&&!qq.DragAndDrop&&(t("DnD module unavailable.","info"),qq(d).remove()),qq.supportedFeatures.fileDrop?qq(_).hasAttribute("qq-drop-area-text")&&d&&(g=qq(d).getFirstByClass(m.dropText),g&&qq(g).remove()):(_.removeAttribute("qq-drop-area-text"),d&&qq(d).hasAttribute("qq-hide-dropzone")&&qq(d).css({display:"none"})),p=qq(a).getFirstByClass(m.thumbnail),s?p&&(f=parseInt(p.getAttribute("qq-max-size")),f=f>0?f:null,u=qq(p).hasAttribute("qq-server-scale")):p&&qq(p).remove(),s=s&&p,n=qq(a).getByClass(m.editFilenameInput).length>0,i=qq(a).getByClass(m.retry).length>0,r=qq(a).getFirstByClass(m.list),null==r)throw new Error("Could not find the file list container in the template!");return l=r.children[0].cloneNode(!0),r.innerHTML="",a.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),t("Template parsing complete"),{template:a,fileTemplate:l}},M=function(e,t,n){var i=n,o=i.firstChild;t>0&&(o=qq(i).children()[t].nextSibling),i.insertBefore(e,o)},G=function(e){var t=e.id,n=e.optFileOrBlob,i=n&&n.qqThumbnailId,o=O(t),r={customResizeFunction:e.customResizeFunction,maxSize:f,orient:!0,scale:!0};qq.supportedFeatures.imagePreviews?o?q.limits.maxThumbs&&q.limits.maxThumbs<=d?(H(t,o),w()):y(o).done(function(){g[t]=new qq.Promise,g[t].done(function(){setTimeout(w,q.limits.timeBetweenThumbs)}),null!=i?Q(t,i):S(t,n,r)}):w():o&&(y(o),w())},V=function(e){var t=e.id,n=e.thumbnailUrl,i=e.showWaitingImg,o=O(t),r={customResizeFunction:e.customResizeFunction,scale:u,maxSize:f};if(o)if(n){if(!(q.limits.maxThumbs&&q.limits.maxThumbs<=d))return i&&y(o),q.imageGenerator.generate(n,o,r).then(function(){W(o),d++,setTimeout(w,q.limits.timeBetweenThumbs)},function(){H(t,o),setTimeout(w,q.limits.timeBetweenThumbs)});H(t,o),w()}else H(t,o),w()},X=function(e,t){var n=R(e),i=null==e?m.totalProgressBar:m.progressBar;n&&!qq(n).hasClass(i)&&(n=qq(n).getFirstByClass(i)),n&&(qq(n).css({width:t+"%"}),n.setAttribute("aria-valuenow",t))},W=function(e){e&&qq(e).removeClass(q.classes.hide)},Q=function(e,n){var i=O(e),o=O(n);t(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",e,n,n)),g[n].then(function(){d++,g[e].success(),t(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",n,e)),i.src=o.src,W(i)},function(){g[e].failure(),q.placeholders.waitUntilUpdate||H(e,i)})};qq.extend(q,e),t=q.log,qq.supportedFeatures.imagePreviews||(q.limits.timeBetweenThumbs=0,q.limits.maxThumbs=0),r=q.containerEl,s=void 0!==q.imageGenerator,o=j(),b(),qq.extend(this,{render:function(){t("Rendering template in DOM."),d=0,r.appendChild(o.template.cloneNode(!0)),L(E()),this.hideTotalProgress(),a=q.fileContainerEl||N(r,m.list),t("Template rendering complete")},renderFailure:function(e){var t=qq.toElement(e);r.innerHTML="",r.appendChild(t)},reset:function(){r.innerHTML="",this.render()},clearFiles:function(){a.innerHTML=""},disableCancel:function(){c=!0},addFile:function(e,t,n,i,s){var u,d=o.fileTemplate.cloneNode(!0),p=N(d,m.file),h=N(r,m.uploader),f=s?l.content:a;s&&(l.map[e]=d),qq(d).addClass("qq-file-id-"+e),h.removeAttribute("qq-drop-area-text"),p&&(qq(p).setText(t),p.setAttribute("title",t)),d.setAttribute("qq-file-id",e),n?M(d,n.index,f):f.appendChild(d),i?(d.style.display="none",qq(d).addClass("qq-hidden-forever")):(L(R(e)),L(A(e)),L(I(e)),L(k(e)),L(T(e)),L(x(e)),c&&this.hideCancel(e),u=O(e),u&&!u.src&&v.then(function(e){u.src=e.src,e.style.maxHeight&&e.style.maxWidth&&qq(u).css({maxHeight:e.style.maxHeight,maxWidth:e.style.maxWidth}),W(u)}))},addFileToCache:function(e,t,n,i){this.addFile(e,t,n,i,!0)},addCacheToDom:function(){a.appendChild(l.content),l.content=document.createDocumentFragment(),l.map={}},removeFile:function(e){qq(P(e)).remove()},getFileId:function(e){var t=e;if(t){for(;null==t.getAttribute("qq-file-id");)t=t.parentNode;return parseInt(t.getAttribute("qq-file-id"))}},getFileList:function(){return a},markFilenameEditable:function(e){var t=U(e);t&&qq(t).addClass(q.classes.editable)},updateFilename:function(e,t){var n=U(e);n&&(qq(n).setText(t),n.setAttribute("title",t))},hideFilename:function(e){L(U(e))},showFilename:function(e){W(U(e))},isFileName:function(e){return qq(e).hasClass(m.file)},getButton:function(){return q.button||N(r,m.button)},hideDropProcessing:function(){L(E())},showDropProcessing:function(){W(E())},getDropZone:function(){return N(r,m.drop)},isEditFilenamePossible:function(){return n},hideRetry:function(e){L(k(e))},isRetryPossible:function(){return i},showRetry:function(e){W(k(e))},getFileContainer:function(e){return P(e)},showEditIcon:function(e){var t=D(e);t&&qq(t).addClass(q.classes.editable)},isHiddenForever:function(e){return qq(P(e)).hasClass("qq-hidden-forever")},hideEditIcon:function(e){var t=D(e);t&&qq(t).removeClass(q.classes.editable)},isEditIcon:function(e){return qq(e).hasClass(m.editNameIcon,!0)},getEditInput:function(e){return N(P(e),m.editFilenameInput)},isEditInput:function(e){return qq(e).hasClass(m.editFilenameInput,!0)},updateProgress:function(e,t,n){var i,o=R(e);o&&n>0&&(i=Math.round(t/n*100),100===i?L(o):W(o),X(e,i))},updateTotalProgress:function(e,t){this.updateProgress(null,e,t)},hideProgress:function(e){var t=R(e);t&&L(t)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(e){X(e,0),this.hideTotalProgress(e)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(e){if(!c){var t=F(e);t&&qq(t).removeClass(q.classes.hide)}},hideCancel:function(e){L(F(e))},isCancel:function(e){return qq(e).hasClass(m.cancel,!0)},allowPause:function(e){W(T(e)),L(x(e))},uploadPaused:function(e){this.setStatusText(e,q.text.paused),this.allowContinueButton(e),L(B(e))},hidePause:function(e){L(T(e))},isPause:function(e){return qq(e).hasClass(m.pause,!0)},isContinueButton:function(e){return qq(e).hasClass(m.continueButton,!0)},allowContinueButton:function(e){W(x(e)),L(T(e))},uploadContinued:function(e){this.setStatusText(e,""),this.allowPause(e),W(B(e))},showDeleteButton:function(e){W(I(e))},hideDeleteButton:function(e){L(I(e))},isDeleteButton:function(e){return qq(e).hasClass(m.deleteButton,!0)},isRetry:function(e){return qq(e).hasClass(m.retry,!0)},updateSize:function(e,t){var n=A(e);n&&(W(n),qq(n).setText(t))},setStatusText:function(e,t){var n=N(P(e),m.statusText);n&&(null==t?qq(n).clearText():qq(n).setText(t))},hideSpinner:function(e){qq(P(e)).removeClass("qq-in-progress"),L(B(e))},showSpinner:function(e){qq(P(e)).addClass("qq-in-progress"),W(B(e))},generatePreview:function(e,t,n){this.isHiddenForever(e)||(h.push({id:e,customResizeFunction:n,optFileOrBlob:t}),!p&&w())},updateThumbnail:function(e,t,n,i){this.isHiddenForever(e)||(h.push({customResizeFunction:i,update:!0,id:e,thumbnailUrl:t,showWaitingImg:n}),!p&&w())},hasDialog:function(e){return qq.supportedFeatures.dialogElement&&!!C(e)},showDialog:function(e,t,n){var i=C(e),o=N(i,m.dialogMessage),r=i.getElementsByTagName("INPUT")[0],a=N(i,m.dialogCancelButton),s=N(i,m.dialogOkButton),u=new qq.Promise,l=function(){a.removeEventListener("click",c),s&&s.removeEventListener("click",d),u.failure()},c=function(){a.removeEventListener("click",c),i.close()},d=function(){i.removeEventListener("close",l),s.removeEventListener("click",d),i.close(),u.success(r&&r.value)};return i.addEventListener("close",l),a.addEventListener("click",c),s&&s.addEventListener("click",d),r&&(r.value=n),o.textContent=t,i.showModal(),u}})},qq.UiEventHandler=function(e,t){"use strict";function n(e){i.attach(e,o.eventType,function(e){e=e||window.event;var t=e.target||e.srcElement;o.onHandled(t,e)})}var i=new qq.DisposeSupport,o={eventType:"click",attachTo:null,onHandled:function(e,t){}};qq.extend(this,{addHandler:function(e){n(e)},dispose:function(){i.dispose()}}),qq.extend(t,{getFileIdFromItem:function(e){return e.qqFileId},getDisposeSupport:function(){return i}}),qq.extend(o,e),o.attachTo&&n(o.attachTo)},qq.FileButtonsClickHandler=function(e){"use strict";function t(e,t){qq.each(o,function(n,o){var r,a=n.charAt(0).toUpperCase()+n.slice(1);if(i.templating["is"+a](e))return r=i.templating.getFileId(e),qq.preventDefault(t),i.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",i.onGetName(r),r)),o(r),!1})}var n={},i={templating:null,log:function(e,t){},onDeleteFile:function(e){},onCancel:function(e){},onRetry:function(e){},onPause:function(e){},onContinue:function(e){},onGetName:function(e){}},o={cancel:function(e){i.onCancel(e)},retry:function(e){i.onRetry(e)},deleteButton:function(e){i.onDeleteFile(e)},pause:function(e){i.onPause(e)},continueButton:function(e){i.onContinue(e)}};qq.extend(i,e),i.eventType="click",i.onHandled=t,i.attachTo=i.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(i,n))},qq.FilenameClickHandler=function(e){"use strict";function t(e,t){if(i.templating.isFileName(e)||i.templating.isEditIcon(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",i.onGetName(o),o)),qq.preventDefault(t),n.handleFilenameEdit(o,e,!0))}}var n={},i={templating:null,log:function(e,t){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(e){},onGetName:function(e){}};qq.extend(i,e),i.eventType="click",i.onHandled=t,qq.extend(this,new qq.FilenameEditHandler(i,n))},qq.FilenameInputFocusInHandler=function(e,t){"use strict";function n(e,n){if(i.templating.isEditInput(e)){var o=i.templating.getFileId(e);i.onGetUploadStatus(o)===qq.status.SUBMITTED&&(i.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",i.onGetName(o),o)),t.handleFilenameEdit(o,e))}}var i={templating:null,onGetUploadStatus:function(e){},log:function(e,t){}};t||(t={}),i.eventType="focusin",i.onHandled=n,qq.extend(i,e),qq.extend(this,new qq.FilenameEditHandler(i,t))},qq.FilenameInputFocusHandler=function(e){"use strict";e.eventType="focus",e.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(e,{}))},qq.FilenameEditHandler=function(e,t){"use strict";function n(e){var t=s.onGetName(e),n=t.lastIndexOf(".");return n>0&&(t=t.substr(0,n)),t}function i(e){var t=s.onGetName(e);return qq.getExtension(t)}function o(e,t){var n,o=e.value;void 0!==o&&qq.trimStr(o).length>0&&(n=i(t),void 0!==n&&(o=o+"."+n),s.onSetName(t,o)),s.onEditingStatusChange(t,!1)}function r(e,n){t.getDisposeSupport().attach(e,"blur",function(){o(e,n)})}function a(e,n){t.getDisposeSupport().attach(e,"keyup",function(t){13===(t.keyCode||t.which)&&o(e,n)})}var s={templating:null,log:function(e,t){},onGetUploadStatus:function(e){},onGetName:function(e){},onSetName:function(e,t){},onEditingStatusChange:function(e,t){}};qq.extend(s,e),s.attachTo=s.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(s,t)),qq.extend(t,{handleFilenameEdit:function(e,t,i){var o=s.templating.getEditInput(e);s.onEditingStatusChange(e,!0),o.value=n(e),i&&o.focus(),r(o,e),a(o,e)}})}}(window); //# sourceMappingURL=jquery.fine-uploader.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map index 06720b606..77ae5ad30 100644 --- a/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map +++ b/styles/bootstrap/fine-uploader/jquery.fine-uploader.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","rootDataKey","func","$callbackEl","args","jqueryHandlerResult","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","strBefore","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","batchId","proxyGroupId","onStatusChange","retrieve","optionalFilter","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","file","normalizeData","fileContainer","_prepareItemsForUpload","cancel","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","uploadData","_uploadData","enabled","getName","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","debug","pauseUpload","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_onDeleteComplete","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkSuccess","onResume","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","acceptIosCamera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","expunge","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","errorMessage","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","enableAuto","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","filenameParam","forceMultipart","paramsInBody","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partIndex","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","recordsExpireIn","resuming","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","onCancelRetVal","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","handlerType","traditional","handlerModuleSubtype","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","isResumable","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","_getLocalStorageId","formatVersion","_getMimeType","_getPersistableData","ceil","_markNotResumable","localStorageId","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","maxPixels","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","TAG_VAL_OFFSET","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","record","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","expectedBase64Header","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","aBuffer","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","base64test","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","setUploadHeaders","extraHeaders","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","isDirectory","getFilesInDirectory","entriesLeft","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","fileStatus","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateHtml","showThumbnails","serverScale","FILE_ID_ATTR","FILE_CLASS_PREFIX","THUMBNAIL_MAX_SIZE_ATTR","THUMBNAIL_SERVER_SCALE_ATTR","HIDE_DROPZONE_ATTR","DROPZPONE_TEXT_ATTR","IN_PROGRESS_CLASS","HIDDEN_FOREVER_CLASS","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListHtml","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n this._handler.cancel(id);\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n return this._handler.getFile(fileOrBlobId) || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var id = this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL\n });\n\n sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n this._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._netUploadedOrQueued++;\n\n return id;\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n self._options.callbacks.onUpload(id, name);\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n self._options.callbacks.onUploadChunk(id, name, chunkData);\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData) {\n return self._options.callbacks.onResume(id, name, chunkData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({uuid: uuid, name: name, size: size, batchId: batchId});\n\n this._handler.add(id, file);\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id, name, responseJSON)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n }\n else {\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id, name, responseJSON) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n params: {},\n paramsInBody: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: 2000000,\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normaizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normaizedResponse.error, \"error\");\n\n if (normaizedResponse.reset) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) {\n upload.cleanup(id, normaizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx);\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n resuming = handler._getFileState(id).attemptingResume,\n inProgressChunks = handler._getFileState(id).chunking.inProgress || [];\n\n if (handler._getFileState(id).loaded == null) {\n handler._getFileState(id).loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n else {\n handler.uploadChunk(id, chunkIdx, resuming).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function() {\n handler.clearXhr(id, chunkIdx);\n });\n }\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n handler._getFileState(id).loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name);\n\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"
tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":"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","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateHtml,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListHtml,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListHtml = fileListNode.innerHTML;\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: qq.trimStr(tempTemplateEl.innerHTML),\n fileTemplate: qq.trimStr(fileListHtml)\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateHtml = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.innerHTML = templateHtml.template;\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = qq.toElement(templateHtml.fileTemplate),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file +{"version":3,"sources":["?","../client/js/jquery-plugin.js","../client/js/jquery-dnd.js","../client/js/util.js","../client/js/export.js","../client/js/error/error.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/blob-proxy.js","../client/js/button.js","../client/js/upload-data.js","../client/js/uploader.basic.api.js","../client/js/uploader.basic.js","../client/js/ajax.requester.js","../client/js/upload-handler/upload.handler.js","../client/js/upload-handler/upload.handler.controller.js","../client/js/window.receive.message.js","../client/js/upload-handler/form.upload.handler.js","../client/js/upload-handler/xhr.upload.handler.js","../client/js/deletefile.ajax.requester.js","../client/js/image-support/megapix-image.js","../client/js/image-support/image.js","../client/js/image-support/exif.js","../client/js/identify.js","../client/js/image-support/validation.image.js","../client/js/session.js","../client/js/session.ajax.requester.js","../client/js/image-support/scaler.js","../client/js/third-party/ExifRestorer.js","../client/js/total-progress.js","../client/js/paste.js","../client/js/form-support.js","../client/js/traditional/traditional.form.upload.handler.js","../client/js/traditional/traditional.xhr.upload.handler.js","../client/js/traditional/all-chunks-done.ajax.requester.js","../client/js/dnd.js","../client/js/uploader.api.js","../client/js/uploader.js","../client/js/templating.js","../client/js/ui.handler.events.js","../client/js/ui.handler.click.filebuttons.js","../client/js/ui.handler.click.filename.js","../client/js/ui.handler.focusin.filenameinput.js","../client/js/ui.handler.focus.filenameinput.js","../client/js/ui.handler.edit.filename.js"],"names":["global","$","init","options","xformedOpts","transformVariables","newUploaderInstance","getNewUploaderInstance","uploader","addCallbacks","$el","params","uploaderType","pluginOption","namespace","charAt","toUpperCase","slice","toLowerCase","qq","FineUploader","dataStore","key","val","data","undefined","instanceToStore","option","optionVal","transformedOpts","callbacks","each","_options","prop","nonJqueryCallback","name","callbackEventTarget","exec","substring","nonJqueryCallbackRetVal","jqueryEventCallbackRetVal","originalArgs","Array","prototype","call","arguments","transformedArgs","idx","arg","push","maybeWrapInJquery","apply","this","triggerHandler","error","log","message","source","dest","xformed","arrayVals","element","inArray","pluginOptions","isPlainObject","isArray","arrayVal","arrayObjDest","merge","isValidCommand","command","type","match","delegateCommand","retVal","xformedArgs","origArgs","transformedVal","nodeType","cloneNode","fn","fineUploader","optionsOrCommand","self","selfArgs","retVals","index","el","length","jQuery","dropZoneElements","dnd","DragAndDrop","func","$callbackEl","args","fineUploaderDnd","hide","style","display","attach","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","getFirstByClass","children","child","firstChild","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","getAttribute","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","Uint8Array","character","charCodeAt","level","console","isObject","variable","Object","toString","isFunction","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","newStr","nextIdxToReplace","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","override","target","sourceFn","super_","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","Storage","getItem","bind","oldFunc","context","newArgs","concat","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome14OrHigher","isCrossOriginXhrSupported","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","BlobProxy","referenceBlob","onCreate","create","UploadButton","o","createInput","BUTTON_ID_ATTR_NAME","buttonId","title","setMultiple","folders","acceptFiles","position","right","top","fontFamily","fontSize","margin","padding","cursor","height","disposeSupport","onChange","hoverClass","focusClass","ios8BrowserCrashWorkaround","overflow","direction","getInput","getButtonId","isMultiple","optInput","removeAttribute","setAcceptFiles","reset","UploadData","uploaderProxy","getDataByIds","idOrIds","entries","id","getDataByUuids","uuids","uuid","byUuid","getDataByStatus","status","statusResults","statuses","statusEnum","statusResultIndexes","byStatus","dataIndex","byProxyGroupId","byBatchId","addFile","spec","SUBMITTING","originalName","size","file","batchId","proxyGroupId","onBeforeStatusChange","onStatusChange","retrieve","optionalFilter","removeFileRef","record","setStatus","newStatus","oldStatus","byStatusOldStatusIndex","splice","uuidChanged","newUuid","oldUuid","updateName","newName","updateSize","newSize","setParentId","targetId","parentId","getIdsInProxyGroup","getIdsInBatch","SUBMITTED","REJECTED","QUEUED","CANCELED","PAUSED","UPLOADING","UPLOAD_FINALIZING","UPLOAD_RETRYING","UPLOAD_SUCCESSFUL","UPLOAD_FAILED","DELETE_FAILED","DELETING","DELETED","basePublicApi","addBlobs","blobDataOrArray","endpoint","addFiles","addInitialFiles","cannedFileList","cannedFile","_addCannedFile","_maybeHandleIos8SafariWorkaround","_storedIds","_currentBatchId","processBlob","_handleNewFile","blobs","defaultName","verifiedFiles","processBlobData","blobData","processCanvas","processCanvasData","canvasData","normalizedQuality","processFileOrInput","fileOrInput","files","normalizeData","fileContainer","_prepareItemsForUpload","cancel","uploadData","_uploadData","getName","_handler","cancelAll","storedIdsCopy","storedFileId","clearStoredFiles","continueUpload","enabled","_uploadFile","deleteFile","_onSubmitDelete","doesExist","fileOrBlobId","isValid","drawThumbnail","fileId","imgOrCanvas","maxSize","fromServer","customResizeFunction","fileOrUrl","promiseToReturn","_imageGenerator","_thumbnailUrls","scale","getFile","container","generate","modifiedContainer","reason","getButton","_getButton","_buttonIdsForFileIds","getEndpoint","_endpointStore","get","uploadDataRecord","getInProgress","getParentId","uploadDataEntry","getUploads","getResumableFilesData","getSize","getNetUploads","_netUploaded","getRemainingAllowedItems","allowedItems","_currentItemLimit","_netUploadedOrQueued","getUuid","isResumable","hasResumeRecord","debug","pauseUpload","expunge","_autoRetries","_retryTimeouts","_preventRetries","_buttons","button","_paramsStore","_pasteHandler","session","refreshOnReset","_refreshSessionData","_succeededSinceLastAllComplete","_failedSinceLastAllComplete","_totalProgress","_customResumeDataStore","retry","_manualRetry","scaleImage","specs","Scaler","setCustomHeaders","headers","_customHeadersStore","set","setCustomResumeData","setDeleteFileCustomHeaders","_deleteFileCustomHeadersStore","setDeleteFileEndpoint","_deleteFileEndpointStore","setDeleteFileParams","_deleteFileParamsStore","setEndpoint","setForm","elementOrId","_updateFormSupportAndParams","setItemLimit","newItemLimit","setName","setParams","setUuid","_onDeleteComplete","errorMessage","uploadStoredFiles","_itemError","_uploadStoredFiles","basePrivateApi","sessionData","deleteFileEndpoint","deleteFileParams","thumbnailUrl","_annotateWithButtonId","associatedInput","qqButtonId","_getButtonId","_batchError","onError","_createDeleteHandler","DeleteFileAjaxRequester","method","maxConnections","uuidParamName","request","uuidName","customHeaders","paramsStore","endpointStore","cors","onDelete","_onDelete","onDeleteComplete","xhrOrXdr","isError","_createPasteHandler","PasteSupport","targetElement","paste","pasteReceived","_handleCheckedCallback","onPasteReceived","_handlePasteSuccess","identifier","_createStore","initialValue","_readOnlyValues_","store","catchall","perIdReadOnlyValues","readOnlyValues","copy","orig","getReadOnlyValues","includeReadOnlyValues","existing","values","addReadOnly","_createUploadDataTracker","_onUploadStatusChange","_maybeAllComplete","setTimeout","_createUploadButton","allowMultiple","workarounds","iosEmptyVideos","_isAllowedExtension","allowedExtensions","accept","validation","classes","buttonFocus","buttonHover","ios8BrowserCrash","inputName","_onInputChange","fileInputTitle","_disposeSupport","_createUploadHandler","additionalOptions","lastOnProgress","preventRetryParam","preventRetryResponseProperty","onProgress","loaded","total","_onProgress","onComplete","xhr","_onComplete","onCancel","cancelFinalizationEffort","_onCancel","onUploadPrep","_onUploadPrep","onUpload","_onUpload","onUploadResult","onUploadChunk","chunkData","_onUploadChunk","onUploadChunkResult","partIndex","onUploadChunkSuccess","_onUploadChunkSuccess","onResume","customResumeData","onAutoRetry","responseJSON","_onAutoRetry","onUuidChanged","setSize","_setSize","getDataByUuid","isQueued","isInProgress","getCustomResumeData","_getCustomResumeData","UploadHandlerController","_fileOrBlobRejected","_formatSize","sizeSymbols","max","toFixed","_generateExtraButtonSpecs","_extraButtonSpecs","extraButtons","extraButtonOptionEntry","extraButtonSpec","_initExtraButton","extraButtonsSpec","_defaultButtonId","buttonOrFileInputOrFile","inputs","fileInput","fileBlobOrInput","_getNotFinished","_getValidationBase","_getValidationDescriptor","fileWrapper","_getValidationDescriptors","fileWrappers","fileDescriptors","_handleCameraAccess","camera","optionRoot","details","callbackRetVal","successParam","newFileWrapperList","actualFile","handler","_customNewFileHandler","_handleNewFileGeneric","addFileToHandler","_trackButton","fileList","extSuppliedName","extension","_handleDeleteSuccess","_handleDeleteFailed","_initFormSupportAndParams","_formSupport","FormSupport","attachedToForm","getFormInputsAsObject","autoUpload","newAutoUpload","newEndpoint","_isDeletePossible","expected","allowXdr","allowed","valid","allowedExt","extRegex","code","maybeNameOrNames","replacement","extensionsForMessage","placeholderMatch","messages","names","validationBase","allowedExtension","formatFileName","sizeLimit","minSizeLimit","placeholder","_onBeforeManualRetry","notFinished","_onAllComplete","ios8SafariUploads","alert","unsupportedBrowserIos8Safari","_maybeParseAndSendUploadError","response","errorReason","defaultResponseError","_maybeProcessNextItemAfterOnValidateCallback","validItem","stopOnFirstInvalidFile","validationDescriptor","onValidate","_onValidateCallbackSuccess","_onValidateCallbackFailure","successful","failed","onAllComplete","_shouldAutoRetry","retryWaitPeriod","autoAttemptDelay","_onBeforeAutoRetry","itemLimit","onManualRetry","clearTimeout","storedItemIndex","fileIndex","onIndividualProgress","_onSubmit","_onSubmitCallbackSuccess","_onSubmitted","onSubmitted","_storeForLater","onSuccessCallback","additionalMandatedParams","adjustedOnSuccessCallback","onSubmitDelete","_deleteHandler","sendDelete","_onTotalProgress","onTotalProgress","enableAuto","_onValidateBatchCallbackFailure","_onValidateBatchCallbackSuccess","validationDescriptors","proposedNetFilesUploadedOrQueued","tooManyItemsError","nextIndex","_validateFileOrBlobData","_upload","onValidateBatch","_preventLeaveInProgress","event","onLeave","Session","_session","addFileRecord","refresh","_sessionRequestComplete","onSessionRequestComplete","onNewSize","maxAutoAttempts","formElementOrId","onSubmit","idToUpload","stillSubmitting","validityChecker","allowEmpty","ImageValidation","validate","image","errorCode","_wrapCallbacks","safeCallback","errorMsg","exception","callbackName","callbackFunc","FineUploaderBasic","disableCancelForFormUploads","warnBeforeUnload","filenameParam","forceMultipart","omitDefaultParams","paramsInBody","requireSuccessJson","totalFileSizeName","maxHeight","maxWidth","minHeight","minWidth","maybeXhr","maybeXhrOrXdr","attemptNumber","fileOrBlobData","typeError","sizeError","minSizeError","emptyError","noFilesError","maxHeightImageError","maxWidthImageError","minHeightImageError","minWidthImageError","retryFailTooManyItems","concurrent","mandatory","paramNames","partByteOffset","chunkSize","totalFileSize","totalParts","partSize","jsonPayload","resetOnStatus","recordsExpireIn","resuming","customKeys","fileOrBlobName","sendCredentials","interceptSubmit","customResizer","sendOriginal","orient","defaultType","defaultQuality","failureText","includeExif","sizes","ImageGenerator","_scaler","handleNewFile","TotalProgress","entry","AjaxRequester","isSimpleMethod","containsNonSimpleHeaders","containsNonSimple","header","isXdr","getCorsAjaxTransport","ontimeout","onprogress","getXhrOrXdr","suppliedXhr","requestData","dequeue","nextId","queue","sendRequest","xdrError","isResponseSuccessful","getParams","onDemandParams","additionalParams","mandatedParams","optXhr","url","payload","onSend","createUrl","additionalQueryParams","getXdrLoadHandler","getXdrErrorHandler","onreadystatechange","getXhrReadyStateChangeHandler","registerForUploadProgress","open","setHeaders","send","shouldParamsBeInQueryString","contentType","stringify","addToPath","readyState","lengthComputable","onDemandHeaders","additionalHeaders","allHeaders","acceptHeader","setRequestHeader","allowXRequestedWithAndCacheControl","responseCode","successfulResponseCodes","prepareToSend","validMethods","DELETE","PATCH","POST","PUT","GET","initTransport","path","cacheBuster","withPath","appendToPath","withParams","withQueryParams","_additionalQueryParams_","withHeaders","withPayload","thePayload","withCacheBuster","qqtimestamp","Date","getTime","canceled","UploadHandler","proxy","fileState","fileItem","getThirdPartyFileId","_getFileState","_setThirdPartyFileId","thirdPartyFileId","_wasCanceled","preventRetryResponse","controller","chunkingPossible","concurrentChunkingPossible","chunked","chunkIdx","_getChunkData","attemptingResume","chunkProgress","_getChunkDataForCallback","finalize","finalizeChunks","normaizedResponse","normalizeResponse","_maybeDeletePersistedChunkData","cleanup","normalizedResponse","handleFailure","clearCachedChunk","inProgressIdx","responseToReport","inProgressChunksArray","inProgress","remaining","unshift","ignoreFailure","keys","_getXhrs","ckid","ckXhr","abort","_cancelled","moveInProgressToRemaining","connectionManager","free","hasMoreParts","nextPart","nextIdx","_getTotalChunks","reevaluateChunking","sendNext","inProgressChunks","available","requestOverrides","uploadChunkData","overrides","uploadChunk","inProgressChunkIdx","_maybePersistChunkedState","clearXhr","_open","_openChunks","_waiting","openChunkEntriesCount","openChunksCount","openChunkIndexes","dontAllowNext","allowNext","waitingIndex","connectionsIndex","getProxyOrBlob","getWaitingOrConnected","waitingOrConnected","chunks","parseInt","isUsingConnection","pop","openChunksEntry","simple","uploadFile","maybeNewUuid","_clearXhrs","getProxy","initHandler","traditional","onFinalizing","_removeExpiredChunkingRecords","isDeferredEligibleForUpload","maybeDefer","generatedBlob","updateBlob","maybeSendDeferredFiles","errorResponse","idsInGroup","uploadedThisId","idInGroup","now","originalResponse","_shouldChunkThisFile","blobToUpload","cancelRetVal","isProxied","_getLocalStorageId","isAttemptingResume","WindowReceiveMessage","callbackWrapperDetachers","receiveMessage","onMessageCallbackWrapper","stopReceivingMessages","detacher","FormUploadHandler","expungeFile","detachLoadEvents","isCors","postMessageCallbackTimers","corsMessageReceiver","iframe","getElementById","_getIframeName","getFileIdForIframeName","iframeName","initIframeForUpload","body","registerPostMessageCallback","onloadCallbacks","onloadCallback","_parseJsonResponse","_detachLoadEvent","formHandlerInstanceId","_attachLoadEvent","responseDescriptor","contentDocument","_createIframe","_initFormForUpload","targetName","innerHtmlOrMessage","XhrUploadHandler","xhrId","ajaxRequester","_getAjaxRequester","getChunkSize","chunkFiles","resumeEnabled","blobOrProxy","_initTempState","_maybePrepareForResume","cachedChunks","tempState","xhrs","ajaxRequesters","responseParser","lastChunkIdx","_getXhr","resumableFilesData","_iterateResumeRecords","notResumable","optInProgress","optRemaining","chunkingState","reverse","paused","totalChunks","parts","newBlob","chunkId","_createXhr","optChunkIdx","_registerXhr","chunkIndex","fileSize","startBytes","endBytes","part","count","startByte","endByte","localStorageId","forEach","_getMimeType","_getPersistableData","ceil","_markNotResumable","removeItem","persistedData","lastUpdated","_registerProgressHandler","progressCalculator","totalSuccessfullyLoadedForFile","loadedForRequest","totalForRequest","estActualChunkLoaded","totalLoadedForFile","chunkLoaded","optAjaxRequester","xhrsId","expirationDays","expirationDate","setDate","getDate","getMandatedParams","_method","requester","detectSubsampling","img","ctx","iw","naturalWidth","ih","naturalHeight","width","getContext","drawImage","getImageData","detectVerticalSquash","alpha","ratio","sy","ey","py","renderImageToDataURL","doSquash","renderImageToCanvas","maybeCalculateDownsampledDimensions","origHeight","origWidth","newHeight","sqrt","newWidth","modifiedDimensions","save","resize","renderImageToCanvasWithCustomResizer","imageHeight","imageWidth","orientation","targetHeight","targetWidth","transformCoordinate","tmpCtx","sx","dx","d","tmpCanvas","vertSquashRatio","dw","dh","dy","clearRect","restore","qqImageRendered","resizeInfo","sourceCanvas","sourceCanvasContext","targetCanvas","translate","rotate","PI","MegaPixImage","srcImage","errorCallback","Image","URL","createObjectURL","webkitURL","src","listeners","imageLoadListeners","render","opt","imgWidth","imgHeight","optionsKey","optionsValue","oldTargetSrc","onrender","isImg","isCanvas","isImgCorsSupported","crossOrigin","isCanvasSupported","determineMimeOfFileName","nameWithPath","pathSegments","isCrossOrigin","targetProtocol","targetHostname","targetPort","targetAnchor","href","protocol","port","hostname","location","registerImgLoadListeners","registerCanvasDrawImageListener","registerThumbnailRenderedListener","registered","draw","drawPreview","Identify","megapixErrorHandler","isPreviewable","dummyExif","exif","Exif","mpImg","Orientation","failureMsg","drawOnCanvasOrImgFromUrl","canvasOrImg","tempImg","tempImgRender","drawOnImgFromUrlWithCssScaling","drawFromUrl","fileBlobOrUrl","_testing","parseLittleEndian","hex","pow","seekToApp1","offset","theOffset","thePromise","segmentLength","getApp1Offset","isLittleEndian","app1Start","getDirEntryCount","littleEndian","getIfd","dirEntries","getDirEntries","ifdHex","getTagValues","tagsToFind","TAG_IDS","vals","tagValHex","tagValLength","idHex","tagsToFindIdx","TAG_INFO","274","parser","onParseFailure","app1Offset","dirEntryCount","tagValues","isIdentifiable","magicBytes","questionableBytes","identifiable","magicBytesEntries","magicBytesArrayEntry","previewable","isPreviewableSync","PREVIEWABLE_MIME_TYPES","fileMime","isRecognizedImage","image/jpeg","image/gif","image/png","image/bmp","image/tiff","hasNonZeroLimits","limits","atLeastOne","limit","getWidthHeight","sizeDetermination","getFailingLimit","dimensions","failingLimit","limitName","limitValue","limitMatcher","dimensionPropName","actualValue","validationEffort","isJsonResponseValid","handleFileItems","fileItems","someItemsIgnored","err","refreshEffort","refreshCompleteCallback","requesterOptions","SessionAjaxRequester","queryServer","responseText","includeOriginal","failedToScaleText","_getSortedSizes","getFileRecords","originalFileUuid","originalFileName","originalBlobOrBlobData","records","originalBlob","sizeRecord","outputType","_determineOutputType","requestedType","refType","_getName","_generateScaledImage","failedText","api","scaledIds","originalId","blobSize","scaledId","qqparentuuid","qqparentsize","param","scalingEffort","scalingOptions","scaler","referenceType","scaledVersionProperties","startOfExt","versionType","scaledName","scaledExt","nameAppendage","sort","a","b","sourceFile","imageGenerator","scaledImageDataUri","signalSuccess","_insertExifHeader","scaledImageDataUriWithExif","originalImage","reader","insertionEffort","originalImageDataUri","ExifRestorer","readAsDataURL","_dataUriToBlob","_createBlob","KEY_STR","encode64","chr1","chr2","enc1","enc2","enc3","output","chr3","enc4","isNaN","origFileBase64","resizedFileBase64","rawImage","decode64","segments","slice2Segments","exifManipulation","exifArray","getExifArray","newImageArray","insertExif","seg","x","imageData","buf","separatePoint","mae","ato","array","rawImageArray","head","endPoint","perFileProgress","totalLoaded","totalSize","lastLoadedSent","lastTotalSent","callbackProxy","noRetryableFiles","retryable","none","failedId","updateTotalProgress","onNew","newLoaded","newTotal","oldLoaded","oldTotal","isImage","registerPasteHandler","detachPasteHandler","clipboardData","getAsFile","unregisterPasteHandler","startUpload","determineNewEndpoint","formEl","validateForm","nativeSubmit","checkValidity","maybeUploadOnSubmit","submit","determineFormEl","_form2Obj","notIrrelevantType","irrelevantTypes","radioOrCheckbox","ignoreValue","checked","selectValue","select","selected","elements","getIframeContentJson","doc","innerHtml","contentWindow","nodeValue","createForm","responseFromMessage","multipart","addChunkingSpecificParams","allChunksDoneRequester","AllChunksDoneAjaxRequester","createReadyStateChangedHandler","onUploadOrChunkComplete","getChunksCompleteParams","isErrorUploadResponse","parseResponse","sendChunksCompleteRequest","complete","setParamsAndGetEntityToSend","entityToSendParams","xhrOverrides","customParams","defaultParams","xhrOverrideParams","setUploadHeaders","headersOptions","headerOverrides","headerName","headerValue","extraHeaders","uploadChunkParams","toSend","promises","endpointHandler","uploadDroppedFiles","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","parseEntryPromise","qqPath","extractDirectoryPath","droppedFiles","fileError","fullPath","isDirectory","getFilesInDirectory","entriesLeft","indexOfNameInFullPath","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","includes","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","dispatchEvent","attachEvents","effect","relatedTarget","elementFromPoint","clientX","clientY","uiPublicApi","_parent","_templating","addCacheToDom","clearFiles","addExtraDropzone","_dnd","removeExtraDropzone","getItemByFileId","isHiddenForever","getFileContainer","_setupDragAndDrop","_totalFilesInBatch","_filesInBatchAddedToUi","_setupClickAndEditEventHandlers","formattedFilename","updateFilename","uploadPaused","continued","uploadContinued","getId","fileContainerOrChildEl","getFileId","getDropTarget","qqDropTarget","uiPrivateApi","_removeFileItem","removeFile","_fileButtonsClickHandler","FileButtonsClickHandler","_bindFileButtonsClickEvent","_focusinEventSupported","_isEditFilenameEnabled","_filenameClickHandler","_bindFilenameClickEvent","_filenameInputFocusInHandler","_bindFilenameInputFocusInEvent","_filenameInputFocusHandler","_bindFilenameInputFocusEvent","dragAndDrop","extraDropzones","templating","defaultDropZone","getDropZone","showDropProcessing","hideDropProcessing","errorData","lvl","onDeleteFile","onRetry","onPause","onContinue","onGetName","isEditFilenamePossible","FilenameClickHandler","FilenameInputFocusHandler","_filenameEditHandler","onGetUploadStatus","onSetName","onEditingStatusChange","isEditing","qqInput","getEditInput","qqFileContainer","hideFilename","hideEditIcon","showFilename","showEditIcon","markFilenameEditable","hideRetry","setStatusText","_classes","retrying","hidePause","FilenameInputFocusInHandler","hideSpinner","resetTotalProgress","reportDirectoryPaths","qqpath","_addToList","addHandler","updateProgress","hideCancel","hideProgress","waitingForResponse","_displayFileSize","completeUpload","_markFileAsSuccessful","fail","showCancel","isRetryPossible","showRetry","_controlFailureTextDisplay","parentRetVal","newResult","showDeleteButton","_maybeUpdateThumbnail","showSpinner","allowPause","retryNumForDisplay","maxAuto","retryNote","_showCancelLink","showAutoRetryNote","autoRetryNote","resetProgress","_onSubmitDeleteSuccess","forceConfirm","_showDeleteConfirm","_sendDeleteRequest","deletingFailedText","hideDeleteButton","deletingStatusText","confirmMessage","deleteRequestArgs","showConfirm","canned","prependData","prependIndex","dontDisplay","hideScaled","prependFiles","disableCancel","_handledProxyGroup","_clearList","addFileToCache","updateThumbnail","thumbnails","generatePreview","fileSizeOnSubmit","loadedSize","sizeForDisplay","_formatProgress","uploadedSize","formatProgress","mode","responseProperty","failureReason","failedUploadTextDisplay","failUpload","enableTooltip","_showTooltip","showMessage","_setupPastePrompt","namePromptMessage","defaultVal","showPrompt","placeholders","waitUntilResponse","listElement","template","editable","tooManyFilesError","unsupportedBrowser","promptForName","maxCount","notAvailablePath","waitingPath","timeBetweenThumbs","hasDialog","showDialog","confirm","defaultValue","prompt","Templating","templateIdOrEl","containerEl","fileContainerEl","maxThumbs","waitUntilUpdate","thumbnailNotAvailable","waitingForThumbnail","renderFailure","isEditElementsExist","isRetryElementExist","templateDom","showThumbnails","serverScale","fileBatch","content","createDocumentFragment","map","isCancelDisabled","generatedThumbnails","thumbnailQueueMonitorRunning","thumbGenerationQueue","thumbnailMaxSize","selectorClasses","alertDialog","dialogCancelButton","confirmDialog","dialogMessage","dialogOkButton","promptDialog","drop","list","progressBarContainer","totalProgressBarContainer","totalProgressBar","spinner","continueButton","deleteButton","statusText","editFilenameInput","editNameIcon","dropText","dropProcessing","dropProcessingSpinner","thumbnail","previewGeneration","cachedThumbnailNotAvailableImg","cachedWaitingForThumbnailImg","cacheThumbnailPlaceholders","notAvailableUrl","waitingUrl","updatedImg","displayWaitingImg","waitingImgPlacement","maybeScalePlaceholderViaCss","show","generateNewPreview","getThumbnail","qqThumbnailId","maybeSetDisplayNotAvailableImg","generateNextQueuedPreview","queuedThumbRequest","update","processUpdateQueuedPreviewRequest","processNewQueuedPreviewRequest","getCancel","getTemplateEl","getContinue","getDialog","getDelete","getDropProcessing","getEditIcon","getPause","getProgress","getRetry","getSpinner","cssClass","previewing","notAvailableImgPlacement","parseAndGetTemplate","scriptEl","scriptHtml","fileListNode","tempTemplateEl","fileListEl","defaultButton","dropTextEl","uploaderEl","fileTemplate","prependFile","parentEl","beforeEl","optFileOrBlob","relatedThumbnailId","useCachedPreview","showWaitingImg","setProgressBarWidth","percent","bar","progressBarSelector","targetThumbnailId","cachedThumbnailId","targetThumbnail","cachedThumbnail","hideTotalProgress","cantRenderEl","prependInfo","hideForever","batch","thumb","fileEl","fileNameEl","waitingImg","currentNode","getFileList","filenameEl","isFileName","icon","isEditIcon","isEditInput","isCancel","allowContinueButton","isPause","isContinueButton","isDeleteButton","isRetry","textEl","dialog","messageEl","inputEl","cancelBtn","okBtn","closeHandler","cancelClickHandler","okClickHandler","close","showModal","UiEventHandler","s","protectedApi","eventType","srcElement","onHandled","attachTo","getFileIdFromItem","qqFileId","getDisposeSupport","examineEvent","buttonHandlers","buttonType","firstLetterCapButtonType","inheritedInternalApi","handleFilenameEdit","FilenameEditHandler","handleInputFocus","getFilenameSansExtension","filenameSansExt","getOriginalExtension","origName","handleNameUpdate","newFilenameInputEl","origExtension","registerInputBlurHandler","registerInputEnterKeyHandler","keyCode","which","focusInput","focus"],"mappings":";CAAA,SAAUA,SCCT,SAASC,GACN,YAIA,SAASC,GAAKC,GACV,GAAIC,GAAcC,EAAmBF,OACjCG,EAAsBC,EAAuBH,EAKjD,OAHAI,GAASF,GACTG,EAAaL,EAAaE,GAEnBI,EAGX,QAASH,GAAuBI,GAC5B,GAAIC,GAAeC,EAAa,gBAC5BC,EAAYD,EAAa,eAG7B,OAAID,IAGAA,EAAeA,EAAaG,OAAO,GAAGC,cAAgBJ,EAAaK,MAAM,GAAGC,cAExEJ,EACO,GAAIK,IAAGL,GAAW,eAAiBF,GAAcD,GAGrD,GAAIQ,IAAG,eAAiBP,GAAcD,IAGzCG,EACO,GAAIK,IAAGL,GAAWM,aAAaT,GAGnC,GAAIQ,IAAGC,aAAaT,GAInC,QAASU,GAAUC,EAAKC,GACpB,GAAIC,GAAOd,EAAIc,KAAK,eAEpB,KAAID,EAQA,MAAaE,UAATD,EACO,KAEJA,EAAKF,EAVCG,UAATD,IACAA,MAEJA,EAAKF,GAAOC,EACZb,EAAIc,KAAK,eAAgBA,GAYjC,QAAShB,GAASkB,GACd,MAAOL,GAAU,WAAYK,GAGjC,QAASb,GAAac,EAAQC,GAC1B,MAAOP,GAAUM,EAAQC,GAK7B,QAASnB,GAAaoB,EAAiBvB,GACnC,GAAIwB,GAAYD,EAAgBC,YAEhC7B,GAAE8B,KAAKzB,EAAoB0B,SAASF,UAAW,SAASG,EAAMC,GAC1D,GAAIC,GAAMC,CAEVD,GAAO,WAAWE,KAAKJ,GAAM,GAC7BE,EAAOA,EAAKG,UAAU,EAAG,GAAGpB,cAAgBiB,EAAKG,UAAU,GAC3DF,EAAsB1B,EAEtBoB,EAAUG,GAAQ,WACd,GAEIM,GAAyBC,EAFzBC,EAAeC,MAAMC,UAAU1B,MAAM2B,KAAKC,WAC1CC,IAGJ7C,GAAE8B,KAAKU,EAAc,SAASM,EAAKC,GAC/BF,EAAgBG,KAAKC,EAAkBF,MAG3CT,EAA0BL,EAAkBiB,MAAMC,KAAMX,EAExD,KACID,EAA4BJ,EAAoBiB,eAAelB,EAAMW,GAEzE,MAAOQ,GACHnC,GAAGoC,IAAI,uDAAyDD,EAAME,QAAS,SAInF,MAA+B,OAA3BjB,EACOA,EAEJC,KAIflC,EAAoB0B,SAASF,UAAYA,EAI7C,QAASzB,GAAmBoD,EAAQC,GAChC,GAAIC,GAASC,CAgDb,IA5CQD,EAFKlC,SAATiC,EAC4B,UAAxBD,EAAO7C,cACKiD,QAASnD,EAAI,OAOnBgD,EAGdzD,EAAE8B,KAAK0B,EAAQ,SAASxB,EAAMV,GACtBtB,EAAE6D,QAAQ7B,EAAM8B,IAAkB,EAClClD,EAAaoB,EAAMV,GAEdA,YAAetB,GACpB0D,EAAQ1B,GAAQV,EAAI,GAEftB,EAAE+D,cAAczC,IACrBoC,EAAQ1B,MACR5B,EAAmBkB,EAAKoC,EAAQ1B,KAE3BhC,EAAEgE,QAAQ1C,IACfqC,KACA3D,EAAE8B,KAAKR,EAAK,SAASwB,EAAKmB,GACtB,GAAIC,KAEAD,aAAoBjE,GACpBA,EAAEmE,MAAMR,EAAWM,GAEdjE,EAAE+D,cAAcE,IACrB7D,EAAmB6D,EAAUC,GAC7BP,EAAUX,KAAKkB,IAGfP,EAAUX,KAAKiB,KAGvBP,EAAQ1B,GAAQ2B,GAGhBD,EAAQ1B,GAAQV,IAIXE,SAATiC,EACA,MAAOC,GAIf,QAASU,GAAeC,GACpB,MAA2B,WAApBrE,EAAEsE,KAAKD,KACTA,EAAQE,MAAM,OACS/C,SAAxBjB,IAAW8D,GAKnB,QAASG,GAAgBH,GACrB,GAEII,GAFAC,KACAC,EAAWlC,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAOrD,OAJAxC,GAAmBuE,EAAUD,GAE7BD,EAASlE,IAAW8D,GAASnB,MAAM3C,IAAYmE,GAExCzB,EAAkBwB,GAI7B,QAASxB,GAAkB3B,GACvB,GAAIsD,GAAiBtD,CAUrB,OANW,OAAPA,GAA8B,gBAARA,IACL,IAAjBA,EAAIuD,UAAmC,IAAjBvD,EAAIuD,WAAmBvD,EAAIwD,YAEjDF,EAAiB5E,EAAEsB,IAGhBsD,EAlMX,GAAInE,GACAqD,GAAiB,eAAgB,eAoMrC9D,GAAE+E,GAAGC,aAAe,SAASC,GACzB,GAAIC,GAAO/B,KAAMgC,EAAWvC,UAAWwC,IAoBvC,OAlBAjC,MAAKrB,KAAK,SAASuD,EAAOC,GAGtB,GAFA7E,EAAMT,EAAEsF,GAEJ/E,KAAc6D,EAAea,IAG7B,GAFAG,EAAQpC,KAAKwB,EAAgBtB,MAAMgC,EAAMC,IAErB,IAAhBD,EAAKK,OACL,OAAO,MAGsB,gBAArBN,IAAkCA,EAI9CjF,EAAEqD,MAAM,UAAa4B,EAAmB,0CAHxChF,EAAKiD,MAAMgC,EAAMC,KAOF,IAAnBC,EAAQG,OACDH,EAAQ,GAEVA,EAAQG,OAAS,EACfH,EAGJjC,OAGbqC,QCtOD,SAASxF,GACN,YAIA,SAASC,GAAKC,GACLA,IACDA,MAGJA,EAAQuF,kBAAoBhF,EAC5B,IAAIN,GAAcC,EAAmBF,EAIrC,OAHAM,GAAaL,GACbuF,EAAI,GAAIxE,IAAGyE,YAAYxF,IAEhBM,EAGX,QAASW,GAAUC,EAAKC,GACpB,GAAIC,GAAOd,EAAIc,KAjBD,kBAmBd,KAAID,EAQA,MAAaE,UAATD,EACO,KAEJA,EAAKF,EAVCG,UAATD,IACAA,MAEJA,EAAKF,GAAOC,EACZb,EAAIc,KAxBM,kBAwBYA,GAU9B,QAASmE,GAAIjE,GACT,MAAOL,GAAU,cAAeK,GAGpC,QAASjB,GAAaoB,GAClB,GAAIC,GAAYD,EAAgBC,YAEhC7B,GAAE8B,KAAK,GAAIZ,IAAGyE,YAAY9D,UAAa,SAASG,EAAM4D,GAClD,GACIC,GADA3D,EAAOF,CAGX6D,GAAcpF,EAEdoB,EAAUG,GAAQ,WACd,GAAI8D,GAAOrD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAGtC,OAF0BiD,GAAYzC,eAAelB,EAAM4D,MAQvE,QAAS1F,GAAmBoD,EAAQC,GAChC,GAAIC,GAASC,CAkCb,IA/BID,EADSlC,SAATiC,KAIUA,EAGdzD,EAAE8B,KAAK0B,EAAQ,SAASxB,EAAMV,GACtBA,YAAetB,GACf0D,EAAQ1B,GAAQV,EAAI,GAEftB,EAAE+D,cAAczC,IACrBoC,EAAQ1B,MACR5B,EAAmBkB,EAAKoC,EAAQ1B,KAE3BhC,EAAEgE,QAAQ1C,IACfqC,KACA3D,EAAE8B,KAAKR,EAAK,SAASwB,EAAKmB,GAClBA,YAAoBjE,GACpBA,EAAEmE,MAAMR,EAAWM,GAGnBN,EAAUX,KAAKiB,KAGvBP,EAAQ1B,GAAQ2B,GAGhBD,EAAQ1B,GAAQV,IAIXE,SAATiC,EACA,MAAOC,GAIf,QAASU,GAAeC,GACpB,MAA2B,WAApBrE,EAAEsE,KAAKD,IACE,YAAZA,GACmB7C,SAAnBkE,IAAMrB,GAGd,QAASG,GAAgBH,GACrB,GAAIK,KAEJ,OADAtE,GADiCqC,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,GAC1C8B,GACtBgB,IAAMrB,GAASnB,MAAMwC,IAAOhB,GA1GvC,GACIjE,EA4GJT,GAAE+E,GAAGgB,gBAAkB,SAASd,GAC5B,GAAIC,GAAO/B,KAAMgC,EAAWvC,UAAWwC,IAoBvC,OAlBAjC,MAAKrB,KAAK,SAASuD,EAAOC,GAGtB,GAFA7E,EAAMT,EAAEsF,GAEJI,KAAStB,EAAea,IAGxB,GAFAG,EAAQpC,KAAKwB,EAAgBtB,MAAMgC,EAAMC,IAErB,IAAhBD,EAAKK,OACL,OAAO,MAGsB,gBAArBN,IAAkCA,EAI9CjF,EAAEqD,MAAM,UAAa4B,EAAmB,kDAHxChF,EAAKiD,MAAMgC,EAAMC,KAOF,IAAnBC,EAAQG,OACDH,EAAQ,GAEVA,EAAQG,OAAS,EACfH,EAGJjC,OAGbqC,OC7IF,IAAItE,IAAK,SAAS0C,GACd,YAEA,QACIoC,KAAM,WAEF,MADApC,GAAQqC,MAAMC,QAAU,OACjB/C,MAIXgD,OAAQ,SAAS7B,EAAMS,GAMnB,MALInB,GAAQwC,iBACRxC,EAAQwC,iBAAiB9B,EAAMS,GAAI,GAC5BnB,EAAQyC,aACfzC,EAAQyC,YAAY,KAAO/B,EAAMS,GAE9B,WACH7D,GAAG0C,GAAS0C,OAAOhC,EAAMS,KAIjCuB,OAAQ,SAAShC,EAAMS,GAMnB,MALInB,GAAQ2C,oBACR3C,EAAQ2C,oBAAoBjC,EAAMS,GAAI,GAC/BnB,EAAQyC,aACfzC,EAAQ4C,YAAY,KAAOlC,EAAMS,GAE9B5B,MAGXsD,SAAU,SAASC,GAKf,QAAKA,IAKD9C,IAAY8C,IAIZ9C,EAAQ6C,SACD7C,EAAQ6C,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwB/C,OAOrDgD,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAahD,EAASiD,GACnC1D,MAGX4D,OAAQ,WAEJ,MADAnD,GAAQkD,WAAWE,YAAYpD,GACxBT,MAOX8D,IAAK,SAASC,GAEV,GAAqB,MAAjBtD,EAAQqC,MACR,KAAM,IAAI/E,IAAGiG,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1BxD,GAAQqC,MAAMmB,SAAqD,SAArBxD,EAAe,UACpEsD,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9ElG,GAAGsG,OAAO5D,EAAQqC,MAAOiB,GAElB/D,MAGXsE,SAAU,SAASvF,EAAMwF,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAU1F,EAAO,QACrC,OAAOyF,GAAGE,KAAKjE,EAAQkE,eAAiBJ,IAAkBC,EAAGE,KAAKjE,EAAQkD,WAAWgB,aAGzFC,SAAU,SAAS7F,GAIf,MAHKhB,IAAG0C,GAAS6D,SAASvF,KACtB0B,EAAQkE,WAAa,IAAM5F,GAExBiB,MAGX6E,YAAa,SAAS9F,GAClB,GAAIyF,GAAK,GAAIC,QAAO,QAAU1F,EAAO,QAErC,OADA0B,GAAQkE,UAAYlE,EAAQkE,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtE9E,MAGX+E,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASvE,EAAQ0E,cACV1E,EAAQ0E,cAAc,IAAMR,GAE9BlE,EAAQ2E,iBACN3E,EAAQ2E,iBAAiB,IAAMT,IAG1CM,EAAaxE,EAAQ4E,qBAAqB,KAE1CtH,GAAGY,KAAKsG,EAAY,SAAStF,EAAKxB,GAC1BJ,GAAGI,GAAKmG,SAASK,IACjBO,EAAOrF,KAAK1B,KAGb6G,EAAQE,EAAO,GAAKA,IAG/BI,gBAAiB,SAASX,GACtB,MAAO5G,IAAG0C,GAASsE,WAAWJ,GAAW,IAG7CY,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQ/E,EAAQgF,WAEbD,GACoB,IAAnBA,EAAM9D,UACN6D,EAAS1F,KAAK2F,GAElBA,EAAQA,EAAME,WAGlB,OAAOH,IAGXI,QAAS,SAASC,GAGd,MAFAnF,GAAQoF,UAAYD,EACpBnF,EAAQqF,YAAcF,EACf5F,MAGX+F,UAAW,WACP,MAAOhI,IAAG0C,GAASkF,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAIzF,GAAQuF,eAEHvF,EAAQuF,aAAaC,IAKkC,MAArD,WAAahH,KAAKwB,EAAQ0F,aAAaF,KAG9CC,EAAUzF,EAAQwF,GAEF5H,SAAZ6H,GAKiC,MAA9B,WAAajH,KAAKiH,QAMxC,WACG,YAEAnI,IAAGqI,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAOxI,IAAGyI,cAAcH,EAAOI,UAAUH,EAAMC,KAGnDxI,GAAGyI,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAAS3I,EAAMkI,GACxB,GAAIU,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOlJ,GACZiJ,EAAYE,QAAQjB,IAGpB,GAAIkB,OAAMpJ,IAAQ+C,KAAMmF,IAyB3C,OAlBIM,GADAF,EAAQe,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKjB,EAAQe,MAAM,KAAK,IAGxBG,UAAUlB,EAAQe,MAAM,KAAK,IAI9CX,EAAaJ,EAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBd,EAAc,GAAIkB,aAAYjB,EAAWxE,QACzCyE,EAAW,GAAIiB,YAAWnB,GAC1B5I,GAAGY,KAAKiI,EAAY,SAASjH,EAAKoI,GAC9BlB,EAASlH,GAAOoI,EAAUC,WAAW,KAGlCjB,EAAWJ,EAAaG,IAGnC/I,GAAGoC,IAAM,SAASC,EAAS6H,GACnBhB,OAAOiB,UACFD,GAAmB,SAAVA,EAKNhB,OAAOiB,QAAQD,GACfhB,OAAOiB,QAAQD,GAAO7H,GAGtB6G,OAAOiB,QAAQ/H,IAAI,IAAM8H,EAAQ,KAAO7H,GAR5C6G,OAAOiB,QAAQ/H,IAAIC,KAc/BrC,GAAGoK,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAAS1G,UAAyD,oBAA7C2G,OAAO9I,UAAU+I,SAAS9I,KAAK4I,IAG5ErK,GAAGwK,WAAa,SAASH,GACrB,MAA6B,kBAAf,IASlBrK,GAAG8C,QAAU,SAAS2H,GAClB,MAAiD,mBAA1CH,OAAO9I,UAAU+I,SAAS9I,KAAKgJ,IACjCA,GAASvB,OAAOY,aAAeW,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBb,aAIrF9J,GAAG4K,WAAa,SAASC,GACrB,MAAyD,kCAAlDP,OAAO9I,UAAU+I,SAAS9I,KAAKoJ,IAK1C7K,GAAG8K,WAAa,SAASC,GACrB,MAAyD,sBAAlDT,OAAO9I,UAAU+I,SAAS9I,KAAKsJ,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CjL,GAAGkL,SAAW,SAASC,GACnB,MAAuD,oBAAhDb,OAAO9I,UAAU+I,SAAS9I,KAAK0J,IAG1CnL,GAAGoL,QAAU,SAASC,GAClB,MAAIC,QAAO9J,UAAU+J,KACVF,EAAOE,OAGXF,EAAOtE,QAAQ,aAAc,KAOxC/G,GAAGwL,OAAS,SAASC,GAEjB,GAAI7G,GAAQrD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,GAC9CgK,EAASD,EACTE,EAAmBD,EAAO/B,QAAQ,KAetC,OAbA3J,IAAGY,KAAKgE,EAAM,SAAShD,EAAKxB,GAQxB,GAJAsL,EAHgBA,EAAOvK,UAAU,EAAGwK,GAGfvL,EAFNsL,EAAOvK,UAAUwK,EAAmB,GAGnDA,EAAmBD,EAAO/B,QAAQ,KAAMgC,EAAmBvL,EAAIiE,QAG3DsH,EAAmB,EACnB,OAAO,IAIRD,GAGX1L,GAAG4L,OAAS,SAASC,GACjB,MAAO3C,QAAO4C,MAAsD,kBAA9CxB,OAAO9I,UAAU+I,SAAS9I,KAAKoK,IAGzD7L,GAAG+L,WAAa,SAASC,GACrB,MAAO9C,QAAO+C,UAA8D,sBAAlD3B,OAAO9I,UAAU+I,SAAS9I,KAAKuK,IAG7DhM,GAAGkM,cAAgB,SAASC,GACxB,MAAOnM,IAAG4L,OAAOO,IAAqBnM,GAAGoM,QAAQD,IAGrDnM,GAAGoM,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAASnJ,GACxB,GAAIoJ,GAAiBpJ,EAAKrD,aAE1B,OAAIuM,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAItD,OAAOuD,kBAC4C,8BAA/CnC,OAAO9I,UAAU+I,SAAS9I,KAAK4K,IAC3BA,EAAWjJ,MAAQmJ,EAAaF,EAAWjJ,WAKnDiJ,EAAWK,SAC8B,UAArCL,EAAWK,QAAQ3M,eACfsM,EAAWjJ,MAAQmJ,EAAaF,EAAWjJ,QAS3DpD,GAAG2M,OAAS,SAASC,GACjB,GAAI1D,OAAOO,MAAsD,kBAA9Ca,OAAO9I,UAAU+I,SAAS9I,KAAKmL,GAC9C,OAAO,GAIf5M,GAAG6M,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAM1J,KAAO,OAGU9C,SAAnBwM,EAAMG,UACc,mBAATnB,OACa,mBAAboB,WACoC,SAAnClN,GAAGmN,oBAAqBC,QAI5CpN,GAAGmN,kBAAoB,WACnB,GAAIjE,OAAOmE,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOnL,GAEH,MADAnC,IAAGoC,IAAI,wCAAyC,SACzC,OAIfpC,GAAGuN,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMpJ,OAAS,GAC5BmJ,EAAaC,MAAM,GAAGC,kBAG9B1N,GAAG2N,wBAA0B,WACzB,OAAQ3N,GAAG4N,gBACP5N,GAAG6M,yBACuBvM,SAAzBwL,KAAKtK,UAAU1B,OAAsDQ,SAA/BwL,KAAKtK,UAAUqM,aAAyDvN,SAA5BwL,KAAKtK,UAAUsM,WAG1G9N,GAAG+N,UAAY,SAASC,EAAYC,EAAOC,GAGvC,OAFaF,EAAWlO,OAASkO,EAAWF,UAAYE,EAAWH,aAErDpM,KAAKuM,EAAYC,EAAOC,IAG1ClO,GAAGmO,iBAAmB,SAASzD,GAC3B,GAAI0D,GAAa,GACbC,EAAQ,GAAItE,YAAWW,EAY3B,OAVA1K,IAAGY,KAAKyN,EAAO,SAASzM,EAAK0M,GACzB,GAAIC,GAAeD,EAAI/D,SAAS,GAE5BgE,GAAalK,OAAS,IACtBkK,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXpO,GAAGwO,cAAgB,SAASC,EAAMC,EAAarK,GAC3C,GAAIsK,GAAc3O,GAAG+N,UAAUU,EAAMC,EAAaA,EAAcrK,GAC5DuK,EAAa,GAAIC,YACjBC,EAAU,GAAI9O,IAAG+O,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQjP,GAAGmO,iBAAiBS,EAAWzH,UAGnDyH,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGX9O,GAAGsG,OAAS,SAASW,EAAOoI,EAAQC,GAahC,MAZAtP,IAAGY,KAAKyO,EAAQ,SAASvO,EAAMV,GACvBkP,GAAgBtP,GAAGoK,SAAShK,IACRE,SAAhB2G,EAAMnG,KACNmG,EAAMnG,OAEVd,GAAGsG,OAAOW,EAAMnG,GAAOV,GAAK,IAG5B6G,EAAMnG,GAAQV,IAIf6G,GAaXjH,GAAGuP,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACApN,EAASmN,EAASC,EAUtB,OARA1P,IAAGY,KAAK0B,EAAQ,SAASqN,EAAaC,GACNtP,SAAxBkP,EAAOG,KACPD,EAAOC,GAAeH,EAAOG,IAGjCH,EAAOG,GAAeC,IAGnBJ,GAMXxP,GAAG2J,QAAU,SAASkG,EAAKC,EAAKC,GAC5B,GAAIF,EAAIlG,QACJ,MAAOkG,GAAIlG,QAAQmG,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAIxL,MAMd,KAJI0L,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIX/P,GAAGkQ,YAAc,WACb,MAAO,uCAAuCnJ,QAAQ,QAAS,SAASoJ,GAEpE,GAAIC,GAAoB,GAAhBhK,KAAKiK,SAAgB,CAC7B,QADyC,KAALF,EAAWC,EAAS,EAAJA,EAAU,GACrD7F,SAAS,OAM1BvK,GAAGsQ,GAAK,WACJ,MAAOC,WAAUC,UAAU7G,QAAQ,WAAY,GAC3C4G,UAAUC,UAAU7G,QAAQ,cAAe,GAGnD3J,GAAGyQ,IAAM,WACL,MAAOF,WAAUC,UAAU7G,QAAQ,aAAc,GAGrD3J,GAAG0Q,IAAM,WACL,MAAOH,WAAUC,UAAU7G,QAAQ,aAAc,GAGrD3J,GAAG2Q,KAAO,WACN,MAAOJ,WAAUC,UAAU7G,QAAQ,cAAe,GAGtD3J,GAAG4Q,KAAO,WACN,MAAO5Q,IAAGsQ,MAAQC,UAAUC,UAAU7G,QAAQ,YAAa,GAG/D3J,GAAG6Q,KAAO,WACN,MAAON,WAAUC,UAAU7G,QAAQ,SAAW,GAGlD3J,GAAG8Q,OAAS,WACR,MAA4BxQ,UAArBiQ,UAAUQ,QAAwBR,UAAUQ,OAAOpH,QAAQ,YAAa,GAGnF3J,GAAGgR,OAAS,WACR,MAA4B1Q,UAArBiQ,UAAUQ,QAAwBR,UAAUQ,OAAOpH,QAAQ,aAAc,GAGpF3J,GAAGiR,MAAQ,WACP,MAA4B3Q,UAArBiQ,UAAUQ,QAAwBR,UAAUQ,OAAOpH,QAAQ,YAAa,GAGnF3J,GAAGkR,QAAU,WACT,OAASlR,GAAG6Q,SAAW7Q,GAAG4Q,QAAUL,UAAUC,UAAU7G,QAAQ,cAAe,GAA2BrJ,SAArBiQ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrI/Q,GAAGmR,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrBpR,GAAGqR,QAAU,WACT,MAAOd,WAAUC,UAAUzQ,cAAc4J,QAAQ,cAAe,GAKpE3J,GAAG4N,aAAe,WACd,MAAO5N,IAAGqR,WAAad,UAAUC,UAAUzQ,cAAc4J,QAAQ,UAAY,GAGjF3J,GAAGsR,KAAO,WACN,MAAOtR,IAAGuR,OAAShB,UAAUC,UAAU7G,QAAQ,aAAc,GAGjE3J,GAAGwR,KAAO,WACN,MAAOxR,IAAGuR,OAAShB,UAAUC,UAAU7G,QAAQ,aAAc,GAGjE3J,GAAGyR,KAAO,WACN,MAAOzR,IAAGuR,OAAShB,UAAUC,UAAU7G,QAAQ,aAAc,GAIjE3J,GAAG0R,OAAS,WACR,MAAO1R,IAAGuR,OAAShB,UAAUC,UAAU7G,QAAQ,eAAgB,GAGnE3J,GAAGuR,IAAM,WAEL,MAAOhB,WAAUC,UAAU7G,QAAQ,WAAY,GACxC4G,UAAUC,UAAU7G,QAAQ,WAAY,GACxC4G,UAAUC,UAAU7G,QAAQ,aAAc,GAGrD3J,GAAG2R,UAAY,WACX,MAAO3R,IAAGuR,OAAShB,UAAUC,UAAU7G,QAAQ,YAAa,GAGhE3J,GAAG4R,UAAY,WACX,MAAO5R,IAAGuR,QAAUvR,GAAG2R,aAAepB,UAAUC,UAAU7G,QAAQ,aAAc,GAGpF3J,GAAG6R,iBAAmB,WAClB,MAAO7R,IAAGuR,QAAUvR,GAAG2R,cAAgB3R,GAAG4R,aAM9C5R,GAAG8R,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxBhS,GAAGiS,UAAa,WACZ,GAAIC,GAAMnF,SAASC,cAAc,MACjC,OAAO,UAASmF,GACZD,EAAIE,UAAYD,CAChB,IAAIzP,GAAUwP,EAAIxK,UAElB,OADAwK,GAAIpM,YAAYpD,GACTA,MAKf1C,GAAGY,KAAO,SAASyR,EAAcC,GAC7B,GAAIC,GAAYhP,CAEhB,IAAI8O,EAEA,GAAInJ,OAAOsJ,SAAWH,EAAa1H,cAAgBzB,OAAOsJ,QACtD,IAAKD,EAAa,EAAGA,EAAaF,EAAahO,SAC3Cd,EAAS+O,EAASD,EAAalS,IAAIoS,GAAaF,EAAaI,QAAQJ,EAAalS,IAAIoS,KAClFhP,KAAW,GAFoCgP,SAStD,IAAIvS,GAAG8C,QAAQuP,IAAiBrS,GAAG4K,WAAWyH,IAAiBrS,GAAG8K,WAAWuH,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAahO,SAC3Cd,EAAS+O,EAASC,EAAYF,EAAaE,IACvChP,KAAW,GAFoCgP,SAOtD,IAAIvS,GAAGkL,SAASmH,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAahO,SAC3Cd,EAAS+O,EAASC,EAAYF,EAAazS,OAAO2S,IAC9ChP,KAAW,GAFoCgP,SAQvD,KAAKA,IAAcF,GACf,GAAI/H,OAAO9I,UAAUyO,eAAexO,KAAK4Q,EAAcE,KACnDhP,EAAS+O,EAASC,EAAYF,EAAaE,IACvChP,KAAW,GACX,OASxBvD,GAAG0S,KAAO,SAASC,EAASC,GACxB,GAAI5S,GAAGwK,WAAWmI,GAAU,CACxB,GAAI/N,GAAQrD,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,EAElD,OAAO,YACH,GAAImR,GAAU7S,GAAGsG,UAAW1B,EAI5B,OAHIlD,WAAU2C,SACVwO,EAAUA,EAAQC,OAAOvR,MAAMC,UAAU1B,MAAM2B,KAAKC,aAEjDiR,EAAQ3Q,MAAM4Q,EAASC,IAItC,KAAM,IAAI5M,OAAM,wCAmBpBjG,GAAG+S,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQtM,KAAKsM,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAWrR,KACa,gBAAZwR,GACFtT,GAAG+S,QAAQO,EAASE,GAAU,GACe,sBAA5ClJ,OAAO9I,UAAU+I,SAAS9I,KAAK6R,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAKzM,KAAKsM,GAAU,MAAMtM,KAAKsM,GAAS,GAAK,IAAM,IAC7DE,EAAWrR,KAAKmR,GAChBE,EAAWrR,KAAK9B,GAAG+S,QAAQC,KACqB,mBAAxC1I,OAAO9I,UAAU+I,SAAS9I,KAAKuR,IAA8C,SAARA,EAC7EhT,GAAGY,KAAKoS,EAAK,SAASpR,EAAKxB,GACvBiT,EAAIjT,EAAKwB,KAEU,SAARoR,GAAiC,OAARA,GAAiC,gBAARA,GACjEhT,GAAGY,KAAKoS,EAAK,SAASlS,EAAMV,GACxBiT,EAAIjT,EAAKU,KAGbqS,EAAWrR,KAAK2R,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBrM,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7B/G,GAAG2T,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAI1G,WAGnBlN,GAAGY,KAAKoS,EAAK,SAAS7S,EAAKC,GACvBD,EAAM0T,EAAeA,EAAe,IAAM1T,EAAM,IAAMA,EAElDH,GAAGoK,SAAShK,GACZJ,GAAG2T,aAAavT,EAAKwT,EAAUzT,GAE1BH,GAAGwK,WAAWpK,GACnBwT,EAASrK,OAAOpJ,EAAKC,KAGrBwT,EAASrK,OAAOpJ,EAAKC,KAItBwT,GAGX5T,GAAG8T,WAAa,SAASd,EAAKe,GAC1B,GAAIjH,EAeJ,OAbKiH,KACDA,EAAOhH,SAASC,cAAc,SAGlChN,GAAG2T,aAAaX,GACZzJ,OAAQ,SAASpJ,EAAKC,GAClB0M,EAAQC,SAASC,cAAc,SAC/BF,EAAMkH,aAAa,OAAQ7T,GAC3B2M,EAAMkH,aAAa,QAAS5T,GAC5B2T,EAAKE,YAAYnH,MAIlBiH,GAOX/T,GAAGkU,UAAY,SAASC,MAEpB,MAAIjL,QAAOkL,MAAQpU,GAAGwK,WAAW4J,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjCnU,GAAGuU,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAASnQ,OAASoQ,IAIzDzU,GAAG4U,YAAc,SAASC,GAGtB,MAAI7U,IAAGoM,QAAQyI,GAEJA,EAAgBpK,MAAM1D,QAAQ,YAAa,IAE7C/G,GAAG4L,OAAOiJ,IACkB,OAA7BA,EAAgBC,UAAkDxU,SAA7BuU,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgB7T,MAM3BhB,GAAG+U,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIXjQ,OAAQ,WACJ,GAAIL,GAAOlD,SAEXO,MAAKmT,YAAYpV,GAAG4E,EAAK,IAAIK,OAAOjD,MAAMC,KAAMV,MAAMC,UAAU1B,MAAM2B,KAAKC,UAAW,MAI1F0T,YAAa,SAASC,GAClBL,EAAUlT,KAAKuT,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAOtV,MAGY,mBAAXwV,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAUzV,GAGjBnB,OAAOmB,GAAKA,MCRnB,WACG,YAEAA,IAAGiG,MAAQ,SAAS5D,GAChBJ,KAAKI,QAAU,kBAAoBrC,GAAG0V,QAAU,KAAOrT,GAG3DrC,GAAGiG,MAAMzE,UAAY,GAAIyE,UCV7BjG,GAAG0V,QAAU,SCAb1V,GAAG2V,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAY9I,SAASC,cAAc,SACnC6I,EAAUzS,KAAO,OACjBpD,GAAG6V,GAAW/Q,OAEV+Q,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQjW,GAAGgR,UAAYhR,GAAGiR,UAC+C3Q,SAArEiQ,UAAUC,UAAUnN,MAAM,uCAIlC,QAAS6S,KACL,GAAIhN,OAAOmE,eAAgB,CAIvB,MAA+B/M,UAHrBN,GAAGmN,oBAGFgJ,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiC9V,UAA1B4I,OAAOmN,eAKlB,QAASC,KACL,QAAIJ,KAIGE,IAGX,QAASG,KAEL,MAA2DjW,UAApDyM,SAASC,cAAc,SAASwJ,gBAG3C,QAASC,KACL,IACI,QAASvN,OAAOwN,cAEZ1W,GAAGwK,WAAWtB,OAAOwN,aAAaC,SAE1C,MAAOxU,GAEH,OAAO,GAIf,QAASyU,KACL,GAAIC,GAAO9J,SAASC,cAAc,OAElC,QAAQ,aAAe6J,IAAS,eAAiBA,IAAQ,UAAYA,MAChE7W,GAAGqR,YAAcrR,GAAGuR,MA1F7B,GAAIuF,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAzCAd,GAAoBlB,IAEpBqB,EAA4BH,GAAqB9W,GAAG6M,uBAEpDkK,EAAyBE,IAA8BjX,GAAG4N,eAE1DoJ,EAAmBC,GAA6BL,IAGhDM,EAAqBF,GAAqB,WACtC,GAAIlK,GAAQC,SAASC,cAAc,QAGnC,OADAF,GAAM1J,KAAO,UACH,oBAAsB0J,GAASC,SAAS1F,iBAAiB,oBAAoB,QAG3F8P,EAAmBF,GAA6BjX,GAAG2N,0BAEnDyJ,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BhB,IAEtDqB,EAAqBR,IAA6CxW,SAAvB4I,OAAO2O,aAA6BZ,GAE/EO,EAA4BtB,IAE5BqB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmD3W,SAAtB4I,OAAO2F,WAE5D+I,EAA0B,WACtB,QAAIX,KACQjX,GAAG4N,iBAAmB5N,GAAG2R,iBAMrCmG,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiBnP,OAAOoP,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAcjZ,GAAG8Q,SACjBoI,0BAA2BlZ,GAAGuR,MAC9B4H,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxBrX,GAAGwZ,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQ1Z,GAAGwK,WAAWiP,EAAaC,QAG9E1Z,GAAG+O,QAAU,WACT,YAEA,IAAI4K,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZha,IAAGsG,OAAOrE,MACNyX,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiB/X,KAAKmY,GAEtBC,GACAJ,EAAiBhY,KAAKoY,IAGrBF,KAAU,EACfE,GAAaA,EAAUlY,MAAM,KAAM4X,GAE9BK,GACLA,EAAUjY,MAAM,KAAM2X,GAGnB1X,MAGXkY,KAAM,SAAS7H,GAQX,MAPc,KAAV0H,EACAD,EAAcjY,KAAKwQ,GAGnBA,EAAStQ,MAAM,KAAsB1B,SAAhBsZ,EAA4BD,EAAcC,GAG5D3X,MAGXgN,QAAS,WAgBL,MAfA+K,GAAQ,EACRL,EAAcjY,UAEVmY,EAAiBxV,QACjBrE,GAAGY,KAAKiZ,EAAkB,SAASjY,EAAK0Q,GACpCA,EAAStQ,MAAM,KAAM2X,KAIzBI,EAAc1V,QACdrE,GAAGY,KAAKmZ,EAAe,SAASnY,EAAK0Q,GACjCA,EAAStQ,MAAM,KAAM2X,KAItB1X,MAGXkN,QAAS,WAgBL,MAfA6K,IAAQ,EACRJ,EAAclY,UAEVoY,EAAiBzV,QACjBrE,GAAGY,KAAKkZ,EAAkB,SAASlY,EAAK0Q,GACpCA,EAAStQ,MAAM,KAAM4X,KAIzBG,EAAc1V,QACdrE,GAAGY,KAAKmZ,EAAe,SAASnY,EAAK0Q,GACjCA,EAAStQ,MAAM,KAAM4X,KAItB3X,SC3EnBjC,GAAGoa,UAAY,SAASC,EAAeC,GACnC,YAEAta,IAAGsG,OAAOrE,MACNoY,cAAeA,EAEfE,OAAQ,WACJ,MAAOD,GAASD,OCF5Bra,GAAGwa,aAAe,SAASC,GACvB,YA0CA,SAASC,KACL,GAAI5N,GAAQC,SAASC,cAAc,QAmEnC,OAjEAF,GAAMkH,aAAahU,GAAGwa,aAAaG,oBAAqBC,GACxD9N,EAAMkH,aAAa,QAAShV,EAAQ6b,OAEpC7W,EAAK8W,YAAY9b,EAAQiO,SAAUH,GAE/B9N,EAAQ+b,SAAW/a,GAAG2V,kBAAkB8C,iBAExC3L,EAAMkH,aAAa,kBAAmB,IAGtChV,EAAQgc,aACRlO,EAAMkH,aAAa,SAAUhV,EAAQgc,aAGzClO,EAAMkH,aAAa,OAAQ,QAC3BlH,EAAMkH,aAAa,OAAQhV,EAAQgC,MAEnChB,GAAG8M,GAAO/G,KACNkV,SAAU,WAIVC,MAAO,EACPC,IAAK,EACLC,WAAY,QASZC,SAAUrb,GAAGsQ,OAAStQ,GAAG0Q,MAAQ,SAAW,QAC5C4K,OAAQ,EACRC,QAAS,EACTC,OAAQ,UACRtV,QAAS,KAKZlG,GAAGyQ,OAASzQ,GAAG8M,GAAO/G,KAAK0V,OAAQ,SAEpCzc,EAAQ0D,QAAQuR,YAAYnH,GAE5B4O,EAAezW,OAAO6H,EAAO,SAAU,WACnC9N,EAAQ2c,SAAS7O,KAIrB4O,EAAezW,OAAO6H,EAAO,YAAa,WACtC9M,GAAGhB,EAAQ0D,SAASmE,SAAS7H,EAAQ4c,cAEzCF,EAAezW,OAAO6H,EAAO,WAAY,WACrC9M,GAAGhB,EAAQ0D,SAASoE,YAAY9H,EAAQ4c,cAG5CF,EAAezW,OAAO6H,EAAO,QAAS,WAClC9M,GAAGhB,EAAQ0D,SAASmE,SAAS7H,EAAQ6c,cAEzCH,EAAezW,OAAO6H,EAAO,OAAQ,WACjC9M,GAAGhB,EAAQ0D,SAASoE,YAAY9H,EAAQ6c,cAGrC/O,EA5GX,GAgCIA,GAAO8N,EAhCP5W,EAAO/B,KAEPyZ,EAAiB,GAAI1b,IAAG+U,eAExB/V,GAEIgc,YAAa,KAGbtY,QAAS,KAETmZ,WAAY,yBAGZd,SAAS,EAGTa,WAAY,yBAEZE,4BAA4B,EAG5B7O,UAAU,EAGVjM,KAAM,SAGN2a,SAAU,SAAS7O,KAEnB+N,MAAO,KAKf7a,IAAGsG,OAAOtH,EAASyb,GAEnBG,EAAW5a,GAAGkQ,cA2EdlQ,GAAGhB,EAAQ0D,SAASqD,KAChBkV,SAAU,WACVc,SAAU,SAEVC,UAAW,QAIfhc,GAAGsG,OAAOrE,MACNga,SAAU,WACN,MAAOnP,IAGXoP,YAAa,WACT,MAAOtB,IAGXE,YAAa,SAASqB,EAAYC,GAC9B,GAAItP,GAAQsP,GAAYna,KAAKga,UAKzBjd,GAAQ8c,4BAA8B9b,GAAGyR,SAAWzR,GAAG2R,aAAe3R,GAAG6R,oBACzE/E,EAAMkH,aAAa,WAAY,IAI3BmI,EACArP,EAAMkH,aAAa,WAAY,IAG/BlH,EAAMuP,gBAAgB,aAKlCC,eAAgB,SAAStB,GACjBA,IAAgBhc,EAAQgc,aACxBlO,EAAMkH,aAAa,SAAUgH,IAIrCuB,MAAO,WACCzP,EAAMlH,YACN5F,GAAG8M,GAAOjH,SAGd7F,GAAGhB,EAAQ0D,SAASoE,YAAY9H,EAAQ6c,YACxC/O,EAAQ,KACRA,EAAQ4N,OAIhB5N,EAAQ4N,KAGZ1a,GAAGwa,aAAaG,oBAAsB,eCxLtC3a,GAAGwc,WAAa,SAASC,GACrB,YAQA,SAASC,GAAaC,GAClB,GAAI3c,GAAG8C,QAAQ6Z,GAAU,CACrB,GAAIC,KAMJ,OAJA5c,IAAGY,KAAK+b,EAAS,SAAS/a,EAAKib,GAC3BD,EAAQ9a,KAAKzB,EAAKwc,MAGfD,EAGX,MAAOvc,GAAKsc,GAGhB,QAASG,GAAeC,GACpB,GAAI/c,GAAG8C,QAAQia,GAAQ,CACnB,GAAIH,KAMJ,OAJA5c,IAAGY,KAAKmc,EAAO,SAASnb,EAAKob,GACzBJ,EAAQ9a,KAAKzB,EAAK4c,EAAOD,OAGtBJ,EAGX,MAAOvc,GAAK4c,EAAOF,IAGvB,QAASG,GAAgBC,GACrB,GAAIC,MACAC,KAAcvK,OAAOqK,EAYzB,OAVAnd,IAAGY,KAAKyc,EAAU,SAASlZ,EAAOmZ,GAC9B,GAAIC,GAAsBC,EAASF,EAEPhd,UAAxBid,GACAvd,GAAGY,KAAK2c,EAAqB,SAAShK,EAAGkK,GACrCL,EAActb,KAAKzB,EAAKod,QAK7BL,EAhDX,GAAI/c,MACA4c,KACAO,KACAE,KACAC,IA+CJ3d,IAAGsG,OAAOrE,MAgBN2b,QAAS,SAASC,GACd,GAAIV,GAASU,EAAKV,QAAUnd,GAAGmd,OAAOW,WAClCjB,EAAKxc,EAAKyB,MACNd,KAAM6c,EAAK7c,KACX+c,aAAcF,EAAK7c,KACnBgc,KAAMa,EAAKb,KACXgB,KAAmB,MAAbH,EAAKG,MAAe,EAAKH,EAAKG,KACpCb,OAAQA,EACRc,KAAMJ,EAAKI,OACV,CA+BT,OA7BIJ,GAAKK,UACL7d,EAAKwc,GAAIqB,QAAUL,EAAKK,QAEQ5d,SAA5Bqd,EAAUE,EAAKK,WACfP,EAAUE,EAAKK,aAEnBP,EAAUE,EAAKK,SAASpc,KAAK+a,IAG7BgB,EAAKM,eACL9d,EAAKwc,GAAIsB,aAAeN,EAAKM,aAEa7d,SAAtCod,EAAeG,EAAKM,gBACpBT,EAAeG,EAAKM,kBAExBT,EAAeG,EAAKM,cAAcrc,KAAK+a,IAG3Cxc,EAAKwc,GAAIA,GAAKA,EACdI,EAAOY,EAAKb,MAAQH,EAEKvc,SAArBkd,EAASL,KACTK,EAASL,OAEbK,EAASL,GAAQrb,KAAK+a,GAEtBgB,EAAKO,sBAAwBP,EAAKO,qBAAqBvB,GACvDJ,EAAc4B,eAAexB,EAAI,KAAMM,GAEhCN,GAGXyB,SAAU,SAASC,GACf,MAAIve,IAAGoK,SAASmU,IAAmBle,EAAKgE,OACV/D,SAAtBie,EAAe1B,GACRH,EAAa6B,EAAe1B,IAGNvc,SAAxBie,EAAevB,KACbF,EAAeyB,EAAevB,MAGhCuB,EAAepB,OACbD,EAAgBqB,EAAepB,QADrC,OAKEnd,GAAGsG,UAAWjG,GAAM,IAInCme,cAAe,SAAS3B,GACpB,GAAI4B,GAAS/B,EAAaG,EAEtB4B,UACOA,GAAOR,MAItB1B,MAAO,WACHlc,KACA4c,KACAO,KACAG,MAGJe,UAAW,SAAS7B,EAAI8B,GACpB,GAAIC,GAAYve,EAAKwc,GAAIM,OACrB0B,EAAyB7e,GAAG2J,QAAQ6T,EAASoB,GAAY/B,EAE7DW,GAASoB,GAAWE,OAAOD,EAAwB,GAEnDxe,EAAKwc,GAAIM,OAASwB,EAEUre,SAAxBkd,EAASmB,KACTnB,EAASmB,OAEbnB,EAASmB,GAAW7c,KAAK+a,GAEzBJ,EAAc4B,eAAexB,EAAI+B,EAAWD,IAGhDI,YAAa,SAASlC,EAAImC,GACtB,GAAIC,GAAU5e,EAAKwc,GAAIG,IAEvB3c,GAAKwc,GAAIG,KAAOgC,EAChB/B,EAAO+B,GAAWnC,QACXI,GAAOgC,IAGlBC,WAAY,SAASrC,EAAIsC,GACrB9e,EAAKwc,GAAI7b,KAAOme,GAGpBC,WAAY,SAASvC,EAAIwC,GACrBhf,EAAKwc,GAAImB,KAAOqB,GAIpBC,YAAa,SAASC,EAAUC,GAC5Bnf,EAAKkf,GAAUC,SAAWA,GAG9BC,mBAAoB,SAAS5C,GACzB,GAAIsB,GAAe9d,EAAKwc,GAAIsB,YAE5B,OAAIA,GACOT,EAAeS,OAK9BuB,cAAe,SAAS7C,GAGpB,MAAOc,GAFOtd,EAAKwc,GAAIqB,aAOnCle,GAAGmd,QACCW,WAAY,aACZ6B,UAAW,YACXC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,UAAW,YACXC,kBAAmB,oBACnBC,gBAAiB,kBACjBC,kBAAmB,oBACnBC,cAAe,gBACfC,cAAe,gBACfC,SAAU,WACVC,QAAS,WCpNZ,WACG,YAEAvgB,IAAGwgB,eAECC,SAAU,SAASC,EAAiBlhB,EAAQmhB,GACxC1e,KAAK2e,SAASF,EAAiBlhB,EAAQmhB,IAG3CE,gBAAiB,SAASC,GACtB,GAAI9c,GAAO/B,IAEXjC,IAAGY,KAAKkgB,EAAgB,SAAS3c,EAAO4c,GACpC/c,EAAKgd,eAAeD,MAI5BH,SAAU,SAASvgB,EAAMb,EAAQmhB,GAC7B1e,KAAKgf,kCAEL,IAAI/C,GAAqC,IAA3Bjc,KAAKif,WAAW7c,OAAerE,GAAGkQ,cAAgBjO,KAAKkf,gBAEjEC,EAAcphB,GAAG0S,KAAK,SAASjE,GAC3BxM,KAAKof,gBACD5S,KAAMA,EACNzN,KAAMiB,KAAKpB,SAASygB,MAAMC,aAC3BrD,EAASsD,IACbvf,MAEHwf,EAAkBzhB,GAAG0S,KAAK,SAASgP,GAC/Bzf,KAAKof,eAAeK,EAAUxD,EAASsD,IACxCvf,MAEH0f,EAAgB3hB,GAAG0S,KAAK,SAASpK,GAC7B,GAAImG,GAAOzO,GAAGqI,aAAaC,EAE3BrG,MAAKof,gBACD5S,KAAMA,EACNzN,KAAMiB,KAAKpB,SAASygB,MAAMC,YAAc,QACzCrD,EAASsD,IACbvf,MAEH2f,EAAoB5hB,GAAG0S,KAAK,SAASmP,GACjC,GAAIC,GAAoBD,EAAWrZ,SAAWqZ,EAAWrZ,QAAU,IAC/DiG,EAAOzO,GAAGqI,aAAawZ,EAAWvZ,OAAQuZ,EAAWze,KAAM0e,EAE/D7f,MAAKof,gBACD5S,KAAMA,EACNzN,KAAM6gB,EAAW7gB,MAClBkd,EAASsD,IACbvf,MAEH8f,EAAqB/hB,GAAG0S,KAAK,SAASsP,GAClC,GAAIhiB,GAAGoM,QAAQ4V,IAAgBhiB,GAAG2V,kBAAkBmC,cAAe,CAC/D,GAAImK,GAAQ1gB,MAAMC,UAAU1B,MAAM2B,KAAKugB,EAAYC,OAC/Cje,EAAO/B,IAEXjC,IAAGY,KAAKqhB,EAAO,SAASrgB,EAAKqc,GACzBja,EAAKqd,eAAepD,EAAMC,EAASsD,SAIvCvf,MAAKof,eAAeW,EAAa9D,EAASsD,IAE/Cvf,MAEHigB,EAAgB,WACRliB,GAAG+L,WAAW1L,KACdA,EAAOkB,MAAMC,UAAU1B,MAAM2B,KAAKpB,IAEtCA,KAAUyS,OAAOzS,IAGrB2D,EAAO/B,KACPuf,IAEJvf,MAAKkf,gBAAkBjD,EAEnB7d,IACA6hB,IAEAliB,GAAGY,KAAKP,EAAM,SAASuB,EAAKugB,GACpBniB,GAAGkM,cAAciW,GACjBJ,EAAmBI,GAEdniB,GAAG2M,OAAOwV,GACff,EAAYe,GAEPniB,GAAGoK,SAAS+X,GACbA,EAAc1T,MAAQ0T,EAAcnhB,KACpCygB,EAAgBU,GAEXA,EAAc7Z,QAAU6Z,EAAcnhB,MAC3C4gB,EAAkBO,GAGjBA,EAAczV,SAAmD,WAAxCyV,EAAczV,QAAQ3M,cACpD4hB,EAAcQ,GAGdne,EAAK5B,IAAI+f,EAAgB,6CAA8C,UAI/ElgB,KAAKG,IAAI,YAAcof,EAAcnd,OAAS,WAC9CpC,KAAKmgB,uBAAuBZ,EAAehiB,EAAQmhB,KAI3D0B,OAAQ,SAASxF,GACb,GAAIyF,GAAargB,KAAKsgB,YAAYjE,UAAUzB,GAAIA,GAE5CyF,IAAcA,EAAWnF,SAAWnd,GAAGmd,OAAO8C,kBAC9Che,KAAKG,IAAIpC,GAAGwL,OAAO,2DAA4DqR,EAAI5a,KAAKugB,QAAQ3F,IAAM,SAGtG5a,KAAKwgB,SAASJ,OAAOxF,IAI7B6F,UAAW,WACP,GAAIC,MACA3e,EAAO/B,IAEXjC,IAAGsG,OAAOqc,EAAe1gB,KAAKif,YAC9BlhB,GAAGY,KAAK+hB,EAAe,SAAS/gB,EAAKghB,GACjC5e,EAAKqe,OAAOO,KAGhB3gB,KAAKwgB,SAASC,aAGlBG,iBAAkB,WACd5gB,KAAKif,eAGT4B,eAAgB,SAASjG,GACrB,GAAIyF,GAAargB,KAAKsgB,YAAYjE,UAAUzB,GAAIA,GAEhD,UAAK7c,GAAG2V,kBAAkBkD,QAAU5W,KAAKpB,SAASoX,SAAS8K,WAIvDT,EAAWnF,SAAWnd,GAAGmd,OAAO4C,QAChC9d,KAAKG,IAAIpC,GAAGwL,OAAO,yDAA0DqR,EAAI5a,KAAKugB,QAAQ3F,KAC9F5a,KAAK+gB,YAAYnG,IACV,IAGP5a,KAAKG,IAAIpC,GAAGwL,OAAO,sDAAuDqR,EAAI5a,KAAKugB,QAAQ3F,IAAM,UAG9F,KAGXoG,WAAY,SAASpG,GACjB,MAAO5a,MAAKihB,gBAAgBrG,IAIhCsG,UAAW,SAASC,GAChB,MAAOnhB,MAAKwgB,SAASY,QAAQD,IAOjCE,cAAe,SAASC,EAAQC,EAAaC,EAASC,EAAYC,GAC9D,GACIC,GAAW5kB,EADX6kB,EAAkB,GAAI7jB,IAAG+O,OAqC7B,OAlCI9M,MAAK6hB,iBACLF,EAAY3hB,KAAK8hB,eAAeR,GAChCvkB,GACI2kB,qBAAsBA,EACtBF,QAASA,EAAU,EAAIA,EAAU,KACjCO,MAAOP,EAAU,IAKhBC,GAAc1jB,GAAG2V,kBAAkB+C,gBACpCkL,EAAY3hB,KAAKgiB,QAAQV,IAIZ,MAAbK,EACAC,EAAgB1U,SAAS+U,UAAWV,EAAarhB,MAAO,2BAGxDF,KAAK6hB,gBAAgBK,SAASP,EAAWJ,EAAaxkB,GAAS0a,KAC3D,SAAiB0K,GACbP,EAAgB5U,QAAQmV,IAG5B,SAAiBF,EAAWG,GACxBR,EAAgB1U,SAAS+U,UAAWA,EAAW/hB,MAAOkiB,GAAU,oCAM5ER,EAAgB1U,SAAS+U,UAAWV,EAAarhB,MAAO,mCAGrD0hB,GAGXS,UAAW,SAASf,GAChB,MAAOthB,MAAKsiB,WAAWtiB,KAAKuiB,qBAAqBjB,KAGrDkB,YAAa,SAASlB,GAClB,MAAOthB,MAAKyiB,eAAeC,IAAIpB,IAGnCU,QAAS,SAASb,GACd,GACIwB,GADA3G,EAAOhc,KAAKwgB,SAASwB,QAAQb,EAWjC,OARKnF,KACD2G,EAAmB3iB,KAAKsgB,YAAYjE,UAAUzB,GAAIuG,IAE9CwB,IACA3G,EAAO2G,EAAiB3G,OAIzBA,GAAQ,MAGnB4G,cAAe,WACX,MAAO5iB,MAAKsgB,YAAYjE,UACpBnB,QACInd,GAAGmd,OAAO6C,UACVhgB,GAAGmd,OAAO+C,gBACVlgB,GAAGmd,OAAO0C,UAEfxb,QAGPme,QAAS,SAAS3F,GACd,MAAO5a,MAAKsgB,YAAYjE,UAAUzB,GAAIA,IAAK7b,MAI/C8jB,YAAa,SAASjI,GAClB,GAAIkI,GAAkB9iB,KAAK+iB,YAAYnI,GAAIA,IACvC2C,EAAW,IAQf,OANIuF,IACiCzkB,SAA7BykB,EAAgBvF,WAChBA,EAAWuF,EAAgBvF,UAI5BA,GAGXyF,sBAAuB,WACnB,MAAOhjB,MAAKwgB,SAASwC,yBAGzBC,QAAS,SAASrI,GACd,MAAO5a,MAAKsgB,YAAYjE,UAAUzB,GAAIA,IAAKmB,MAG/CmH,cAAe,WACX,MAAOljB,MAAKmjB,cAGhBC,yBAA0B,WACtB,GAAIC,GAAerjB,KAAKsjB,iBAExB,OAAID,GAAe,EACRA,EAAerjB,KAAKujB,qBAGxB,MAGXR,WAAY,SAASzG,GACjB,MAAOtc,MAAKsgB,YAAYjE,SAASC,IAGrCkH,QAAS,SAAS5I,GACd,MAAO5a,MAAKsgB,YAAYjE,UAAUzB,GAAIA,IAAKG,MAG/C0I,YAAa,SAAS7I,GAClB,MAAO5a,MAAKwgB,SAASkD,gBAAgB9I,IAGzCza,IAAK,SAASqJ,EAAKvB,IACXjI,KAAKpB,SAAS+kB,OAAW1b,GAAmB,SAAVA,EAG7BA,GAAmB,SAAVA,GACdlK,GAAGoC,IAAI,kBAAoBpC,GAAG0V,QAAU,KAAOjK,EAAKvB,GAHpDlK,GAAGoC,IAAI,kBAAoBpC,GAAG0V,QAAU,KAAOjK,IAQvDoa,YAAa,SAAShJ,GAClB,GAAIyF,GAAargB,KAAKsgB,YAAYjE,UAAUzB,GAAIA,GAEhD,KAAK7c,GAAG2V,kBAAkBkD,QAAU5W,KAAKpB,SAASoX,SAAS8K,QACvD,OAAO,CAIX,IAAI/iB,GAAG2J,SAAS3J,GAAGmd,OAAO6C,UAAWhgB,GAAGmd,OAAO+C,iBAAkBoC,EAAWnF,SAAW,EAAG,CACtF,GAAIlb,KAAKwgB,SAAS5J,MAAMgE,GAEpB,MADA5a,MAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAO4C,SAClC,CAGP9d,MAAKG,IAAIpC,GAAGwL,OAAO,mCAAoCqR,EAAI5a,KAAKugB,QAAQ3F,IAAM,aAIlF5a,MAAKG,IAAIpC,GAAGwL,OAAO,wDAAyDqR,EAAI5a,KAAKugB,QAAQ3F,IAAM,QAGvG,QAAO,GAGX2B,cAAe,SAAS3B,GACpB5a,KAAKwgB,SAASqD,QAAQjJ,GACtB5a,KAAKsgB,YAAY/D,cAAc3B,IAGnCN,MAAO,WACHta,KAAKG,IAAI,yBAETH,KAAKwgB,SAASlG,QACdta,KAAKif,cACLjf,KAAK8jB,gBACL9jB,KAAK+jB,kBACL/jB,KAAKgkB,mBACLhkB,KAAK8hB,kBAEL/jB,GAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjCA,EAAO5J,UAGXta,KAAKmkB,aAAa7J,QAClBta,KAAKyiB,eAAenI,QACpBta,KAAKujB,qBAAuB,EAC5BvjB,KAAKmjB,aAAe,EACpBnjB,KAAKsgB,YAAYhG,QACjBta,KAAKuiB,wBAELviB,KAAKokB,eAAiBpkB,KAAKokB,cAAc9J,QACzCta,KAAKpB,SAASylB,QAAQC,gBAAkBtkB,KAAKukB,sBAE7CvkB,KAAKwkB,kCACLxkB,KAAKykB,+BAELzkB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAepK,QAE3Cta,KAAK2kB,uBAAuBrK,SAGhCsK,MAAO,SAAShK,GACZ,MAAO5a,MAAK6kB,aAAajK,IAG7BkK,WAAY,SAASlK,EAAImK,GACrB,GAAIhjB,GAAO/B,IAEX,OAAOjC,IAAGinB,OAAOzlB,UAAUulB,WAAWlK,EAAImK,GACtC5kB,IAAKpC,GAAG0S,KAAK1O,EAAK5B,IAAK4B,GACvBigB,QAASjkB,GAAG0S,KAAK1O,EAAKigB,QAASjgB,GAC/Bse,WAAYte,EAAKue,eAIzB2E,iBAAkB,SAASC,EAAStK,GAChC5a,KAAKmlB,oBAAoBC,IAAIF,EAAStK,IAG1CyK,oBAAqB,SAASzK,EAAIxc,GAC9B4B,KAAK2kB,uBAAuBS,IAAIhnB,EAAMwc,IAG1C0K,2BAA4B,SAASJ,EAAStK,GAC1C5a,KAAKulB,8BAA8BH,IAAIF,EAAStK,IAGpD4K,sBAAuB,SAAS9G,EAAU9D,GACtC5a,KAAKylB,yBAAyBL,IAAI1G,EAAU9D,IAGhD8K,oBAAqB,SAASnoB,EAAQqd,GAClC5a,KAAK2lB,uBAAuBP,IAAI7nB,EAAQqd,IAI5CgL,YAAa,SAASlH,EAAU9D,GAC5B5a,KAAKyiB,eAAe2C,IAAI1G,EAAU9D,IAGtCiL,QAAS,SAASC,GACd9lB,KAAK+lB,4BAA4BD,IAGrCE,aAAc,SAASC,GACnBjmB,KAAKsjB,kBAAoB2C,GAG7BC,QAAS,SAAStL,EAAIsC,GAClBld,KAAKsgB,YAAYrD,WAAWrC,EAAIsC,IAGpCiJ,UAAW,SAAS5oB,EAAQqd,GACxB5a,KAAKmkB,aAAaiB,IAAI7nB,EAAQqd,IAGlCwL,QAAS,SAASxL,EAAImC,GAClB,MAAO/c,MAAKsgB,YAAYxD,YAAYlC,EAAImC,IAY5CN,UAAW,SAAS7B,EAAI8B,GAEpB,IADiB1c,KAAK+iB,YAAYnI,GAAIA,IAElC,KAAM,IAAI7c,IAAGiG,MAAM4W,EAAK,2BAG5B,QAAQ8B,GACJ,IAAK3e,IAAGmd,OAAOoD,QACXte,KAAKqmB,kBAAkBzL,EAAI,MAAM,EACjC,MACJ,KAAK7c,IAAGmd,OAAOkD,cACXpe,KAAKqmB,kBAAkBzL,EAAI,MAAM,EACjC,MACJ,SACI,GAAI0L,GAAe,+BAAiCvnB,KAAO,6BAA+B2d,CAE1F,MADA1c,MAAKG,IAAImmB,GACH,GAAIvoB,IAAGiG,MAAMsiB,KAI/BC,kBAAmB,WACgB,IAA3BvmB,KAAKif,WAAW7c,OAChBpC,KAAKwmB,WAAW,gBAGhBxmB,KAAKymB,uBAQjB1oB,GAAG2oB,gBAEC3H,eAAgB,SAAS4H,GACrB,GAAI5kB,GAAO/B,IAEX,OAAOA,MAAKsgB,YAAY3E,SACpBZ,KAAM4L,EAAY5L,KAClBhc,KAAM4nB,EAAY5nB,KAClBgd,KAAM4K,EAAY5K,KAClBb,OAAQnd,GAAGmd,OAAOgD,kBAClB/B,qBAAsB,SAASvB,GAC3B+L,EAAYC,oBAAsB7kB,EAAKyjB,sBAAsBmB,EAAYC,mBAAoBhM,GAC7F+L,EAAYE,kBAAoB9kB,EAAK2jB,oBAAoBiB,EAAYE,iBAAkBjM,GAEnF+L,EAAYG,eACZ/kB,EAAK+f,eAAelH,GAAM+L,EAAYG,cAG1C/kB,EAAKohB,eACLphB,EAAKwhB,2BAKjBwD,sBAAuB,SAAS/K,EAAMgL,GAC9BjpB,GAAG4L,OAAOqS,KACVA,EAAKiL,WAAajnB,KAAKknB,aAAaF,KAI5CG,YAAa,SAAS/mB,GAClBJ,KAAKpB,SAASF,UAAU0oB,QAAQ,KAAM,KAAMhnB,EAAS/B,SAGzDgpB,qBAAsB,WAClB,GAAItlB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGupB,yBACVC,OAAQvnB,KAAKpB,SAASoiB,WAAWuG,OAAO3pB,cACxC4pB,eAAgBxnB,KAAKpB,SAAS4oB,eAC9BC,cAAeznB,KAAKpB,SAAS8oB,QAAQC,SACrCC,cAAe5nB,KAAKulB,8BACpBsC,YAAa7nB,KAAK2lB,uBAClBmC,cAAe9nB,KAAKylB,yBACpBsC,KAAM/nB,KAAKpB,SAASmpB,KACpB5nB,IAAKpC,GAAG0S,KAAK1O,EAAK5B,IAAK4B,GACvBimB,SAAU,SAASpN,GACf7Y,EAAKkmB,UAAUrN,GACf7Y,EAAKnD,SAASF,UAAUspB,SAASpN,IAErCsN,iBAAkB,SAAStN,EAAIuN,EAAUC,GACrCrmB,EAAKskB,kBAAkBzL,EAAIuN,EAAUC,GACrCrmB,EAAKnD,SAASF,UAAUwpB,iBAAiBtN,EAAIuN,EAAUC,OAMnEC,oBAAqB,WACjB,GAAItmB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGuqB,cACVC,cAAevoB,KAAKpB,SAAS4pB,MAAMD,cACnC7pB,WACIyB,IAAKpC,GAAG0S,KAAK1O,EAAK5B,IAAK4B,GACvB0mB,cAAe,SAASjc,GACpBzK,EAAK2mB,wBACD3pB,KAAM,kBACNsR,SAAUtS,GAAG0S,KAAK1O,EAAKnD,SAASF,UAAUiqB,gBAAiB5mB,EAAMyK,GACjEwL,UAAWja,GAAG0S,KAAK1O,EAAK6mB,oBAAqB7mB,EAAMyK,GACnDqc,WAAY,sBAOhCC,aAAc,SAASC,EAAcC,GACjC,GAAIC,MACAC,EAAWH,EACXI,KACAC,EAAiBJ,EACjBK,EAAO,SAASC,GACZ,MAAIvrB,IAAGoK,SAASmhB,GACLvrB,GAAGsG,UAAWilB,GAElBA,GAEXC,EAAoB,WAChB,MAAIxrB,IAAGwK,WAAW6gB,GACPA,IAEJA,GAEXI,EAAwB,SAAS5O,EAAI6O,GAC7BL,GAAkBrrB,GAAGoK,SAASshB,IAC9B1rB,GAAGsG,OAAOolB,EAAUF,KAGpBJ,EAAoBvO,IACpB7c,GAAGsG,OAAOolB,EAAUN,EAAoBvO,IAIpD,QACIwK,IAAK,SAASjnB,EAAKyc,GAEL,MAANA,GACAqO,KACAC,EAAWG,EAAKlrB,IAGhB8qB,EAAMrO,GAAMyO,EAAKlrB,IAIzBukB,IAAK,SAAS9H,GACV,GAAI8O,EAYJ,OARIA,GADM,MAAN9O,GAAcqO,EAAMrO,GACXqO,EAAMrO,GAGNyO,EAAKH,GAGlBM,EAAsB5O,EAAI8O,GAEnBL,EAAKK,IAGhBC,YAAa,SAAS/O,EAAI8O,GAElB3rB,GAAGoK,SAAS8gB,KAED,OAAPrO,EACI7c,GAAGwK,WAAWmhB,GACdN,EAAiBM,GAGjBN,EAAiBA,MACjBrrB,GAAGsG,OAAO+kB,EAAgBM,KAI9BP,EAAoBvO,GAAMuO,EAAoBvO,OAC9C7c,GAAGsG,OAAO8kB,EAAoBvO,GAAK8O,MAK/C9lB,OAAQ,SAAS0d,GACb,aAAc2H,GAAM3H,IAGxBhH,MAAO,WACH2O,KACAE,KACAD,EAAWH,KAKvBa,yBAA0B,WACtB,GAAI7nB,GAAO/B,IAEX,OAAO,IAAIjC,IAAGwc,YACVgG,QAAS,SAAS3F,GACd,MAAO7Y,GAAKwe,QAAQ3F,IAExB4I,QAAS,SAAS5I,GACd,MAAO7Y,GAAKyhB,QAAQ5I,IAExBqI,QAAS,SAASrI,GACd,MAAO7Y,GAAKkhB,QAAQrI,IAExBwB,eAAgB,SAASxB,EAAI+B,EAAWD,GACpC3a,EAAK8nB,sBAAsBjP,EAAI+B,EAAWD,GAC1C3a,EAAKnD,SAASF,UAAU0d,eAAexB,EAAI+B,EAAWD,GACtD3a,EAAK+nB,kBAAkBlP,EAAI8B,GAEvB3a,EAAK2iB,gBACLqF,WAAW,WACPhoB,EAAK2iB,eAAetI,eAAexB,EAAI+B,EAAWD,IACnD,OAcnBsN,oBAAqB,SAASpO,GAM1B,QAASqO,KACL,QAAIlsB,GAAG2V,kBAAkBmC,kBAEjB9T,EAAKnD,SAASsrB,YAAYC,gBAC1BpsB,GAAGuR,QACFvR,GAAGsR,QACJtN,EAAKqoB,oBAAoBC,EAAmB,WAK1BhsB,SAAlBud,EAAK5Q,SACEjJ,EAAKnD,SAASoM,SAGlB4Q,EAAK5Q,WApBpB,GAGIkZ,GAHAniB,EAAO/B,KACP+Y,EAAc6C,EAAK0O,QAAUtqB,KAAKpB,SAAS2rB,WAAWxR,YACtDsR,EAAoBzO,EAAKyO,mBAAqBrqB,KAAKpB,SAAS2rB,WAAWF,iBA6C3E,OArBAnG,GAAS,GAAInmB,IAAGwa,cACZQ,YAAaA,EACbtY,QAASmb,EAAKnb,QACdmZ,WAAY5Z,KAAKpB,SAAS4rB,QAAQC,YAClC3R,QAAS8C,EAAK9C,QACda,WAAY3Z,KAAKpB,SAAS4rB,QAAQE,YAClC7Q,2BAA4B7Z,KAAKpB,SAASsrB,YAAYS,iBACtD3f,SAAUif,IACVlrB,KAAMiB,KAAKpB,SAAS8oB,QAAQkD,UAC5BlR,SAAU,SAAS7O,GACf9I,EAAK8oB,eAAehgB,IAExB+N,MAAqB,MAAdgD,EAAKhD,MAAgB5Y,KAAKpB,SAASgH,KAAKklB,eAAiBlP,EAAKhD,QAGzE5Y,KAAK+qB,gBAAgB5X,YAAY,WAC7B+Q,EAAOlR,YAGXjR,EAAKkiB,SAASpkB,KAAKqkB,GAEZA,GAGX8G,qBAAsB,SAASC,EAAmBvtB,GAC9C,GAAIqE,GAAO/B,KACPkrB,KACAnuB,GACI4mB,MAAO3jB,KAAKpB,SAAS+kB,MACrB6D,eAAgBxnB,KAAKpB,SAAS4oB,eAC9BO,KAAM/nB,KAAKpB,SAASmpB,KACpBF,YAAa7nB,KAAKmkB,aAClB2D,cAAe9nB,KAAKyiB,eACpBzM,SAAUhW,KAAKpB,SAASoX,SACxBc,OAAQ9W,KAAKpB,SAASkY,OACtBuI,MAAOrf,KAAKpB,SAASygB,MACrBlf,IAAKpC,GAAG0S,KAAK1O,EAAK5B,IAAK4B,GACvBopB,kBAAmBnrB,KAAKpB,SAASgmB,MAAMwG,6BACvCC,WAAY,SAASzQ,EAAI7b,EAAMusB,EAAQC,GAC/BD,EAAS,GAAKC,EAAQ,IAItBL,EAAetQ,GACXsQ,EAAetQ,GAAI0Q,SAAWA,GAAUJ,EAAetQ,GAAI2Q,QAAUA,IACrExpB,EAAKypB,YAAY5Q,EAAI7b,EAAMusB,EAAQC,GACnCxpB,EAAKnD,SAASF,UAAU2sB,WAAWzQ,EAAI7b,EAAMusB,EAAQC,KAIzDxpB,EAAKypB,YAAY5Q,EAAI7b,EAAMusB,EAAQC,GACnCxpB,EAAKnD,SAASF,UAAU2sB,WAAWzQ,EAAI7b,EAAMusB,EAAQC,IAGzDL,EAAetQ,IAAO0Q,OAAQA,EAAQC,MAAOA,KAGjDE,WAAY,SAAS7Q,EAAI7b,EAAMmG,EAAQwmB,SAC5BR,GAAetQ,EAEtB,IACItZ,GADA4Z,EAASnZ,EAAKghB,YAAYnI,GAAIA,IAAKM,MAOnCA,KAAWnd,GAAGmd,OAAOgD,mBAAqBhD,IAAWnd,GAAGmd,OAAOiD,gBAInE7c,EAASS,EAAK4pB,YAAY/Q,EAAI7b,EAAMmG,EAAQwmB,GAIxCpqB,YAAmBvD,IAAG+O,QACtBxL,EAAO4W,KAAK,WACRnW,EAAKnD,SAASF,UAAU+sB,WAAW7Q,EAAI7b,EAAMmG,EAAQwmB,KAIzD3pB,EAAKnD,SAASF,UAAU+sB,WAAW7Q,EAAI7b,EAAMmG,EAAQwmB,KAG7DE,SAAU,SAAShR,EAAI7b,EAAM8sB,GACzB,GAAIhf,GAAU,GAAI9O,IAAG+O,OAgBrB,OAdA/K,GAAK2mB,wBACD3pB,KAAM,WACNsR,SAAUtS,GAAG0S,KAAK1O,EAAKnD,SAASF,UAAUktB,SAAU7pB,EAAM6Y,EAAI7b,GAC9DkZ,UAAWpL,EAAQK,QACnB8K,UAAW,WACP6T,EAAyBpU,KAAK,WAC1B1V,EAAK+pB,UAAUlR,EAAI7b,KAGvB8N,EAAQG,WAEZ6b,WAAYjO,IAGT/N,GAEXkf,aAAchuB,GAAG0S,KAAKzQ,KAAKgsB,cAAehsB,MAC1CisB,SAAU,SAASrR,EAAI7b,GACnBgD,EAAKmqB,UAAUtR,EAAI7b,EACnB,IAAIotB,GAAiBpqB,EAAKnD,SAASF,UAAUutB,SAASrR,EAAI7b,EAE1D,OAAIhB,IAAGwZ,iBAAiB4U,IACpBpqB,EAAK5B,IAAIpC,GAAGwL,OAAO,+DAAgEqR,IAC5EuR,IAGJ,GAAIpuB,IAAG+O,SAAUE,WAE5Bof,cAAe,SAASxR,EAAI7b,EAAMstB,GAC9BtqB,EAAKuqB,eAAe1R,EAAIyR,EACxB,IAAIE,GAAsBxqB,EAAKnD,SAASF,UAAU0tB,cAAcxR,EAAI7b,EAAMstB,EAE1E,OAAItuB,IAAGwZ,iBAAiBgV,IACpBxqB,EAAK5B,IAAIpC,GAAGwL,OAAO,uEAAwEqR,EAAIyR,EAAUG;uIAClGD,IAGJ,GAAIxuB,IAAG+O,SAAUE,WAE5Byf,qBAAsB,SAAS7R,EAAIyR,EAAWnnB,EAAQwmB,GAClD3pB,EAAK2qB,sBAAsB9R,EAAIyR,GAC/BtqB,EAAKnD,SAASF,UAAU+tB,qBAAqB1sB,MAAMgC,EAAMtC,YAE7DktB,SAAU,SAAS/R,EAAI7b,EAAMstB,EAAWO,GACpC,MAAO7qB,GAAKnD,SAASF,UAAUiuB,SAAS/R,EAAI7b,EAAMstB,EAAWO,IAEjEC,YAAa,SAASjS,EAAI7b,EAAM+tB,EAAcpB,GAC1C,MAAO3pB,GAAKgrB,aAAahtB,MAAMgC,EAAMtC,YAEzCutB,cAAe,SAASpS,EAAImC,GACxBhb,EAAK5B,IAAI,sCAAwC4B,EAAKyhB,QAAQ5I,GAAM,SAAWmC,EAAU,KACzFhb,EAAKqkB,QAAQxL,EAAImC,IAErBwD,QAASxiB,GAAG0S,KAAK1O,EAAKwe,QAASxe,GAC/ByhB,QAASzlB,GAAG0S,KAAK1O,EAAKyhB,QAASzhB,GAC/BkhB,QAASllB,GAAG0S,KAAK1O,EAAKkhB,QAASlhB,GAC/BkrB,QAASlvB,GAAG0S,KAAK1O,EAAKmrB,SAAUnrB,GAChCorB,cAAe,SAASpS,GACpB,MAAOhZ,GAAKghB,YAAYhI,KAAMA,KAElCqS,SAAU,SAASxS,GACf,GAAIM,GAASnZ,EAAKghB,YAAYnI,GAAIA,IAAKM,MACvC,OAAOA,KAAWnd,GAAGmd,OAAO0C,QACxB1C,IAAWnd,GAAGmd,OAAOwC,WACrBxC,IAAWnd,GAAGmd,OAAO+C,iBACrB/C,IAAWnd,GAAGmd,OAAO4C,QAE7BN,mBAAoBzb,EAAKue,YAAY9C,mBACrCC,cAAe1b,EAAKue,YAAY7C,cAChC4P,aAAc,SAASzS,GACnB,MAAO7Y,GAAKghB,YAAYnI,GAAIA,IAAKM,SAAWnd,GAAGmd,OAAO6C,WAE1DuP,oBAAqBvvB,GAAG0S,KAAK1O,EAAKwrB,qBAAsBxrB,GACxD0a,UAAW,SAAS7B,EAAIM,GACpBnZ,EAAKue,YAAY7D,UAAU7B,EAAIM,IAgB3C,OAZAnd,IAAGY,KAAKqB,KAAKpB,SAAS8oB,QAAS,SAAS7oB,EAAMV,GAC1CpB,EAAQ8B,GAAQV,IAGpBpB,EAAQ6qB,cAAgB5nB,KAAKmlB,oBAEzB8F,GACAltB,GAAGY,KAAKssB,EAAmB,SAAS/sB,EAAKC,GACrCpB,EAAQmB,GAAOC,IAIhB,GAAIJ,IAAGyvB,wBAAwBzwB,EAASW,IAGnD+vB,oBAAqB,SAAS7S,GAC1B5a,KAAKujB,uBACLvjB,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAOyC,WAG7C+P,YAAa,SAASthB,GAClB,GAAc,IAAVA,EACA,MAAOA,GAAQpM,KAAKpB,SAASgH,KAAK+nB,YAAY,EAElD,IAAIrc,IAAI,CACR,GACIlF,IAAgB,IAChBkF,UACKlF,EAAQ,IAEjB,OAAOjI,MAAKypB,IAAIxhB,EAAO,IAAKyhB,QAAQ,GAAK7tB,KAAKpB,SAASgH,KAAK+nB,YAAYrc,IAK5Ewc,0BAA2B,WACvB,GAAI/rB,GAAO/B,IAEXA,MAAK+tB,qBAELhwB,GAAGY,KAAKqB,KAAKpB,SAASovB,aAAc,SAASruB,EAAKsuB,GAC9C,GAAIjjB,GAAWijB,EAAuBjjB,SAClCuf,EAAaxsB,GAAGsG,UAAWtC,EAAKnD,SAAS2rB,YAAY,GACrD2D,EAAkBnwB,GAAGsG,UAAW4pB,EAEnB5vB,UAAb2M,IACAA,EAAWjJ,EAAKnD,SAASoM,UAGzBkjB,EAAgB3D,YAChBxsB,GAAGsG,OAAOkmB,EAAY0D,EAAuB1D,YAAY,GAG7DxsB,GAAGsG,OAAO6pB,GACNljB,SAAUA,EACVuf,WAAYA,IACb,GAEHxoB,EAAKosB,iBAAiBD,MAI9B5L,WAAY,SAAS3J,GACjB,GAAIyV,GAAmBpuB,KAAK+tB,kBAAkBpV,EAE9C,OAAIyV,GACOA,EAAiB3tB,QAEnBkY,IAAa3Y,KAAKquB,iBAChBruB,KAAKpB,SAASslB,OADpB,QAYTgD,aAAc,SAASoH,GACnB,GAAIC,GAAQC,EACRC,EAAkBH,CAQtB,IALIG,YAA2B1wB,IAAGoa,YAC9BsW,EAAkBA,EAAgBrW,eAIlCqW,IAAoB1wB,GAAG2M,OAAO+jB,GAAkB,CAChD,GAAI1wB,GAAG4L,OAAO8kB,GACV,MAAOA,GAAgBxH,UAEtB,IAA8C,UAA1CwH,EAAgBhkB,QAAQ3M,eACU,SAAvC2wB,EAAgBttB,KAAKrD,cAErB,MAAO2wB,GAAgBtoB,aAAapI,GAAGwa,aAAaG,oBAYxD,IATA6V,EAASE,EAAgBppB,qBAAqB,SAE9CtH,GAAGY,KAAK4vB,EAAQ,SAAS5uB,EAAKkL,GAC1B,GAAmC,SAA/BA,EAAM1E,aAAa,QAEnB,MADAqoB,GAAY3jB,GACL,IAIX2jB,EACA,MAAOA,GAAUroB,aAAapI,GAAGwa,aAAaG,uBAK1D6U,qBAAsB,SAASjM,GAC3B,MAAOthB,MAAK2kB,uBAAuBjC,IAAIpB,IAG3CoN,gBAAiB,WACb,MAAO1uB,MAAKsgB,YAAYjE,UACpBnB,QACInd,GAAGmd,OAAO6C,UACVhgB,GAAGmd,OAAO+C,gBACVlgB,GAAGmd,OAAO0C,OACV7f,GAAGmd,OAAOW,WACV9d,GAAGmd,OAAOwC,UACV3f,GAAGmd,OAAO4C,UAEf1b,QAKPusB,mBAAoB,SAAShW,GACzB,GAAIuV,GAAkBluB,KAAK+tB,kBAAkBpV,EAE7C,OAAOuV,GAAkBA,EAAgB3D,WAAavqB,KAAKpB,SAAS2rB,YAGxEqE,yBAA0B,SAASC,GAC/B,MAAIA,GAAY7S,eAAgBje,IAAGoa,WAE3BpZ,KAAMhB,GAAG4U,YAAYkc,EAAY7S,KAAK5D,eACtC2D,KAAM8S,EAAY7S,KAAK5D,cAAc2D,OAKzChd,KAAMiB,KAAK+iB,YAAYnI,GAAIiU,EAAYjU,KAAK7b,KAC5Cgd,KAAM/b,KAAK+iB,YAAYnI,GAAIiU,EAAYjU,KAAKmB,OAIpD+S,0BAA2B,SAASC,GAChC,GAAIhtB,GAAO/B,KACPgvB,IAMJ,OAJAjxB,IAAGY,KAAKowB,EAAc,SAASpvB,EAAKkvB,GAChCG,EAAgBnvB,KAAKkC,EAAK6sB,yBAAyBC,MAGhDG,GAIXC,oBAAqB,WACjB,GAAIjvB,KAAKpB,SAASswB,OAAO5f,KAAOvR,GAAGuR,MAAO,CACtC,GACI4U,GAASlkB,KAAKpB,SAASswB,OAAOhL,OAC9BvL,EAAWuL,EAASlkB,KAAKknB,aAAahD,GAAUlkB,KAAKquB,iBACrDc,EAAanvB,KAAKpB,QAGlB+Z,IAAYA,IAAa3Y,KAAKquB,mBAC9Bc,EAAanvB,KAAK+tB,kBAAkBpV,IAIxCwW,EAAWnkB,UAAW,EAGoB,OAAtCmkB,EAAW5E,WAAWxR,YACtBoW,EAAW5E,WAAWxR,YAfJ,yBAkBlBoW,EAAW5E,WAAWxR,aAAe,0BAIzChb,GAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjC,GAAIA,EAAOjK,gBAAkBtB,EAIzB,MAHAuL,GAAOrL,YAAYsW,EAAWnkB,UAC9BkZ,EAAO7J,eAAe8U,EAAWpW,cAE1B,MAMvB2P,uBAAwB,SAAS0G,GAC7B,GAAIrtB,GAAO/B,KACPqvB,EAAiBD,EAAQ/e,UAE7B,OAAItS,IAAGwZ,iBAAiB8X,IACpBrvB,KAAKG,IAAIivB,EAAQrwB,KAAO,kBAAoBqwB,EAAQrwB,KAAO,gCAAkCqwB,EAAQvG,YAC9FwG,EAAe5X,KAClB,SAAS6X,GACLvtB,EAAK5B,IAAIivB,EAAQrwB,KAAO,wBAA0BqwB,EAAQvG,YAC1DuG,EAAQpX,UAAUsX,IAEtB,WACQF,EAAQnX,WACRlW,EAAK5B,IAAIivB,EAAQrwB,KAAO,wBAA0BqwB,EAAQvG,YAC1DuG,EAAQnX,aAGRlW,EAAK5B,IAAIivB,EAAQrwB,KAAO,wBAA0BqwB,EAAQvG,gBAKtEwG,KAAmB,EACnBD,EAAQpX,UAAUqX,GAGdD,EAAQnX,WACRjY,KAAKG,IAAIivB,EAAQrwB,KAAO,mCAAqCqwB,EAAQvG,WAAa,iCAClFuG,EAAQnX,aAGRjY,KAAKG,IAAIivB,EAAQrwB,KAAO,mCAAqCqwB,EAAQvG,WAAa,wBAInFwG,IAIXjQ,eAAgB,SAASpD,EAAMC,EAASsT,GACpC,GAAIxtB,GAAO/B,KACP+a,EAAOhd,GAAGkQ,cACV8N,GAAO,EACPhd,EAAOhB,GAAG4U,YAAYqJ,GACtBwT,EAAaxT,EAAKxP,MAAQwP,EAC1ByT,EAAUzvB,KAAK0vB,sBACX1vB,KAAK0vB,sBACL3xB,GAAG0S,KAAK1O,EAAK4tB,sBAAuB5tB,IAEvChE,GAAGoM,QAAQqlB,IAAeA,EAAWzT,MAAQ,IAC9CA,EAAOyT,EAAWzT,MAGtB0T,EAAQD,EAAYzwB,EAAMgc,EAAMgB,EAAMwT,EAAoBtT,EAASjc,KAAKpB,SAAS8oB,QAAQC,UACrFtH,WAAYte,EAAKue,YACjBuH,YAAa9lB,EAAKoiB,aAClByL,iBAAkB,SAAShV,EAAIoB,GAC3Bja,EAAKye,SAASpP,IAAIwJ,EAAIoB,GACtBja,EAAKwhB,uBACLxhB,EAAK8tB,aAAajV,OAK9B+U,sBAAuB,SAAS3T,EAAMjd,EAAMgc,EAAMgB,EAAM+T,EAAU7T,GAC9D,GAAIrB,GAAK5a,KAAKsgB,YAAY3E,SACtBZ,KAAMA,EACNhc,KAAMA,EACNgd,KAAMA,EACNE,QAASA,EACTD,KAAMA,GAGVhc,MAAKwgB,SAASpP,IAAIwJ,EAAIoB,GAEtBhc,KAAK6vB,aAAajV,GAElB5a,KAAKujB,uBAELuM,EAASjwB,MAAM+a,GAAIA,EAAIoB,KAAMA,KAGjC4M,oBAAqB,SAASpc,EAAMujB,GAChC,GAAIC,GAAYxjB,EAAKrL,KAAKsG,MAAM,KAAK,GACjC1I,EAAOgxB,CAGC,OAARhxB,IACAA,EAAOiB,KAAKpB,SAAS4pB,MAAMlJ,aAG/BvgB,GAAQ,IAAMixB,EAEdhwB,KAAK2e,UACD5f,KAAMA,EACNyN,KAAMA,KAIdyjB,qBAAsB,SAASrV,GAC3B,GAAI5a,KAAK+iB,YAAYnI,GAAIA,IAAKM,SAAWnd,GAAGmd,OAAOoD,QAAS,CACxD,GAAIvf,GAAOiB,KAAKugB,QAAQ3F,EAExB5a,MAAKujB,uBACLvjB,KAAKmjB,eACLnjB,KAAKwgB,SAASqD,QAAQjJ,GACtB5a,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAOoD,SACzCte,KAAKG,IAAI,uBAAyBpB,EAAO,sBAIjDmxB,oBAAqB,SAAStV,EAAIuN,GAC9B,GAAIppB,GAAOiB,KAAKugB,QAAQ3F,EAExB5a,MAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAOkD,eACzCpe,KAAKG,IAAI,uBAAyBpB,EAAO,gBAAiB,SAKrDopB,GAAyC9pB,SAA7B8pB,EAASjU,gBAItBlU,KAAKpB,SAASF,UAAU0oB,QAAQxM,EAAI7b,EAAM,4CAA8CopB,EAASjN,OAAQiN,GAHzGnoB,KAAKpB,SAASF,UAAU0oB,QAAQxM,EAAI7b,EAAM,wBAAyBopB,IAQ3EgG,iBAAkB,SAASvS,GACvB,GAAIsI,GAASlkB,KAAKgqB,qBACdM,OAAQ1O,EAAK2O,WAAWxR,YACxBsR,kBAAmBzO,EAAK2O,WAAWF,kBACnC5pB,QAASmb,EAAKnb,QACdqY,QAAS8C,EAAK9C,QACd9N,SAAU4Q,EAAK5Q,SACf4N,MAAOgD,EAAKkP,gBAGhB9qB,MAAK+tB,kBAAkB7J,EAAOjK,eAAiB2B,GAGnDuU,0BAA2B,WACvBnwB,KAAKowB,aAAeryB,GAAGsyB,aAAe,GAAItyB,IAAGsyB,YACzCrwB,KAAKpB,SAASkT,KAAM/T,GAAG0S,KAAKzQ,KAAKumB,kBAAmBvmB,MAAOjC,GAAG0S,KAAKzQ,KAAKG,IAAKH,OAG7EA,KAAKowB,cAAgBpwB,KAAKowB,aAAaE,gBACvCtwB,KAAKmkB,aAAenkB,KAAK8oB,aACrB9oB,KAAKpB,SAAS8oB,QAAQnqB,OAASyC,KAAKowB,aAAaG,uBAGrDvwB,KAAKpB,SAAS4xB,WAAaxwB,KAAKowB,aAAaK,cACzCzwB,KAAKowB,aAAaM,cAClB1wB,KAAKpB,SAAS8oB,QAAQhJ,SAAW1e,KAAKowB,aAAaM,cAIvD1wB,KAAKmkB,aAAenkB,KAAK8oB,aAAa9oB,KAAKpB,SAAS8oB,QAAQnqB,SAIpEozB,kBAAmB,WACf,SAAK5yB,GAAGupB,0BAA4BtnB,KAAKpB,SAASoiB,WAAWF,YAIzD9gB,KAAKpB,SAASmpB,KAAK6I,aACf7yB,GAAG2V,kBAAkByC,sBAIrBpY,GAAG2V,kBAAkBwC,oBAAqBlW,KAAKpB,SAASmpB,KAAK8I,aAUzEzG,oBAAqB,SAAS0G,EAASje,GACnC,GAAIke,IAAQ,CAEZ,QAAKD,EAAQ1uB,SAIbrE,GAAGY,KAAKmyB,EAAS,SAASnxB,EAAKqxB,GAK3B,GAAIjzB,GAAGkL,SAAS+nB,GAAa,CAEzB,GAAIC,GAAW,GAAIxsB,QAAO,MAAQusB,EAAa,IAAK,IAEpD,IAAgC,MAA5Bne,EAASzR,MAAM6vB,GAEf,MADAF,IAAQ,GACD,KAKZA,IAWXvK,WAAY,SAAS0K,EAAMC,EAAkBpoB,GASzC,QAASoF,GAAEpP,EAAMqyB,GAAehxB,EAAUA,EAAQ0E,QAAQ/F,EAAMqyB,GARhE,GAMIC,GAAsBC,EANtBlxB,EAAUJ,KAAKpB,SAAS2yB,SAASL,GACjC7G,KACAmH,KAAW3gB,OAAOsgB,GAClBpyB,EAAOyyB,EAAM,GACb7Y,EAAW3Y,KAAKknB,aAAane,GAC7B0oB,EAAiBzxB,KAAK2uB,mBAAmBhW,EA+B7C,OA1BA5a,IAAGY,KAAK8yB,EAAepH,kBAAmB,SAAS1qB,EAAK+xB,GAKhD3zB,GAAGkL,SAASyoB,IACZrH,EAAkBxqB,KAAK6xB,KAI/BL,EAAuBhH,EAAkB5Y,KAAK,MAAM3T,cAEpDqQ,EAAE,SAAUnO,KAAKpB,SAAS+yB,eAAe5yB,IACzCoP,EAAE,eAAgBkjB,GAClBljB,EAAE,cAAenO,KAAK0tB,YAAY+D,EAAeG,YACjDzjB,EAAE,iBAAkBnO,KAAK0tB,YAAY+D,EAAeI,eAEpDP,EAAmBlxB,EAAQgB,MAAM,cACR,OAArBkwB,GACAvzB,GAAGY,KAAK2yB,EAAkB,SAAS3xB,EAAKmyB,GACpC3jB,EAAE2jB,EAAaN,EAAM7xB,MAI7BK,KAAKpB,SAASF,UAAU0oB,QAAQ,KAAMroB,EAAMqB,EAAS/B,QAE9C+B,GAYXykB,aAAc,SAASjK,EAAIvK,GACvB,GAAIrQ,KAAK+xB,qBAAqBnX,GAW1B,MAVA5a,MAAKujB,uBACLvjB,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAO+C,iBAErC5N,EACAA,EAASuK,GAGT5a,KAAKwgB,SAASoE,MAAMhK,IAGjB,GAIfkP,kBAAmB,SAASlP,EAAIM,GAC5B,GAAInZ,GAAO/B,KACPgyB,EAAchyB,KAAK0uB,iBAEnBxT,KAAWnd,GAAGmd,OAAOgD,kBACrBle,KAAKwkB,+BAA+B3kB,KAAK+a,GAEpCM,IAAWnd,GAAGmd,OAAOiD,eAC1Bne,KAAKykB,4BAA4B5kB,KAAK+a,GAGtB,IAAhBoX,IACChyB,KAAKwkB,+BAA+BpiB,QAAUpC,KAAKykB,4BAA4BriB,SAEhF2nB,WAAW,WACPhoB,EAAKkwB,eAAelwB,EAAKyiB,+BAAgCziB,EAAK0iB,8BAC/D,IAIXzF,iCAAkC,WAC9B,GAAIjd,GAAO/B,IAEX,IAAIA,KAAKpB,SAASsrB,YAAYgI,mBAAqBn0B,GAAG0R,UAAY1R,GAAG4R,YAIjE,KAHAoa,YAAW,WACP9iB,OAAOkrB,MAAMpwB,EAAKnD,SAAS2yB,SAASa,+BACrC,GACG,GAAIr0B,IAAGiG,MAAMhE,KAAKpB,SAAS2yB,SAASa,+BAIlDC,8BAA+B,SAASzX,EAAI7b,EAAMuzB,EAAU5G,GAGxD,IAAK4G,EAAStlB,QACV,GAAI0e,GAAsB,MAAfA,EAAIxQ,SAAmBoX,EAASpyB,MACvCF,KAAKpB,SAASF,UAAU0oB,QAAQxM,EAAI7b,EAAM,8BAAgC2sB,EAAIxQ,OAAQwQ,OAErF,CACD,GAAI6G,GAAcD,EAASpyB,MAAQoyB,EAASpyB,MAAQF,KAAKpB,SAASgH,KAAK4sB,oBACvExyB,MAAKpB,SAASF,UAAU0oB,QAAQxM,EAAI7b,EAAMwzB,EAAa7G,KAKnE+G,6CAA8C,SAASC,EAAWlnB,EAAOtJ,EAAO3E,EAAQmhB,GACpF,GAAI3c,GAAO/B,IAEX,IAAIwL,EAAMpJ,OAASF,EACf,GAAIwwB,IAAc1yB,KAAKpB,SAAS2rB,WAAWoI,uBAEvC5I,WAAW,WACP,GAAI6I,GAAuB7wB,EAAK6sB,yBAAyBpjB,EAAMtJ,IAC3DyW,EAAW5W,EAAKmlB,aAAa1b,EAAMtJ,GAAO8Z,MAC1CkI,EAASniB,EAAKugB,WAAW3J,EAE7B5W,GAAK2mB,wBACD3pB,KAAM,aACNsR,SAAUtS,GAAG0S,KAAK1O,EAAKnD,SAASF,UAAUm0B,WAAY9wB,EAAM6wB,EAAsB1O,GAClFlM,UAAWja,GAAG0S,KAAK1O,EAAK+wB,2BAA4B/wB,EAAMyJ,EAAOtJ,EAAO3E,EAAQmhB,GAChFzG,UAAWla,GAAG0S,KAAK1O,EAAKgxB,2BAA4BhxB,EAAMyJ,EAAOtJ,EAAO3E,EAAQmhB,GAChFmK,WAAY,SAAW+J,EAAqB7zB,KAAO,YAAc6zB,EAAqB7W,QAE3F,OAEF,KAAK2W,EACN,KAAOxwB,EAAQsJ,EAAMpJ,OAAQF,IACzBH,EAAK0rB,oBAAoBjiB,EAAMtJ,GAAO0Y,KAMtDqX,eAAgB,SAASe,EAAYC,GACjCjzB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAewO,cAAcF,EAAYC,EAAQjzB,KAAKgkB,iBAElFhkB,KAAKpB,SAASF,UAAUw0B,cAAcn1B,GAAGsG,UAAW2uB,GAAaj1B,GAAGsG,UAAW4uB,IAE/EjzB,KAAKwkB,kCACLxkB,KAAKykB,gCAeTsI,aAAc,SAASnS,EAAI7b,EAAM+tB,EAAcpB,EAAKrb,GAChD,GAAItO,GAAO/B,IAIX,IAFA+B,EAAKiiB,gBAAgBpJ,GAAMkS,EAAa/qB,EAAKnD,SAASgmB,MAAMwG,8BAExDrpB,EAAKoxB,iBAAiBvY,GAAK,CAC3B,GAAIwY,GAAyD,IAAvCrxB,EAAKnD,SAASgmB,MAAMyO,gBAkB1C,OAhBAtxB,GAAKswB,8BAA8BtyB,MAAMgC,EAAMtC,WAC/CsC,EAAKnD,SAASF,UAAUmuB,YAAYjS,EAAI7b,EAAMgD,EAAK+hB,aAAalJ,IAChE7Y,EAAKuxB,mBAAmB1Y,EAAI7b,GAE5BgD,EAAKue,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAO+C,iBACzClc,EAAKgiB,eAAenJ,GAAMmP,WAAW,WACjChoB,EAAK5B,IAAI,sBAAwBpB,EAAO,OAEpCsR,EACAA,EAASuK,GAGT7Y,EAAKye,SAASoE,MAAMhK,IAEzBwY,IAEI,IAIfE,mBAAoB,SAAS1Y,EAAI7b,GAC7BiB,KAAKG,IAAI,WAAaH,KAAKpB,SAASgmB,MAAMyO,iBAAmB,4BAA8Bt0B,EAAO,QAItGgzB,qBAAsB,SAASnX,GAC3B,GACI/H,GADA0gB,EAAYvzB,KAAKsjB,iBAGrB,OAAItjB,MAAKgkB,gBAAgBpJ,IACrB5a,KAAKG,IAAI,gCAAkCya,EAAI,SACxC,GAEF5a,KAAKwgB,SAASY,QAAQxG,IAC3B/H,EAAW7S,KAAKugB,QAAQ3F,GAEpB5a,KAAKpB,SAASF,UAAU80B,cAAc5Y,EAAI/H,MAAc,IAIxD0gB,EAAY,GAAKvzB,KAAKujB,qBAAuB,EAAIgQ,GACjDvzB,KAAKwmB,WAAW,0BACT,IAGXxmB,KAAKG,IAAI,wBAA0B0S,EAAW,UAAY+H,EAAK,SACxD,MAGP5a,KAAKG,IAAI,IAAMya,EAAK,2BAA4B,UACzC,IAIfkR,UAAW,SAASlR,EAAI7b,GACpBiB,KAAKujB,uBAELkQ,aAAazzB,KAAK+jB,eAAenJ,GAEjC,IAAI8Y,GAAkB31B,GAAG2J,QAAQ1H,KAAKif,WAAYrE,IAC7C5a,KAAKpB,SAAS4xB,YAAckD,GAAmB,GAChD1zB,KAAKif,WAAWpC,OAAO6W,EAAiB,GAG5C1zB,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAO2C,WAG7C8N,YAAa,SAAS/Q,EAAI7b,EAAMmG,EAAQwmB,GAoBpC,MAnBKxmB,GAAO8H,SASJ9H,EAAO4hB,eACP9mB,KAAK8hB,eAAelH,GAAM1V,EAAO4hB,cAGrC9mB,KAAKmjB,eACLnjB,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAOgD,qBAbzCle,KAAKujB,uBACLvjB,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAOiD,eAErCjZ,EAAOlF,KAAKpB,SAASgmB,MAAMwG,iCAAkC,IAC7DprB,KAAKgkB,gBAAgBpJ,IAAM,IAYnC5a,KAAKqyB,8BAA8BzX,EAAI7b,EAAMmG,EAAQwmB,KAE9CxmB,EAAO8H,SAGlBib,UAAW,SAASrN,GAChB5a,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAOmD,WAG7CgI,kBAAmB,SAASzL,EAAIuN,EAAUC,GAC3BpoB,KAAKugB,QAAQ3F,EAEpBwN,GACApoB,KAAKkwB,oBAAoBtV,EAAIuN,GAG7BnoB,KAAKiwB,qBAAqBrV,IAIlCiQ,eAAgB,SAAShgB,GACrB,GAAI8oB,EAEJ,IAAI51B,GAAG2V,kBAAkBmC,cAAe,CACpC,IAAK8d,EAAY,EAAGA,EAAY9oB,EAAMmV,MAAM5d,OAAQuxB,IAChD3zB,KAAK+mB,sBAAsBlc,EAAMmV,MAAM2T,GAAY9oB,EAGvD7K,MAAK2e,SAAS9T,EAAMmV,WAGfnV,GAAMrC,MAAMpG,OAAS,GAC1BpC,KAAK2e,SAAS9T,EAGlB9M,IAAGY,KAAKqB,KAAKikB,SAAU,SAAStkB,EAAKukB,GACjCA,EAAO5J,WAIfkR,YAAa,SAAS5Q,EAAI7b,EAAMusB,EAAQC,GACpCvrB,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAekP,qBAAqBhZ,EAAI0Q,EAAQC,IAGhFsI,UAAW,SAASjZ,EAAI7b,KAIxB+0B,yBAA0B,SAASlZ,EAAI7b,GACnCiB,KAAK6zB,UAAU9zB,MAAMC,KAAMP,WAC3BO,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAOwC,WACzC1d,KAAK+zB,aAAah0B,MAAMC,KAAMP,WAE1BO,KAAKpB,SAAS4xB,YACdxwB,KAAKpB,SAASF,UAAUs1B,YAAYj0B,MAAMC,KAAMP,WAChDO,KAAK+gB,YAAYnG,KAGjB5a,KAAKi0B,eAAerZ,GACpB5a,KAAKpB,SAASF,UAAUs1B,YAAYj0B,MAAMC,KAAMP,aAIxDwhB,gBAAiB,SAASrG,EAAIsZ,EAAmBC,GAC7C,GACIC,GADArZ,EAAO/a,KAAKwjB,QAAQ5I,EAOxB,OAJIsZ,KACAE,EAA4Br2B,GAAG0S,KAAKyjB,EAAmBl0B,KAAM4a,EAAIG,EAAMoZ,IAGvEn0B,KAAK2wB,qBACL3wB,KAAK0oB,wBACD3pB,KAAM,iBACNsR,SAAUtS,GAAG0S,KAAKzQ,KAAKpB,SAASF,UAAU21B,eAAgBr0B,KAAM4a,GAChE5C,UAAWoc,GACPr2B,GAAG0S,KAAKzQ,KAAKs0B,eAAeC,WAAYv0B,KAAM4a,EAAIG,EAAMoZ,GAC5DtL,WAAYjO,KAET,IAGP5a,KAAKG,IAAI,iCAAmCya,EAAK,wHACuB,SACjE,IAIfmZ,aAAc,SAASnZ,KAIvB4Z,iBAAkB,SAASlJ,EAAQC,GAC/BvrB,KAAKpB,SAASF,UAAU+1B,gBAAgBnJ,EAAQC,IAGpDS,cAAe,SAASpR,KAIxBsR,UAAW,SAAStR,EAAI7b,GACpBiB,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAO6C,YAG7CuO,eAAgB,SAAS1R,EAAIyR,KAI7BK,sBAAuB,SAAS9R,EAAIyR,IAC3BrsB,KAAKgkB,gBAAgBpJ,IAAO5a,KAAKpB,SAASgmB,MAAM8P,aACjD10B,KAAK8jB,aAAalJ,GAAM,IAIhCiP,sBAAuB,SAASjP,EAAI+B,EAAWD,GAEvCA,IAAc3e,GAAGmd,OAAO4C,QACxB2V,aAAazzB,KAAK+jB,eAAenJ,KAIzC+Z,gCAAiC,SAAS5F,GACtC,GAAIhtB,GAAO/B,IAEXjC,IAAGY,KAAKowB,EAAc,SAASpvB,EAAKkvB,GAChC9sB,EAAK0rB,oBAAoBoB,EAAYjU,OAI7Cga,gCAAiC,SAASC,EAAuBrpB,EAAOjO,EAAQmhB,EAAUwF,GACtF,GAAIoC,GACAiN,EAAYvzB,KAAKsjB,kBACjBwR,EAAmC90B,KAAKujB,oBAE1B,KAAdgQ,GAAmBuB,GAAoCvB,EACnD/nB,EAAMpJ,OAAS,EACfpC,KAAK0oB,wBACD3pB,KAAM,aACNsR,SAAUtS,GAAG0S,KAAKzQ,KAAKpB,SAASF,UAAUm0B,WAAY7yB,KAAM60B,EAAsB,GAAI3Q,GACtFlM,UAAWja,GAAG0S,KAAKzQ,KAAK8yB,2BAA4B9yB,KAAMwL,EAAO,EAAGjO,EAAQmhB,GAC5EzG,UAAWla,GAAG0S,KAAKzQ,KAAK+yB,2BAA4B/yB,KAAMwL,EAAO,EAAGjO,EAAQmhB,GAC5EmK,WAAY,SAAWrd,EAAM,GAAGwQ,KAAKjd,KAAO,YAAcyM,EAAM,GAAGwQ,KAAKD,OAI5E/b,KAAKwmB,WAAW,iBAIpBxmB,KAAK20B,gCAAgCnpB,GACrC8a,EAAetmB,KAAKpB,SAAS2yB,SAASwD,kBACjCjwB,QAAQ,gBAAiBgwB,GACzBhwB,QAAQ,iBAAkByuB,GAC/BvzB,KAAKmnB,YAAYb,KAIzByM,2BAA4B,SAASvnB,EAAOtJ,EAAO3E,EAAQmhB,GACvD,GAAIsW,GAAY9yB,EAAQ,CAExBlC,MAAKytB,oBAAoBjiB,EAAMtJ,GAAO0Y,GAAIpP,EAAMtJ,GAAO8Z,KAAKjd,MAE5DiB,KAAKyyB,8CAA6C,EAAOjnB,EAAOwpB,EAAWz3B,EAAQmhB,IAGvFoU,2BAA4B,SAAStnB,EAAOtJ,EAAO3E,EAAQmhB,GACvD,GAAI3c,GAAO/B,KACPg1B,EAAY9yB,EAAQ,EACpB0wB,EAAuB5yB,KAAK4uB,yBAAyBpjB,EAAMtJ,GAE/DlC,MAAKi1B,wBAAwBzpB,EAAMtJ,GAAQ0wB,GACtCnb,KACD,WACI1V,EAAKmzB,QAAQ1pB,EAAMtJ,GAAO0Y,GAAIrd,EAAQmhB,GACtC3c,EAAK0wB,8CAA6C,EAAMjnB,EAAOwpB,EAAWz3B,EAAQmhB,IAEtF,WACI3c,EAAK0wB,8CAA6C,EAAOjnB,EAAOwpB,EAAWz3B,EAAQmhB,MAK/FyB,uBAAwB,SAAS3U,EAAOjO,EAAQmhB,GAC5C,GAAqB,IAAjBlT,EAAMpJ,OAEN,WADApC,MAAKwmB,WAAW,eAIpB,IAAIqO,GAAwB70B,KAAK8uB,0BAA0BtjB,GACvDmN,EAAW3Y,KAAKknB,aAAa1b,EAAM,GAAGwQ,MACtCkI,EAASlkB,KAAKsiB,WAAW3J,EAE7B3Y,MAAK0oB,wBACD3pB,KAAM,kBACNsR,SAAUtS,GAAG0S,KAAKzQ,KAAKpB,SAASF,UAAUy2B,gBAAiBn1B,KAAM60B,EAAuB3Q,GACxFlM,UAAWja,GAAG0S,KAAKzQ,KAAK40B,gCAAiC50B,KAAM60B,EAAuBrpB,EAAOjO,EAAQmhB,EAAUwF,GAC/GjM,UAAWla,GAAG0S,KAAKzQ,KAAK20B,gCAAiC30B,KAAMwL,GAC/Dqd,WAAY,sBAIpBuM,wBAAyB,WACrB,GAAIrzB,GAAO/B,IAEXA,MAAK+qB,gBAAgB/nB,OAAOiE,OAAQ,eAAgB,SAAS6I,GACzD,GAAI/N,EAAK6gB,gBAKL,MAJA9S,GAAIA,GAAK7I,OAAOouB,MAEhBvlB,EAAEC,YAAchO,EAAKnD,SAAS2yB,SAAS+D,QAEhCvzB,EAAKnD,SAAS2yB,SAAS+D,WAQ1C/Q,oBAAqB,WACjB,GAAIxiB,GAAO/B,KACPjD,EAAUiD,KAAKpB,SAASylB,OAGxBtmB,IAAGw3B,SAA6C,MAAlCv1B,KAAKpB,SAASylB,QAAQ3F,WAC/B1e,KAAKw1B,WACNz3B,GAAGsG,OAAOtH,GAAUgrB,KAAM/nB,KAAKpB,SAASmpB,OAExChrB,EAAQoD,IAAMpC,GAAG0S,KAAKzQ,KAAKG,IAAKH,MAChCjD,EAAQ04B,cAAgB13B,GAAG0S,KAAKzQ,KAAK+e,eAAgB/e,MAErDA,KAAKw1B,SAAW,GAAIz3B,IAAGw3B,QAAQx4B,IAGnCgtB,WAAW,WACPhoB,EAAKyzB,SAASE,UAAUje,KAAK,SAAS6a,EAAUnK,GAC5CpmB,EAAK4zB,0BACL5zB,EAAKnD,SAASF,UAAUk3B,yBAAyBtD,GAAU,EAAMnK,IAElE,SAASmK,EAAUnK,GAElBpmB,EAAKnD,SAASF,UAAUk3B,yBAAyBtD,GAAU,EAAOnK,MAEvE,KAIXwN,wBAAyB,aAEzBzI,SAAU,SAAStS,EAAIwC,GACnBpd,KAAKsgB,YAAYnD,WAAWvC,EAAIwC,GAChCpd,KAAK0kB,gBAAkB1kB,KAAK0kB,eAAemR,UAAUjb,IAGzDuY,iBAAkB,SAASvY,GACvB,GAAIyF,GAAargB,KAAKsgB,YAAYjE,UAAUzB,GAAIA,GAGhD,WAAK5a,KAAKgkB,gBAAgBpJ,IACnB5a,KAAKpB,SAASgmB,MAAM8P,YACpBrU,EAAWnF,SAAWnd,GAAGmd,OAAO4C,SAELzf,SAA1B2B,KAAK8jB,aAAalJ,KAClB5a,KAAK8jB,aAAalJ,GAAM,GAGxB5a,KAAK8jB,aAAalJ,GAAM5a,KAAKpB,SAASgmB,MAAMkR,oBAC5C91B,KAAK8jB,aAAalJ,IAAO,GAClB,IAOnBqZ,eAAgB,SAASrZ,GACrB5a,KAAKif,WAAWpf,KAAK+a,IAIzBiV,aAAc,SAASjV,GACnB,GAAIjC,EAGAA,GADA5a,GAAG2V,kBAAkBmC,cACV7V,KAAKwgB,SAASwB,QAAQpH,GAAIqM,WAG1BjnB,KAAKknB,aAAalnB,KAAKwgB,SAASxG,SAASY,IAGpDjC,IACA3Y,KAAKuiB,qBAAqB3H,GAAMjC,IAIxCoN,4BAA6B,SAASgQ,GAClC/1B,KAAKpB,SAASkT,KAAKrR,QAAUs1B,EAE7B/1B,KAAKowB,aAAeryB,GAAGsyB,aAAe,GAAItyB,IAAGsyB,YACrCrwB,KAAKpB,SAASkT,KAAM/T,GAAG0S,KAAKzQ,KAAKumB,kBAAmBvmB,MAAOjC,GAAG0S,KAAKzQ,KAAKG,IAAKH,OAGjFA,KAAKowB,cAAgBpwB,KAAKowB,aAAaE,iBACvCtwB,KAAKmkB,aAAawF,YAAY,KAAM3pB,KAAKowB,aAAaG,uBAEtDvwB,KAAKpB,SAAS4xB,WAAaxwB,KAAKowB,aAAaK,cACzCzwB,KAAKowB,aAAaM,aAClB1wB,KAAK4lB,YAAY5lB,KAAKowB,aAAaM,eAK/CwE,QAAS,SAASta,EAAIrd,EAAQmhB,GAC1B,GAAI3f,GAAOiB,KAAKugB,QAAQ3F,EAEpBrd,IACAyC,KAAKmmB,UAAU5oB,EAAQqd,GAGvB8D,GACA1e,KAAK4lB,YAAYlH,EAAU9D,GAG/B5a,KAAK0oB,wBACD3pB,KAAM,WACNsR,SAAUtS,GAAG0S,KAAKzQ,KAAKpB,SAASF,UAAUs3B,SAAUh2B,KAAM4a,EAAI7b,GAC9DiZ,UAAWja,GAAG0S,KAAKzQ,KAAK8zB,yBAA0B9zB,KAAM4a,EAAI7b,GAC5DkZ,UAAWla,GAAG0S,KAAKzQ,KAAKytB,oBAAqBztB,KAAM4a,EAAI7b,GACvD8pB,WAAYjO,KAIpBmG,YAAa,SAASnG,GACb5a,KAAKwgB,SAASrV,OAAOyP,IACtB5a,KAAKsgB,YAAY7D,UAAU7B,EAAI7c,GAAGmd,OAAO0C,SAIjD6I,mBAAoB,WAIhB,IAHA,GAAIwP,GAAYC,EACZn0B,EAAO/B,KAEJA,KAAKif,WAAW7c,QACnB6zB,EAAaj2B,KAAKif,WAAW/L,QAC7BlT,KAAK+gB,YAAYkV,EAIrBC,GAAkBl2B,KAAK+iB,YAAY7H,OAAQnd,GAAGmd,OAAOW,aAAazZ,OAC9D8zB,IACAn4B,GAAGoC,IAAI,qBAAuB+1B,EAAkB,yEAChDnM,WAAW,WACPhoB,EAAK0kB,sBACN,OAYXwO,wBAAyB,SAASpG,EAAa+D,GAC3C,GAAI7wB,GAAO/B,KACPgc,EAAQ,WACJ,MAAI6S,GAAY7S,eAAgBje,IAAGoa,UACxB0W,EAAY7S,KAAK5D,cAErByW,EAAY7S,QAEvBjd,EAAO6zB,EAAqB7zB,KAC5Bgd,EAAO6W,EAAqB7W,KAC5BpD,EAAW3Y,KAAKknB,aAAa2H,EAAY7S,MACzCyV,EAAiBzxB,KAAK2uB,mBAAmBhW,GACzCwd,EAAkB,GAAIp4B,IAAG+O,OAQ7B,OANAqpB,GAAgB1e,KACZ,aACA,WACI1V,EAAK0rB,oBAAoBoB,EAAYjU,GAAI7b,KAG7ChB,GAAGkM,cAAc+R,KAAUhc,KAAKoqB,oBAAoBqH,EAAepH,kBAAmBtrB,IACtFiB,KAAKwmB,WAAW,YAAaznB,EAAMid,GAC5Bma,EAAgBjpB,WAGtBlN,KAAKpB,SAAS2rB,WAAW6L,YAAuB,IAATra,EAKxCA,EAAO,GAAK0V,EAAeG,WAAa7V,EAAO0V,EAAeG,WAC9D5xB,KAAKwmB,WAAW,YAAaznB,EAAMid,GAC5Bma,EAAgBjpB,WAGvB6O,EAAO,GAAKA,EAAO0V,EAAeI,cAClC7xB,KAAKwmB,WAAW,eAAgBznB,EAAMid,GAC/Bma,EAAgBjpB,YAGvBnP,GAAGs4B,iBAAmBt4B,GAAG2V,kBAAkB+C,eAAiB1Y,GAAG4L,OAAOqS,GACtE,GAAIje,IAAGs4B,gBAAgBra,EAAMje,GAAG0S,KAAK1O,EAAK5B,IAAK4B,IAAOu0B,SAAS7E,EAAe8E,OAAO9e,KACjF0e,EAAgBnpB,QAChB,SAASwpB,GACLz0B,EAAKykB,WAAWgQ,EAAY,aAAcz3B,EAAMid,GAChDma,EAAgBjpB,YAKxBipB,EAAgBnpB,UAGbmpB,IA3BHn2B,KAAKwmB,WAAW,aAAcznB,EAAMid,GAC7Bma,EAAgBjpB,YA6B/BupB,eAAgB,WACZ,GAAI10B,GAAM20B,EAAc73B,CAExBkD,GAAO/B,KAEP02B,EAAe,SAAS33B,EAAMsR,EAAU1N,GACpC,GAAIg0B,EAEJ,KACI,MAAOtmB,GAAStQ,MAAMgC,EAAMY,GAEhC,MAAOi0B,GACHD,EAAWC,EAAUx2B,SAAWw2B,EAAUtuB,WAC1CvG,EAAK5B,IAAI,wBAA0BpB,EAAO,gBAAkB43B,EAAU,UAK9E,KAAK93B,IAAQmB,MAAKpB,SAASF,WACtB,WACG,GAAIm4B,GAAcC,CAClBD,GAAeh4B,EACfi4B,EAAe/0B,EAAKnD,SAASF,UAAUm4B,GACvC90B,EAAKnD,SAASF,UAAUm4B,GAAgB,WACpC,MAAOH,GAAaG,EAAcC,EAAcr3B,oBCr7DvE,WACG,YAEA1B,IAAGg5B,kBAAoB,SAASve,GAC5B,GAAIzW,GAAO/B,IAGXA,MAAKpB,UACD+kB,OAAO,EACPO,OAAQ,KACRlZ,UAAU,EACVwc,eAAgB,EAChBwP,6BAA6B,EAC7BxG,YAAY,EACZyG,kBAAkB,EAElBvP,SACIE,iBACAlJ,SAAU,iBACVwY,cAAe,aACfC,gBAAgB,EAChBvM,UAAW,SACXrD,OAAQ,OACR6P,mBAAmB,EACnB75B,UACA85B,cAAc,EACdC,oBAAoB,EACpBC,kBAAmB,kBACnB5P,SAAU,UAGd4C,YACIF,qBACAuH,UAAW,EACXC,aAAc,EACd0B,UAAW,EACXZ,wBAAwB,EACxB5Z,YAAa,KACbwd,OACIiB,UAAW,EACXC,SAAU,EACVC,UAAW,EACXC,SAAU,GAEdvB,YAAY,GAGhB13B,WACIs3B,SAAU,SAASpb,EAAI7b,KACvBi1B,YAAa,SAASpZ,EAAI7b,KAC1B0sB,WAAY,SAAS7Q,EAAI7b,EAAM+tB,EAAc8K,KAC7C1E,cAAe,SAASF,EAAYC,KACpCrH,SAAU,SAAShR,EAAI7b,KACvBktB,SAAU,SAASrR,EAAI7b,KACvBqtB,cAAe,SAASxR,EAAI7b,EAAMstB,KAClCI,qBAAsB,SAAS7R,EAAIyR,EAAWS,EAAcpB,KAC5DiB,SAAU,SAAS/R,EAAI/H,EAAUwZ,EAAWO,KAC5CvB,WAAY,SAASzQ,EAAI7b,EAAMusB,EAAQC,KACvCkJ,gBAAiB,SAASnJ,EAAQC,KAClCnE,QAAS,SAASxM,EAAI7b,EAAMqjB,EAAQyV,KACpChL,YAAa,SAASjS,EAAI7b,EAAM+4B,KAChCtE,cAAe,SAAS5Y,EAAI7b,KAC5Bo2B,gBAAiB,SAAS4C,KAC1BlF,WAAY,SAASkF,KACrB1D,eAAgB,SAASzZ,KACzBoN,SAAU,SAASpN,KACnBsN,iBAAkB,SAAStN,EAAIuN,EAAUC,KACzCO,gBAAiB,SAASnc,KAC1B4P,eAAgB,SAASxB,EAAI+B,EAAWD,KACxCkZ,yBAA0B,SAAStD,EAAUtlB,EAASmb,MAG1DoJ,UACIyG,UAAW,qEACXC,UAAW,yDACXC,aAAc,4DACdC,WAAY,yDACZC,aAAc,sBACdrD,kBAAmB,6EACnBsD,oBAAqB,qBACrBC,mBAAoB,qBACpBC,oBAAqB,4BACrBC,mBAAoB,4BACpBC,sBAAuB,mDACvBnD,QAAS,8EACTlD,6BAA8B,6KAGlCxN,OACI8P,YAAY,EACZoB,gBAAiB,EACjBzC,iBAAkB,EAClBjI,6BAA8B,gBAGlCZ,SACIE,YAAa,yBACbD,YAAa,0BAGjBzU,UACI8K,SAAS,EACT4X,YACI5X,SAAS,GAEb6X,WAAW,EACXC,YACIpM,UAAW,cACXqM,eAAgB,mBAChBC,UAAW,cACXC,cAAe,kBACfC,WAAY,gBAEhBC,SAAU,SAASre,GACf,MAAO,MAGX5N,SACI0R,SAAU,KAEVwG,QAAS,SAAStK,GACd,MAAO,OAGXse,aAAa,EAEb3R,OAAQ,OAERhqB,OAAQ,SAASqd,GACb,MAAO,OAGXue,mBAIRriB,QACIgK,SAAS,EACTsY,gBAAiB,EACjBR,YACIS,SAAU,YAEdC,WAAY,SAAShY,GACjB,WAIRqQ,eAAgB,SAAS4H,GACrB,MAAOA,IAGX3zB,MACI4sB,qBAAsB,gCACtB1H,eAAgB,aAChB6C,aAAc,KAAM,KAAM,KAAM,KAAM,KAAM,OAGhD3M,YACIF,SAAS,EACTyG,OAAQ,SACR7I,SAAU,iBACVkJ,iBACArqB,WAGJwqB,MACI6I,UAAU,EACV4I,iBAAiB,EACjB3I,UAAU,GAGdxR,OACIC,YAAa,aAGjBkJ,OACID,cAAe,KACfjJ,YAAa,gBAGjB4P,QACI5f,KAAK,EAGL4U,OAAQ,MASZ8J,gBAIA3J,SACI3F,SAAU,KACVnhB,UACAqqB,iBACAtD,gBAAgB,GAIpBxS,MAEIrR,QAAS,UAGT+vB,YAAY,EAGZiJ,iBAAiB,GAIrB1iB,SACI2iB,cAAe,KAGfC,cAAc,EAGdC,QAAQ,EAIRC,YAAa,KAEbC,eAAgB,GAEhBC,YAAa,kBAEbC,aAAa,EAGbC,UAGJ/P,aACIC,gBAAgB,EAChB+H,mBAAmB,EACnBvH,kBAAkB,IAK1B5sB,GAAGsG,OAAOrE,KAAKpB,SAAU4Z,GAAG,GAE5BxY,KAAKikB,YACLjkB,KAAK+tB,qBACL/tB,KAAKuiB,wBAELviB,KAAKy2B,iBACLz2B,KAAK+qB,gBAAmB,GAAIhtB,IAAG+U,eAE/B9S,KAAKif,cACLjf,KAAK8jB,gBACL9jB,KAAK+jB,kBACL/jB,KAAKgkB,mBACLhkB,KAAK8hB,kBAEL9hB,KAAKujB,qBAAuB,EAC5BvjB,KAAKmjB,aAAe,EACpBnjB,KAAKsgB,YAActgB,KAAK4pB,2BAExB5pB,KAAKmwB,4BAELnwB,KAAKmlB,oBAAsBnlB,KAAK8oB,aAAa9oB,KAAKpB,SAAS8oB,QAAQE,eACnE5nB,KAAKulB,8BAAgCvlB,KAAK8oB,aAAa9oB,KAAKpB,SAASoiB,WAAW4G,eAEhF5nB,KAAK2lB,uBAAyB3lB,KAAK8oB,aAAa9oB,KAAKpB,SAASoiB,WAAWzjB,QAEzEyC,KAAKyiB,eAAiBziB,KAAK8oB,aAAa9oB,KAAKpB,SAAS8oB,QAAQhJ,UAC9D1e,KAAKylB,yBAA2BzlB,KAAK8oB,aAAa9oB,KAAKpB,SAASoiB,WAAWtC,UAE3E1e,KAAKwgB,SAAWxgB,KAAKgrB,uBAErBhrB,KAAKs0B,eAAiBv2B,GAAGupB,yBAA2BtnB,KAAKqnB,uBAErDrnB,KAAKpB,SAASslB,SACdlkB,KAAKquB,iBAAmBruB,KAAKgqB,qBACzBvpB,QAAST,KAAKpB,SAASslB,OACvBtL,MAAO5Y,KAAKpB,SAASgH,KAAKklB,iBAC3B7Q,eAGPja,KAAK8tB,4BAEL9tB,KAAKivB,sBAEDjvB,KAAKpB,SAAS4pB,MAAMD,gBAChBxqB,GAAGuqB,aACHtoB,KAAKokB,cAAgBpkB,KAAKqoB,sBAG1BroB,KAAKG,IAAI,iCAAkC,UAInDH,KAAKpB,SAASq4B,kBAAoBj3B,KAAKo1B,0BAEvCp1B,KAAK6hB,gBAAkB9jB,GAAGm8B,gBAAkB,GAAIn8B,IAAGm8B,eAAen8B,GAAG0S,KAAKzQ,KAAKG,IAAKH,OACpFA,KAAKukB,sBAELvkB,KAAKwkB,kCACLxkB,KAAKykB,+BAELzkB,KAAKm6B,QAAWp8B,GAAGinB,QAAU,GAAIjnB,IAAGinB,OAAOhlB,KAAKpB,SAASmY,QAAShZ,GAAG0S,KAAKzQ,KAAKG,IAAKH,WAChFA,KAAKm6B,QAAQrZ,UACb9gB,KAAK0vB,sBAAwB3xB,GAAG0S,KAAKzQ,KAAKm6B,QAAQC,cAAep6B,KAAKm6B,UAGtEp8B,GAAGs8B,eAAiBt8B,GAAG2V,kBAAkBmD,cACzC7W,KAAK0kB,eAAiB,GAAI3mB,IAAGs8B,cACzBt8B,GAAG0S,KAAKzQ,KAAKw0B,iBAAkBx0B,MAE/B,SAAS4a,GACL,GAAI0f,GAAQv4B,EAAKue,YAAYjE,UAAUzB,GAAIA,GAC3C,OAAQ0f,IAASA,EAAMve,MAAS,KAK5C/b,KAAKsjB,kBAAoBtjB,KAAKpB,SAAS2rB,WAAWgJ,UAElDvzB,KAAK2kB,uBAAyB3kB,KAAK8oB,gBAIvC/qB,GAAGg5B,kBAAkBx3B,UAAYxB,GAAGwgB,cACpCxgB,GAAGsG,OAAOtG,GAAGg5B,kBAAkBx3B,UAAWxB,GAAG2oB,mBC3UjD3oB,GAAGw8B,cAAgB,SAAS/hB,GACxB,YA2CA,SAASgiB,KACL,MAAOz8B,IAAG2J,SAAS,MAAO,OAAQ,QAAS3K,EAAQwqB,SAAW,EAMlE,QAASkT,GAAyBvV,GAC9B,GAAIwV,IAAoB,CASxB,OAPA38B,IAAGY,KAAK+7B,EAAmB,SAAS/6B,EAAKg7B,GACrC,GAAI58B,GAAG2J,SAAS,SAAU,kBAAmB,mBAAoB,gBAAiBizB,GAAU,EAExF,MADAD,IAAoB,GACb,IAIRA,EAGX,QAASE,GAAMlP,GAEX,MAAO3uB,GAAQgrB,KAAK6I,UAAoCvyB,SAAxBqtB,EAAIxX,gBAIxC,QAAS2mB,KACL,GAAI1S,EAeJ,QAbIlhB,OAAOmE,gBAAkBnE,OAAOoE,iBAChC8c,EAAWpqB,GAAGmN,oBAEmB7M,SAA7B8pB,EAASjU,kBACTiU,EAAW,GAAI/T,gBAEf+T,EAASpb,OAAS,aAClBob,EAASlb,QAAU,aACnBkb,EAAS2S,UAAY,aACrB3S,EAAS4S,WAAa,eAIvB5S,EAIX,QAAS6S,GAAYpgB,EAAIqgB,GACrB,GAAI9S,GAAW+S,EAAYtgB,IAAOsgB,EAAYtgB,GAAI8Q,GAkBlD,OAhBKvD,KAEGA,EADA8S,EACWA,EAGPl+B,EAAQgrB,KAAK6I,SACFiK,IAGA98B,GAAGmN,oBAItBgwB,EAAYtgB,GAAI8Q,IAAMvD,GAGnBA,EAIX,QAASgT,GAAQvgB,GACb,GAEIwgB,GAFA9pB,EAAIvT,GAAG2J,QAAQ2zB,EAAOzgB,GACtBgT,EAAM7wB,EAAQyqB,qBAGX0T,GAAYtgB,GACnBygB,EAAMxe,OAAOvL,EAAG,GAEZ+pB,EAAMj5B,QAAUwrB,GAAOtc,EAAIsc,IAC3BwN,EAASC,EAAMzN,EAAM,GACrB0N,EAAYF,IAIpB,QAAS3P,GAAW7Q,EAAI2gB,GACpB,GAAI7P,GAAMsP,EAAYpgB,GAClB2M,EAASxqB,EAAQwqB,OACjBa,EAAUmT,KAAa,CAE3BJ,GAAQvgB,GAEJwN,EACAjoB,EAAIonB,EAAS,gBAAkB3M,EAAK,cAAe,SAE7CggB,EAAMlP,IAAS8P,EAAqB9P,EAAIxQ,UAC9CkN,GAAU,EACVjoB,EAAIonB,EAAS,gBAAkB3M,EAAK,+BAAiC8Q,EAAIxQ,OAAQ,UAGrFne,EAAQ0uB,WAAW7Q,EAAI8Q,EAAKtD,GAGhC,QAASqT,GAAU7gB,GACf,GAEIrd,GAFAm+B,EAAiBR,EAAYtgB,GAAI+gB,iBACjCC,EAAiB7+B,EAAQ6+B,cAqB7B,OAlBI7+B,GAAQ8qB,YAAYnF,MACpBnlB,EAASR,EAAQ8qB,YAAYnF,IAAI9H,IAGjC8gB,GACA39B,GAAGY,KAAK+8B,EAAgB,SAAS38B,EAAMZ,GACnCZ,EAASA,MACTA,EAAOwB,GAAQZ,IAInBy9B,GACA79B,GAAGY,KAAKi9B,EAAgB,SAAS78B,EAAMZ,GACnCZ,EAASA,MACTA,EAAOwB,GAAQZ,IAIhBZ,EAGX,QAAS+9B,GAAY1gB,EAAIihB,GACrB,GAIIC,GAJApQ,EAAMsP,EAAYpgB,EAAIihB,GACtBtU,EAASxqB,EAAQwqB,OACjBhqB,EAASk+B,EAAU7gB,GACnBmhB,EAAUb,EAAYtgB,GAAImhB,OA+C9B,OA5CAh/B,GAAQi/B,OAAOphB,GAEfkhB,EAAMG,EAAUrhB,EAAIrd,EAAQ29B,EAAYtgB,GAAIshB,uBAGxCtB,EAAMlP,IACNA,EAAI3e,OAASovB,EAAkBvhB,GAC/B8Q,EAAIze,QAAUmvB,EAAmBxhB,IAGjC8Q,EAAI2Q,mBAAqBC,EAA8B1hB,GAG3D2hB,EAA0B3hB,GAG1B8Q,EAAI8Q,KAAKjV,EAAQuU,GAAK,GAIlB/+B,EAAQgrB,KAAK6I,UAAY7zB,EAAQgrB,KAAKyR,kBAAoBoB,EAAMlP,KAChEA,EAAIxX,iBAAkB,GAG1BuoB,EAAW7hB,GAEXza,EAAI,WAAaonB,EAAS,gBAAkB3M,GAExCmhB,EACArQ,EAAIgR,KAAKX,GAEJY,IAAgCp/B,EACrCmuB,EAAIgR,OAECn/B,GAAUR,EAAQ6/B,aAAe7/B,EAAQ6/B,YAAY9+B,cAAc4J,QAAQ,sCAAwC,EACxHgkB,EAAIgR,KAAK3+B,GAAG+S,QAAQvT,EAAQ,KAEvBA,GAAUR,EAAQ6/B,aAAe7/B,EAAQ6/B,YAAY9+B,cAAc4J,QAAQ,qBAAuB,EACvGgkB,EAAIgR,KAAKvqB,KAAK0qB,UAAUt/B,IAGxBmuB,EAAIgR,KAAKn/B,GAGNmuB,EAGX,QAASuQ,GAAUrhB,EAAIrd,EAAQ2+B,GAC3B,GAAIxd,GAAW3hB,EAAQ+qB,cAAcpF,IAAI9H,GACrCkiB,EAAY5B,EAAYtgB,GAAIkiB,SAehC,OAZiBz+B,SAAby+B,IACApe,GAAY,IAAMoe,GAGlBH,GAA+Bp/B,IAC/BmhB,EAAW3gB,GAAG+S,QAAQvT,EAAQmhB,IAG9Bwd,IACAxd,EAAW3gB,GAAG+S,QAAQorB,EAAuBxd,IAG1CA,EAKX,QAAS4d,GAA8B1hB,GACnC,MAAO,YACgC,IAA/BogB,EAAYpgB,GAAImiB,YAChBtR,EAAW7Q,IAKvB,QAAS2hB,GAA0B3hB,GAC/B,GAAIyQ,GAAatuB,EAAQsuB,UAErBA,KACA2P,EAAYpgB,GAAIzP,OAAO4vB,WAAa,SAASjrB,GACrCA,EAAEktB,kBACF3R,EAAWzQ,EAAI9K,EAAEwb,OAAQxb,EAAEyb,SAQ3C,QAAS4Q,GAAkBvhB,GACvB,MAAO,YACH6Q,EAAW7Q,IAMnB,QAASwhB,GAAmBxhB,GACxB,MAAO,YACH6Q,EAAW7Q,GAAI,IAIvB,QAAS6hB,GAAW7hB,GAChB,GAAI8Q,GAAMsP,EAAYpgB,GAClBgN,EAAgB7qB,EAAQ6qB,cACxBqV,EAAkB/B,EAAYtgB,GAAIsiB,sBAClC3V,EAASxqB,EAAQwqB,OACjB4V,IAGCvC,GAAMlP,KACP3uB,EAAQqgC,cAAgB1R,EAAI2R,iBAAiB,SAAUtgC,EAAQqgC,cAG3DrgC,EAAQugC,qCAKHvgC,EAAQgrB,KAAK6I,UAAc4J,MAAoBC,EAAyB7S,KACzE8D,EAAI2R,iBAAiB,mBAAoB,kBACzC3R,EAAI2R,iBAAiB,gBAAiB,eAI1CtgC,EAAQ6/B,aAA2B,SAAXrV,GAAgC,QAAXA,GAC7CmE,EAAI2R,iBAAiB,eAAgBtgC,EAAQ6/B,aAGjD7+B,GAAGsG,OAAO84B,EAAYp/B,GAAGwK,WAAWqf,GAAiBA,EAAchN,GAAMgN,GACzE7pB,GAAGsG,OAAO84B,EAAYF,GAEtBl/B,GAAGY,KAAKw+B,EAAY,SAASp+B,EAAMZ,GAC/ButB,EAAI2R,iBAAiBt+B,EAAMZ,MAKvC,QAASq9B,GAAqB+B,GAC1B,MAAOx/B,IAAG2J,QAAQ3K,EAAQygC,wBAAwBzgC,EAAQwqB,QAASgW,IAAiB,EAGxF,QAASE,GAAc7iB,EAAIihB,EAAQiB,EAAWnB,EAAkBO,EAAuBgB,EAAmBnB,GAYtG,GAXAb,EAAYtgB,IACRkiB,UAAWA,EACXnB,iBAAkBA,EAClBO,sBAAuBA,EACvBgB,kBAAmBA,EACnBnB,QAASA,GAGHV,EAAMx7B,KAAK+a,IAGV7d,EAAQyqB,eACf,MAAO8T,GAAY1gB,EAAIihB,GA7U/B,GAAI17B,GAAKw8B,EACLtB,KACAH,KACAn+B,GACIqgC,aAAc,KACdM,cAAe,QAAS,OAAQ,OAChCnW,OAAQ,OACRqV,YAAa,oCACbpV,eAAgB,EAChBI,iBACAE,iBACAD,eACA+T,kBACA0B,oCAAoC,EACpCE,yBACIG,QAAS,IAAK,IAAK,KACnBC,OAAQ,IAAK,IAAK,IAAK,IAAK,KAC5BC,MAAO,IAAK,IAAK,IAAK,IAAK,KAC3BC,KAAM,IAAK,IAAK,IAAK,IAAK,KAC1BC,KAAM,MAEVhW,MACI6I,UAAU,EACV4I,iBAAiB,GAErBr5B,IAAK,SAASqJ,EAAKvB,KACnB+zB,OAAQ,SAASphB,KACjB6Q,WAAY,SAAS7Q,EAAIuN,EAAUC,KACnCiD,WAAY,KAMpB,IAHAttB,GAAGsG,OAAOtH,EAASyb,GACnBrY,EAAMpD,EAAQoD,IAEVpC,GAAG2J,QAAQ3K,EAAQ2gC,aAAc3gC,EAAQwqB,QAAU,EACnD,KAAM,IAAIvjB,OAAM,IAAMjH,EAAQwqB,OAAS,wDA8S3CoV,GAAiD,QAAnB5/B,EAAQwqB,QAAuC,WAAnBxqB,EAAQwqB,OAElExpB,GAAGsG,OAAOrE,MAENg+B,cAAe,SAASpjB,GACpB,GAAIqjB,GAAM1gC,EAAQ2nB,EAAS6W,EAASmC,EAAahC,CAEjD,QAEIiC,SAAU,SAASC,GAEf,MADAH,GAAOG,EACAp+B,MAOXq+B,WAAY,SAAS1C,GAEjB,MADAp+B,GAASo+B,EACF37B,MAGXs+B,gBAAiB,SAASC,GAEtB,MADArC,GAAwBqC,EACjBv+B,MAIXw+B,YAAa,SAAStB,GAElB,MADAhY,GAAUgY,EACHl9B,MAIXy+B,YAAa,SAASC,GAElB,MADA3C,GAAU2C,EACH1+B,MAIX2+B,gBAAiB,WAEb,MADAT,IAAc,EACPl+B,MAIX08B,KAAM,SAASb,GAKX,MAJIqC,IAAengC,GAAG2J,SAAS,MAAO,UAAW3K,EAAQwqB,SAAW,IAChEhqB,EAAOqhC,aAAc,GAAIC,OAAOC,WAG7BrB,EAAc7iB,EAAIihB,EAAQoC,EAAM1gC,EAAQ2+B,EAAuBhX,EAAS6W,MAK3FgD,SAAU,SAASnkB,GACfugB,EAAQvgB,OC1YpB7c,GAAGihC,cAAgB,SAASpjB,GACxB,YAEA,IAAIqjB,GAAQrjB,EAAKqjB,MACbC,KACAtT,EAAWqT,EAAMrT,SACjBrL,EAAU0e,EAAM1e,OAEpBxiB,IAAGsG,OAAOrE,MACNoR,IAAK,SAASwJ,EAAIukB,GACdD,EAAUtkB,GAAMukB,EAChBD,EAAUtkB,GAAI5J,SAGlBoP,OAAQ,SAASxF,GACb,GAAI7Y,GAAO/B,KACP6rB,EAA2B,GAAI9tB,IAAG+O,OACjB8e,GAAShR,EAAI2F,EAAQ3F,GAAKiR,GAEhCpU,KAAK,WACZ1V,EAAKqf,QAAQxG,KACbskB,EAAUtkB,GAAImkB,UAAW,EACzBh9B,EAAK8hB,QAAQjJ,IAEjBiR,EAAyB7e,aAIjC6W,QAAS,SAASjJ,SACPskB,GAAUtkB,IAGrBwkB,oBAAqB,SAASxkB,GAC1B,MAAOskB,GAAUtkB,GAAI1c,KAGzBkjB,QAAS,SAASxG,GACd,MAAyBvc,UAAlB6gC,EAAUtkB,IAGrBN,MAAO,WACH4kB,MAGJG,cAAe,SAASzkB,GACpB,MAAOskB,GAAUtkB,IAGrB0kB,qBAAsB,SAAS1kB,EAAI2kB,GAC/BL,EAAUtkB,GAAI1c,IAAMqhC,GAGxBC,aAAc,SAAS5kB,GACnB,QAASskB,EAAUtkB,GAAImkB,aCpDnChhC,GAAGyvB,wBAA0B,SAAShV,EAAG9a,GACrC,YAEA,IAGc+hC,GAAsBt/B,EAAKsvB,EAHrCiQ,EAAa1/B,KACb2/B,GAAmB,EACnBC,GAA6B,EAGjC7iC,GACI8qB,eACAL,eAAgB,EAChBxR,UACI8K,SAAS,EACT9V,UACI8V,SAAS,IAGjB3gB,IAAK,SAASqJ,EAAKvB,KACnBojB,WAAY,SAASzQ,EAAI/H,EAAUyY,EAAQC,KAC3CE,WAAY,SAAS7Q,EAAI/H,EAAUyf,EAAU5G,KAC7CE,SAAU,SAAShR,EAAI/H,KACvBkZ,aAAc,SAASnR,KACvBqR,SAAU,SAASrR,EAAI/H,KACvBuZ,cAAe,SAASxR,EAAI/H,EAAUwZ,KACtCI,qBAAsB,SAAS7R,EAAIyR,EAAWiG,EAAU5G,KACxDmB,YAAa,SAASjS,EAAI/H,EAAUyf,EAAU5G,KAC9CiB,SAAU,SAAS/R,EAAI/H,EAAUwZ,EAAWO,KAC5CI,cAAe,SAASpS,EAAImC,KAC5BwD,QAAS,SAAS3F,KAClBqS,QAAS,SAASrS,EAAIwC,KACtBgQ,SAAU,SAASxS,KACnB4C,mBAAoB,SAAS5C,KAC7B6C,cAAe,SAAS7C,KACxByS,aAAc,SAASzS,MAG3BilB,GAEI3nB,KAAM,SAAS0C,EAAIklB,EAAUxN,EAAU5G,GACnC,GAAIW,GAAYoD,EAAQsQ,cAAcnlB,EAAIklB,EAE1CrQ,GAAQ4P,cAAczkB,GAAIolB,kBAAmB,QAEtCvQ,GAAQ4P,cAAczkB,GAAI5J,KAAKivB,cAAcH,GACpDrQ,EAAQ4P,cAAczkB,GAAI0Q,QAAUe,EAAUtQ,KAE9Chf,EAAQ0vB,qBAAqB7R,EAAI6U,EAAQyQ,yBAAyB7T,GAAYiG,EAAU5G,IAK5FyU,SAAU,SAASvlB,GACf,GAAImB,GAAOhf,EAAQkmB,QAAQrI,GACvB7b,EAAOhC,EAAQwjB,QAAQ3F,EAE3Bza,GAAI,qCAAuCya,EAAK,qBAChD6U,EAAQ2Q,eAAexlB,GAAInD,KACvB,SAAS6a,EAAU5G,GACfvrB,EAAI,2BAA6Bya,EAEjC,IAAIylB,GAAoBl1B,EAAOm1B,kBAAkBhO,GAAU,EAE3Dv1B,GAAQsuB,WAAWzQ,EAAI7b,EAAMgd,EAAMA,GACnC0T,EAAQ8Q,+BAA+B3lB,GACvCzP,EAAOq1B,QAAQ5lB,EAAIylB,EAAmB3U,IAE1C,SAAS4G,EAAU5G,GACf,GAAI+U,GAAqBt1B,EAAOm1B,kBAAkBhO,GAAU,EAE5DnyB,GAAI,yCAA2Cya,EAAK,MAAQ6lB,EAAmBvgC,MAAO,UAGlFugC,EAAmBnmB,OAClBoR,GAAO3uB,EAAQiZ,SAAShJ,QAAQmsB,cAAczxB,QAAQgkB,EAAIxQ,SAAW,IAEtE2kB,EAAQvlB,MAAMM,GAGb7d,EAAQ8vB,YAAYjS,EAAI7b,EAAM0hC,EAAoB/U,IACnDvgB,EAAOq1B,QAAQ5lB,EAAI6lB,EAAoB/U,MAMvDgV,cAAe,SAASZ,EAAUllB,EAAI0X,EAAU5G,GAC5C,GAAI3sB,GAAOhC,EAAQwjB,QAAQ3F,EAE3Bza,GAAI,qCAAuCya,EAAK,WAAaklB,GAE7DrQ,EAAQkR,iBAAiB/lB,EAAIklB,EAE7B,IACIc,GADAC,EAAmB11B,EAAOm1B,kBAAkBhO,GAAU,EAG1D,IAAIuO,EAAiBvmB,MACjBulB,EAAQvlB,MAAMM,OAEb,CACD,GAAIkmB,GAAwBrR,EAAQ4P,cAAczkB,GAAI5E,SAAS+qB,UAE/DH,GAAgBE,EAAwB/iC,GAAG2J,QAAQo5B,EAAuBhB,IAAY,EAClFc,GAAiB,IACjBnR,EAAQ4P,cAAczkB,GAAI5E,SAAS+qB,WAAWlkB,OAAO+jB,EAAe,GACpEnR,EAAQ4P,cAAczkB,GAAI5E,SAASgrB,UAAUC,QAAQnB,IAMxDrQ,EAAQ4P,cAAczkB,GAAI5J,KAAKkwB,gBAG5BtB,IACAnQ,EAAQ4P,cAAczkB,GAAI5J,KAAKkwB,eAAgB,EAE/C/gC,EAAIpC,GAAGwL,OAAO,mFAAoF4I,KAAK0qB,UAAUx0B,OAAO84B,KAAK1R,EAAQ2R,SAASxmB,KAAOzI,KAAK0qB,UAAUpN,EAAQ4P,cAAczkB,GAAI5E,SAAS+qB,cACvMhjC,GAAGY,KAAK8wB,EAAQ2R,SAASxmB,GAAK,SAASymB,EAAMC,GACzCnhC,EAAIpC,GAAGwL,OAAO,sDAAuDqR,EAAIymB,EAAMC,EAAMvE,aACrFuE,EAAMC,QAGND,EAAME,YAAa,IAIvB/R,EAAQgS,0BAA0B7mB,GAIlC8mB,EAAkBC,KAAK/mB,GAAI,IAG1B7d,EAAQ8vB,YAAYjS,EAAI7b,EAAM8hC,EAAkBnV,IAIjDvgB,EAAOq1B,QAAQ5lB,EAAIimB,EAAkBnV,KAKjDkW,aAAc,SAAShnB,GACnB,QAAS6U,EAAQ4P,cAAczkB,GAAI5E,SAASgrB,UAAU5+B,QAG1Dy/B,SAAU,SAASjnB,GACf,GAAIknB,GAAUrS,EAAQ4P,cAAczkB,GAAI5E,SAASgrB,UAAU9tB,OAM3D,OAJI4uB,IAAWrS,EAAQsS,gBAAgBnnB,KACnCknB,EAAU,MAGPA,GAGXxnB,MAAO,SAASM,GACZza,EAAI,8FAAgGya,EAAI;2GAExG6U,EAAQ8Q,+BAA+B3lB,GACvC6U,EAAQuS,mBAAmBpnB,GAC3B6U,EAAQ4P,cAAczkB,GAAI0Q,OAAS,EACnCmE,EAAQ4P,cAAczkB,GAAIolB,kBAAmB,GAGjDiC,SAAU,SAASrnB,GACf,GAAImB,GAAOhf,EAAQkmB,QAAQrI,GACvB7b,EAAOhC,EAAQwjB,QAAQ3F,GACvBklB,EAAWD,EAAQgC,SAASjnB,GAC5ByR,EAAYoD,EAAQsQ,cAAcnlB,EAAIklB,GACtCZ,EAAYzP,EAAQ4P,cAAczkB,GAClCye,EAAW6F,EAAUc,iBACrBkC,EAAmBhD,EAAUlpB,SAAS+qB,cAe1C,IAbwB,MAApB7B,EAAU5T,SACV4T,EAAU5T,OAAS,GAInB+N,GAAYt8B,EAAQ4vB,SAAS/R,EAAI7b,EAAMstB,EAAW6S,EAAUtS,qBAAsB,IAClFiT,EAAQvlB,MAAMM,GACdklB,EAAWD,EAAQgC,SAASjnB,GAC5ByR,EAAYoD,EAAQsQ,cAAcnlB,EAAIklB,GACtCzG,GAAW,GAIC,MAAZyG,GAAgD,IAA5BoC,EAAiB9/B,OACrCy9B,EAAQM,SAASvlB,OAIhB,CACDsnB,EAAiBriC,KAAKigC,GACtBrQ,EAAQ4P,cAAczkB,GAAI5E,SAAS+qB,WAAamB,EAE5CtC,GACA8B,EAAkBlF,KAAK5hB,EAAIklB,GAG3BF,GAA8B8B,EAAkBS,aAAe1S,EAAQ4P,cAAczkB,GAAI5E,SAASgrB,UAAU5+B,QAC5Gy9B,EAAQoC,SAASrnB,GAGO,IAAxByR,EAAU7f,KAAKuP,OACf5b,EAAIpC,GAAGwL,OAAO,+DAAgEu2B,EAAUllB,GAAK,SAC7FilB,EAAQa,cAAcZ,EAAUllB,EAAI,8BAA+B,MAG5C7d,GAAQqvB,cAAcxR,EAAI7b,EAAM0wB,EAAQyQ,yBAAyB7T,IAEvE5U,KACjB,SAAS2qB,GACL,GAAKrlC,EAAQswB,aAAazS,GAGrB,CACDza,EAAIpC,GAAGwL,OAAO,oEAAqEqR,EAAIklB,EAAUzT,EAAUrgB,MAAQ,EAAGqgB,EAAUpgB,IAAK8P,GAErI,IAAIsmB,IACAvC,SAAUA,EACVllB,GAAIA,EACJ0nB,UAAWF,EACX/I,SAAUA,EAGd5J,GAAQ8S,YAAYF,GAAiB5qB,KAEjC,SAAiB6a,EAAU5G,GACvBvrB,EAAI,wCAA0Cya,EAAK,WAAaklB,GAEhErQ,EAAQkR,iBAAiB/lB,EAAIklB,EAE7B,IAAIoC,GAAmBzS,EAAQ4P,cAAczkB,GAAI5E,SAAS+qB,eACtDF,EAAmB11B,EAAOm1B,kBAAkBhO,GAAU,GACtDkQ,EAAqBzkC,GAAG2J,QAAQw6B,EAAkBpC,EAEtD3/B,GAAIpC,GAAGwL,OAAO,8CAA+Cu2B,EAAUllB,IAEvEilB,EAAQ3nB,KAAK0C,EAAIklB,EAAUe,EAAkBnV,GAEzC8W,GAAsB,GACtBN,EAAiBrlB,OAAO2lB,EAAoB,GAGhD/S,EAAQgT,0BAA0B7nB,GAE7BilB,EAAQ+B,aAAahnB,IAAmC,IAA5BsnB,EAAiB9/B,OAGzCy9B,EAAQ+B,aAAahnB,GAC1BilB,EAAQoC,SAASrnB,GAGjBza,EAAIpC,GAAGwL,OAAO,oGAAqGqR,EAAIzI,KAAK0qB,UAAUqF,KANtIrC,EAAQM,SAASvlB,IAWzB,SAAiB0X,EAAU5G,GACvBmU,EAAQa,cAAcZ,EAAUllB,EAAI0X,EAAU5G,KAGjDxT,KAAK,WACFuX,EAAQiT,SAAS9nB,EAAIklB,SAlD7B3/B,GAAIpC,GAAGwL,OAAO,6EAA8EqR,EAAIklB,KAuDxG,SAAS5/B,GACL2/B,EAAQa,cAAcZ,EAAUllB,EAAI1a,EAAO,WAO/DwhC,GACIiB,SACAC,eACAC,YAEAV,UAAW,WACP,GAAIvU,GAAM7wB,EAAQyqB,eACdsb,EAAwB,EACxBC,EAAkB,CAOtB,OALAhlC,IAAGY,KAAK+iC,EAAkBkB,YAAa,SAASthB,EAAQ0hB,GACpDF,IACAC,GAAmBC,EAAiB5gC,SAGjCwrB,GAAO8T,EAAkBiB,MAAMvgC,OAAS0gC,EAAwBC,IAM3EpB,KAAM,SAAS/mB,EAAIqoB,GACf,GAGI7H,GAHA8H,GAAaD,EACbE,EAAeplC,GAAG2J,QAAQg6B,EAAkBmB,SAAUjoB,GACtDwoB,EAAmBrlC,GAAG2J,QAAQg6B,EAAkBiB,MAAO/nB,SAGpD8mB,GAAkBkB,YAAYhoB,GAEjCzP,EAAOk4B,eAAezoB,YAAe7c,IAAGoa,YACxChY,EAAI,uCAAyCya,EAAK,qCAC3C6U,GAAQ4P,cAAczkB,GAAIoB,MAIjCmnB,GAAgB,EAChBzB,EAAkBmB,SAAShmB,OAAOsmB,EAAc,GAG3CD,GAAaE,GAAoB,IACtC1B,EAAkBiB,MAAM9lB,OAAOumB,EAAkB,GAEjDhI,EAASsG,EAAkBmB,SAAS3vB,QAChCkoB,GAAU,IACVsG,EAAkBiB,MAAM9iC,KAAKu7B,GAC7BjwB,EAAOa,MAAMovB,MAKzBkI,sBAAuB,WACnB,GAAIC,KAqBJ,OAjBAxlC,IAAGY,KAAK+iC,EAAkBkB,YAAa,SAASthB,EAAQkiB,GAChDA,GAAUA,EAAOphC,QACjBmhC,EAAmB1jC,KAAK4jC,SAASniB,MAMzCvjB,GAAGY,KAAK+iC,EAAkBiB,MAAO,SAAShjC,EAAK2hB,GACtCogB,EAAkBkB,YAAYthB,IAC/BiiB,EAAmB1jC,KAAK4jC,SAASniB,MAKzCiiB,EAAqBA,EAAmB1yB,OAAO6wB,EAAkBmB,WAKrEa,kBAAmB,SAAS9oB,GACxB,MAAO7c,IAAG2J,QAAQg6B,EAAkBiB,MAAO/nB,IAAO,GAGtD4hB,KAAM,SAAS5hB,EAAIklB,GAKf,MAJgB,OAAZA,GACA4B,EAAkBmB,SAAShjC,KAAK+a,KAGhC8mB,EAAkBS,cACF,MAAZrC,GACA4B,EAAkBmB,SAASc,MAC3BjC,EAAkBiB,MAAM9iC,KAAK+a,IAG5B,WACG,GAAIgpB,GAAkBlC,EAAkBkB,YAAYhoB,MACpDgpB,GAAgB/jC,KAAKigC,GACrB4B,EAAkBkB,YAAYhoB,GAAMgpB,MAIrC,IAMftpB,MAAO,WACHonB,EAAkBmB,YAClBnB,EAAkBiB,WAI1BkB,GACInH,KAAM,SAAS9hB,EAAI7b,GACf,GAAImgC,GAAYzP,EAAQ4P,cAAczkB,EAEtC,KAAKskB,EAED,WADA/+B,GAAI,yEAA2Eya,EAAI,OAIvFskB,GAAU5T,OAAS,EAEnBnrB,EAAI,qCAAuCya,GAC3C6U,EAAQqU,WAAWlpB,GAAInD,KACnB,SAAS6a,EAAUuJ,GACf17B,EAAI,uCAAyCya,EAE7C,IAAIimB,GAAmB11B,EAAOm1B,kBAAkBhO,GAAU,GACtDvW,EAAOhf,EAAQkmB,QAAQrI,EAE3B7d,GAAQsuB,WAAWzQ,EAAI7b,EAAMgd,EAAMA,GACnC5Q,EAAO44B,aAAanpB,EAAIimB,GACxB11B,EAAOq1B,QAAQ5lB,EAAIimB,EAAkBhF,IAGzC,SAASvJ,EAAUuJ,GACf17B,EAAI,oCAAsCya,EAE1C,IAAIimB,GAAmB11B,EAAOm1B,kBAAkBhO,GAAU,EAErDv1B,GAAQ8vB,YAAYjS,EAAI7b,EAAM8hC,EAAkBhF,IACjD1wB,EAAOq1B,QAAQ5lB,EAAIimB,EAAkBhF,OAOzD1wB,GACIiV,OAAQ,SAASxF,GACbza,EAAI,cAAgBya,GACpB7d,EAAQ8qB,YAAYjkB,OAAOgX,GAC3B8mB,EAAkBC,KAAK/mB,IAG3B4lB,QAAS,SAAS5lB,EAAI0X,EAAUuJ,GAC5B,GAAI98B,GAAOhC,EAAQwjB,QAAQ3F,EAE3B7d,GAAQ0uB,WAAW7Q,EAAI7b,EAAMuzB,EAAUuJ,GAEnCpM,EAAQ4P,cAAczkB,IACtB6U,EAAQuU,YAAcvU,EAAQuU,WAAWppB,GAG7C8mB,EAAkBC,KAAK/mB,IAK3ByoB,eAAgB,SAASzoB,GACrB,MAAQ6U,GAAQwU,UAAYxU,EAAQwU,SAASrpB,IACxC6U,EAAQzN,SAAWyN,EAAQzN,QAAQpH,IAG5CspB,YAAa,WAITzU,EAAU,IAHQ/xB,EAAYK,GAAGL,GAAaK,GAAGomC,cACtBpmC,GAAG2V,kBAAkBmC,cAAgB,MAAQ,QAEvB,iBAC7C9Y,GAEIuwB,oBAAqBvwB,EAAQuwB,oBAC7BH,cAAepwB,EAAQowB,cACvB5M,QAASxjB,EAAQwjB,QACjB0C,QAASlmB,EAAQkmB,QACjBO,QAASzmB,EAAQymB,QACjBrjB,IAAKA,EACLyrB,SAAU7uB,EAAQ6uB,SAClBP,WAAYtuB,EAAQsuB,WACpB2B,cAAejwB,EAAQiwB,cACvBoX,aAAc,SAASxpB,GACnB7d,EAAQ0f,UAAU7B,EAAI7c,GAAGmd,OAAO8C,sBAKxCyR,EAAQ4U,+BACR5U,EAAQ4U,iCAIhBC,4BAA6B,SAAS1pB,GAClC,MAAO7d,GAAQqwB,SAASxS,IAM5B2pB,WAAY,SAAS3pB,EAAIpO,GAIrB,MAAIA,KAASijB,EAAQzN,QAAQpH,IAAOpO,YAAgBzO,IAAGoa,WAKnDpb,EAAQgvB,aAAanR,GAErBza,EAAI,+CAAiDya,GACrDpO,EAAK8L,SAASb,KAAK,SAAS+sB,GACxBrkC,EAAI,mCAAqCya,GAGzC6U,EAAQgV,WAAW7pB,EAAI4pB,GAGvBznC,EAAQkwB,QAAQrS,EAAI4pB,EAAczoB,MAGlC0T,EAAQuS,mBAAmBpnB,GAE3BzP,EAAOu5B,uBAAuB9pB,IAIlC,SAAS0L,GACL,GAAIqe,KAEAre,KACAqe,EAAczkC,MAAQomB,GAG1BnmB,EAAIpC,GAAGwL,OAAO,yDAA0DqR,EAAI0L,GAAe,SAE3FvpB,EAAQ0uB,WAAW7Q,EAAI7d,EAAQwjB,QAAQ3F,GAAK7c,GAAGsG,OAAOsgC,EAAelF,GAAuB,MAC5Ft0B,EAAOu5B,uBAAuB9pB,GAC9B8mB,EAAkBC,KAAK/mB,MAOxB,GAHIzP,EAAOu5B,uBAAuB9pB,IAO7C8pB,uBAAwB,SAAS9pB,GAC7B,GAAIgqB,GAAa7nC,EAAQygB,mBAAmB5C,GACxCiqB,GAAiB,CAoBrB,OAlBID,IAAcA,EAAWxiC,QACzBjC,EAAI,0CAA4Cya,GAEhD7c,GAAGY,KAAKimC,EAAY,SAASjlC,EAAKmlC,GAC9B,GAAI35B,EAAOm5B,4BAA4BQ,IAAgBrV,EAAQzN,QAAQ8iB,GACnED,EAAiBC,IAAclqB,EAC/BzP,EAAO45B,IAAID,OAEV,IAAI35B,EAAOm5B,4BAA4BQ,GACxC,OAAO,MAKfD,GAAiB,EACjB15B,EAAO45B,IAAInqB,IAGRiqB,GAGXd,aAAc,SAASnpB,EAAI0X,GACEj0B,SAArBi0B,EAASvV,SACThgB,EAAQiwB,cAAcpS,EAAI0X,EAASvV,UAO3CujB,kBAAmB,SAAS0E,EAAkBhS,GAC1C,GAAIV,GAAW0S,CAcf,OAVKjnC,IAAGoK,SAAS68B,KACb1S,KAEIv0B,GAAGkL,SAAS+7B,KAAsBhS,IAClCV,EAASpyB,MAAQ8kC,IAIzB1S,EAAStlB,QAAUgmB,EAEZV,GAGXyS,IAAK,SAASnqB,GACV,GAAI7b,GAAOhC,EAAQwjB,QAAQ3F,EAE3B,KAAK8kB,EAAWte,QAAQxG,GACpB,KAAM,IAAI7c,IAAGiG,MAAM4W,EAAK,qCAG5B7d,GAAQkvB,SAASrR,EAAI7b,GAAM0Y,KACvB,SAAS6a,GACDA,GAAYA,EAAS1b,OACrB7Z,EAAQ0f,UAAU7B,EAAI7c,GAAGmd,OAAO4C,QAChC2R,EAAQ7Y,MAAMgE,GACd8mB,EAAkBC,KAAK/mB,IAGnB+kB,GAAoBlQ,EAAQwV,qBAAqBrqB,GACjDilB,EAAQoC,SAASrnB,GAGjBipB,EAAOnH,KAAK9hB,EAAI7b,IAK5B,SAASmB,GAKL,GAJAA,EAAQA,MAERC,EAAIya,EAAK,qEAAuE1a,EAAO,UAElFnD,EAAQ8vB,YAAYjS,EAAI7b,EAAMmB,EAAM4sB,kBAAqB,CAC1D,GAAIwF,GAAWnnB,EAAOm1B,kBAAkBpgC,EAAM4sB,cAAc,EAC5D3hB,GAAOq1B,QAAQ5lB,EAAI0X,OAMnCtmB,MAAO,SAAS4O,GACZ,GAAIsqB,GAAe/5B,EAAOk4B,eAAezoB,EAEzC,OAAIsqB,GACO/5B,EAAOo5B,WAAW3pB,EAAIsqB,IAG7B/5B,EAAO45B,IAAInqB,IACJ,IAKnB7c,IAAGsG,OAAOrE,MAINoR,IAAK,SAASwJ,EAAIoB,GACdyT,EAAQre,IAAIrR,MAAMC,KAAMP,YAM5B0L,OAAQ,SAASyP,GACb,QAAI8mB,EAAkBlF,KAAK5hB,IAChBzP,EAAOa,MAAM4O,IAK5BgK,MAAO,SAAShK,GAWZ,MANIglB,KACAnQ,EAAQ4P,cAAczkB,GAAI5J,KAAKkwB,eAAgB,GAK/CQ,EAAkBgC,kBAAkB9oB,GAC7BzP,EAAOa,MAAM4O,GAOb8kB,EAAWv0B,OAAOyP,IAOjCwF,OAAQ,SAASxF,GACb,GAAIuqB,GAAe1V,EAAQrP,OAAOxF,EAE9B7c,IAAGwZ,iBAAiB4tB,GACpBA,EAAa1tB,KAAK,WACdtM,EAAOiV,OAAOxF,KAGbuqB,KAAiB,GACtBh6B,EAAOiV,OAAOxF,IAOtB6F,UAAW,WACP,GACInP,GADAiyB,EAAqB7B,EAAkB4B,uBAK3C,IAAIC,EAAmBnhC,OACnB,IAAKkP,EAAIiyB,EAAmBnhC,OAAS,EAAGkP,GAAK,EAAGA,IAC5CouB,EAAWtf,OAAOmjB,EAAmBjyB,GAI7CowB,GAAkBpnB,SAKtB0H,QAAS,SAASpH,GACd,MAAI6U,GAAQwU,UAAYxU,EAAQwU,SAASrpB,GAC9B6U,EAAQwU,SAASrpB,GAAIxC,cAGzBqX,EAAQzN,SAAWyN,EAAQzN,QAAQpH,IAI9CwqB,UAAW,SAASxqB,GAChB,SAAU6U,EAAQwU,WAAYxU,EAAQwU,SAASrpB,KAGnDZ,SAAU,SAASY,GACf,GAAI6U,EAAQzV,SACR,MAAOyV,GAAQzV,SAASY,IAIhCN,MAAO,WACHna,EAAI,4BACJu/B,EAAWjf,YACXihB,EAAkBpnB,QAClBmV,EAAQnV,SAGZuJ,QAAS,SAASjJ,GACd,GAAI8kB,EAAWte,QAAQxG,GACnB,MAAO6U,GAAQ5L,QAAQjJ,IAO/BwG,QAAS,SAASxG,GACd,MAAO6U,GAAQrO,QAAQxG,IAG3B8I,gBAAiB,SAAS9I,GACtB,GAAI1c,GAAMuxB,EAAQrO,QAAQxG,IACtB6U,EAAQ4V,oBACR5V,EAAQ4V,mBAAmBzqB,EAE/B,SAAI1c,KACSuW,aAAajE,QAAQtS,IAMtC8kB,sBAAuB,WACnB,MAAIyM,GAAQzM,sBACDyM,EAAQzM,4BAavBoc,oBAAqB,SAASxkB,GAC1B,GAAI8kB,EAAWte,QAAQxG,GACnB,MAAO6U,GAAQ2P,oBAAoBxkB,IAS3ChE,MAAO,SAASgE,GACZ,SAAI8kB,EAAWjc,YAAY7I,IAAO6U,EAAQ7Y,OAAS8oB,EAAWte,QAAQxG,IAAO6U,EAAQ7Y,MAAMgE,MACvF8mB,EAAkBC,KAAK/mB,GACvB6U,EAAQgS,0BAA0B7mB,IAC3B,IAKf0qB,mBAAoB,SAAS1qB,GACzB,QAAS6U,EAAQ6V,oBAAsB7V,EAAQ6V,mBAAmB1qB,IAItE6I,YAAa,SAAS7I,GAClB,QAAS6U,EAAQhM,aAAegM,EAAQhM,YAAY7I,MAI5D7c,GAAGsG,OAAOtH,EAASyb,GACnBrY,EAAMpD,EAAQoD,IACdw/B,EAAmB5iC,EAAQiZ,SAAS8K,SAAW/iB,GAAG2V,kBAAkBsC,SACpE4pB,EAA6BD,GAAoB5iC,EAAQiZ,SAAS0iB,WAAW5X,QAE7E2e,EAAwB,WACpB,GAAInN,KAIJ,OAFAA,GAASv1B,EAAQouB,oBAAqB,EAE/BmH,KAGXnnB,EAAO+4B,eC1zBXnmC,GAAGwnC,qBAAuB,SAAS/sB,GAC/B,YAEA,IAAIzb,IACIoD,IAAK,SAASC,EAAS6H,MAE3Bu9B,IAEJznC,IAAGsG,OAAOtH,EAASyb,GAEnBza,GAAGsG,OAAOrE,MACNylC,eAAgB,SAAS7qB,EAAIvK,GACzB,GAAIq1B,GAA2B,SAASrQ,GAChChlB,EAASglB,EAAMj3B,MAGnB6I,QAAO2O,YACP4vB,EAAyB5qB,GAAM7c,GAAGkJ,QAAQjE,OAAO,UAAW0iC,GAG5DvlC,IAAI,wDAAyD,UAIrEwlC,sBAAuB,SAAS/qB,GAC5B,GAAI3T,OAAO2O,YAAa,CACpB,GAAIgwB,GAAWJ,EAAyB5qB,EACpCgrB,IACAA,SCvBpB7nC,GAAG8nC,kBAAoB,SAASjqB,GAC5B,YAoBA,SAASkqB,GAAYlrB,SACVmrB,GAAiBnrB,GAKpBorB,IACAvS,aAAawS,EAA0BrrB,UAChCqrB,GAA0BrrB,GACjCsrB,EAAoBP,sBAAsB/qB,GAG9C,IAAIurB,GAASr7B,SAASs7B,eAAe3W,EAAQ4W,eAAezrB,GACxDurB,KAIAA,EAAOp0B,aAAa,MAAO,qBAE3BhU,GAAGooC,GAAQviC,UAQnB,QAAS0iC,GAAuBC,GAC5B,MAAOA,GAAW9+B,MAAM,KAAK,GAUjC,QAAS++B,GAAoBznC,GACzB,GAAIonC,GAASpoC,GAAGiS,UAAU,yCAA2CjR,EAAO,OAO5E,OALAonC,GAAOp0B,aAAa,KAAMhT,GAE1BonC,EAAOrjC,MAAMC,QAAU,OACvB+H,SAAS27B,KAAKz0B,YAAYm0B,GAEnBA,EAUX,QAASO,GAA4BP,EAAQ91B,GACzC,GAAIk2B,GAAaJ,EAAOvrB,GACpB0G,EAASglB,EAAuBC,EAGpCI,GAFWnjB,EAAQlC,IAEKjR,EAIxB01B,EAAiBzkB,GAAUvjB,GAAGooC,GAAQnjC,OAAO,OAAQ,WAC7CysB,EAAQzV,SAASsH,KACjBnhB,EAAI,mEAAqEomC,EAAa,KAEtFN,EAA0BM,GAAcxc,WAAW,WAC/C,GAAIzD,GAAe,gEAAkEigB,CACrFpmC,GAAImmB,EAAc,SAClBjW,GACInQ,MAAOomB,KAEZ,QAMX4f,EAAoBT,eAAec,EAAY,SAASnmC,GACpDD,EAAI,2CAA6CC,EAAU,IAC3D,IAGIwmC,GAFAtU,GADSgU,EAAuBC,GACrB9W,EAAQoX,mBAAmBzmC,IACtC2a,EAAOuX,EAASvX,IAGhBA,IAAQ4rB,EAAgB5rB,IACxB5a,EAAI,qCAAuComC,GAC3C9S,aAAawS,EAA0BM,UAChCN,GAA0BM,GAEjC9W,EAAQqX,iBAAiBP,GAEzBK,EAAiBD,EAAgB5rB,SAE1B4rB,GAAgB5rB,GACvBmrB,EAAoBP,sBAAsBY,GAC1CK,EAAetU,IAETvX,GACN5a,EAAI,IAAMC,EAAU,2CAxHhC,GAAIrD,GAAU6e,EAAK7e,QACf0yB,EAAUzvB,KACVi/B,EAAQrjB,EAAKqjB,MACb8H,EAAwBhpC,GAAGkQ,cAC3B04B,KACAZ,KACAE,KACAD,EAASjpC,EAAQipC,OACjBpb,EAAY7tB,EAAQ6tB,UACpBpH,EAAUyb,EAAMzb,QAChBrjB,EAAM8+B,EAAM9+B,IACZ+lC,EAAsB,GAAInoC,IAAGwnC,sBAAsBplC,IAAKA,GAkH5DpC,IAAGsG,OAAOrE,KAAM,GAAIjC,IAAGihC,cAAcpjB,IAErC7d,GAAGuP,SAAStN,KAAM,SAASyN,GACvB,OAII2D,IAAK,SAASwJ,EAAI4T,GACd/gB,EAAO2D,IAAIwJ,GAAK/P,MAAO2jB,IAEvBA,EAAUzc,aAAa,OAAQ6Y,GAG3B4D,EAAU7qB,YACV5F,GAAGywB,GAAW5qB,UAItBigB,QAAS,SAASjJ,GACdkrB,EAAYlrB,GACZnN,EAAOoW,QAAQjJ,IAGnBwG,QAAS,SAASxG,GACd,MAAOnN,GAAO2T,QAAQxG,IACkBvc,SAApCoxB,EAAQ4P,cAAczkB,GAAI/P,UAK1C9M,GAAGsG,OAAOrE,MACNga,SAAU,SAASY,GACf,MAAO6U,GAAQ4P,cAAczkB,GAAI/P,OAWrCm8B,iBAAkB,SAASb,EAAQ91B,GAE/B,GAAI42B,EAEAjB,GACAU,EAA4BP,EAAQ91B,GAGpC01B,EAAiBI,EAAOvrB,IAAM7c,GAAGooC,GAAQnjC,OAAO,OAAQ,WAMpD,GALA7C,EAAI,yBAA2BgmC,EAAOvrB,IAKjCurB,EAAOxiC,WAAZ,CAIA,IAEI,GAAIwiC,EAAOe,iBACPf,EAAOe,gBAAgBT,MACkB,SAAzCN,EAAOe,gBAAgBT,KAAKt2B,UAK5B,OAGR,MAAOjQ,GAEHC,EAAI,8EAAgFD,EAAME,QAAU,IAAK,SACzG6mC,GAAsBj6B,SAAS,GAGnCqD,EAAS42B,OAWrBE,cAAe,SAASvsB,GAGpB,MAAO4rB,GAFU/W,EAAQ4W,eAAezrB,KAU5CksB,iBAAkB,SAASlsB,GACMvc,SAAzB0nC,EAAiBnrB,KACjBmrB,EAAiBnrB,WACVmrB,GAAiBnrB,KAQhCyrB,eAAgB,SAAS/kB,GACrB,MAAOA,GAAS,IAAMylB,GAY1BK,mBAAoB,SAASxrB,GACzB,GAAI2L,GAAS3L,EAAK2L,OACd7I,EAAW9C,EAAK8C,SAChBnhB,EAASqe,EAAKre,OACd85B,EAAezb,EAAKyb,aACpBgQ,EAAazrB,EAAKyrB,WAClBv1B,EAAO/T,GAAGiS,UAAU,iBAAmBuX,EAAS,2CAChDuU,EAAMpd,CAcV,OAZI2Y,GACAt5B,GAAG8T,WAAWtU,EAAQuU,GAGtBgqB,EAAM/9B,GAAG+S,QAAQvT,EAAQmhB,GAG7B5M,EAAKC,aAAa,SAAU+pB,GAC5BhqB,EAAKC,aAAa,SAAUs1B,GAC5Bv1B,EAAKhP,MAAMC,QAAU,OACrB+H,SAAS27B,KAAKz0B,YAAYF,GAEnBA,GAOX+0B,mBAAoB,SAASS,GACzB,GAAIhV,KAEJ,KACIA,EAAWv0B,GAAGkU,UAAUq1B,GAE5B,MAAOpnC,GACHC,EAAI,0DAA4DD,EAAME,QAAU,IAAK,SAGzF,MAAOkyB,OCnSnBv0B,GAAGwpC,iBAAmB,SAAS3rB,GAC3B,YAqCA,SAAS2lB,GAAM3mB,GACX7c,GAAGY,KAAK8wB,EAAQ2R,SAASxmB,GAAK,SAAS4sB,EAAO9b,GAC1C,GAAI+b,GAAgBhY,EAAQiY,kBAAkB9sB,EAAI4sB,EAElD9b,GAAI2Q,mBAAqB,KACzB3Q,EAAIvgB,OAAO4vB,WAAa,KACxBrP,EAAI6V,QACJkG,GAAiBA,EAAc1I,UAAY0I,EAAc1I,SAASnkB,KA1C1E,GAAI6U,GAAUzvB,KACVtC,EAAYke,EAAK7e,QAAQW,UACzBuhC,EAAQrjB,EAAKqjB,MACbjpB,EAAW4F,EAAK7e,QAAQiZ,SACxB2xB,EAAe,SAAS/sB,GACpB,GAAIskB,GAAYzP,EAAQ4P,cAAczkB,EAEtC,IAAIskB,EAAUpG,UACV,MAAOoG,GAAUpG,SAIjB,IAAIA,GAAY9iB,EAASijB,QAOzB,OALIl7B,IAAGwK,WAAWuwB,KACdA,EAAYA,EAAUle,EAAIqI,EAAQrI,KAGtCskB,EAAUpG,UAAYA,EACfA,GAGfhiB,EAAS8E,EAAK7e,QAAQ+Z,OACtB8wB,EAAa5xB,GAAY4F,EAAK7e,QAAQiZ,SAAS8K,SAAW/iB,GAAG2V,kBAAkBsC,SAC/E6xB,EAAgB/wB,GAAU8E,EAAK7e,QAAQ+Z,OAAOgK,SAAW8mB,GAAc7pC,GAAG2V,kBAAkBoD,OAC5FyJ,EAAU0e,EAAM1e,QAChB0C,EAAUgc,EAAMhc,QAChBO,EAAUyb,EAAMzb,QAChBhB,EAAcyc,EAAMzc,YACpB2K,EAAgB8R,EAAM9R,cACtBH,EAAgBiS,EAAMjS,cACtB3B,EAAa4T,EAAM5T,WACnBlrB,EAAM8+B,EAAM9+B,IACZmtB,EAAsB2R,EAAM3R,mBAahCvvB,IAAGsG,OAAOrE,KAAM,GAAIjC,IAAGihC,cAAcpjB,IAErC7d,GAAGuP,SAAStN,KAAM,SAASyN,GACvB,OAII2D,IAAK,SAASwJ,EAAIktB,GACd,GAAI/pC,GAAG4L,OAAOm+B,IAAgB/pC,GAAG2M,OAAOo9B,GACpCr6B,EAAO2D,IAAIwJ,GAAKoB,KAAM8rB,QAErB,CAAA,KAAIA,YAAuB/pC,IAAGoa,WAI/B,KAAM,IAAInU,OAAM,2CAHhByJ,GAAO2D,IAAIwJ,GAAKqkB,MAAO6I,IAM3BrY,EAAQsY,eAAentB,GACvBitB,GAAiBpY,EAAQuY,uBAAuBptB,IAGpDiJ,QAAS,SAASjJ,GACd2mB,EAAM3mB,GACN6U,EAAQ8Q,+BAA+B3lB,GACvC6U,EAAQuU,WAAWppB,GACnBnN,EAAOoW,QAAQjJ,OAK3B7c,GAAGsG,OAAOrE,MAEN2gC,iBAAkB,SAAS/lB,EAAIklB,GAC3B,GAAIZ,GAAYzP,EAAQ4P,cAAczkB,EAElCskB,UACOA,GAAUluB,KAAKi3B,aAAanI,IAI3C4C,SAAU,SAAS9nB,EAAIklB,GACnB,GAAIoI,GAAYzY,EAAQ4P,cAAczkB,GAAI5J,IAEtCk3B,GAAUC,YACHD,GAAUC,KAAKrI,GAEtBoI,EAAUE,sBACHF,GAAUE,eAAetI,IAMxCM,eAAgB,SAASxlB,EAAIytB,GACzB,GAAIC,GAAe7Y,EAAQsS,gBAAgBnnB,GAAM,EAC7C8Q,EAAM+D,EAAQ8Y,QAAQ3tB,EAAI0tB,EAE9B,OAAID,IACO,GAAItqC,IAAG+O,SAAUE,QAAQq7B,EAAe3c,GAAMA,IAGlD,GAAI3tB,IAAG+O,SAAUE,WAAY0e,IAGxC1J,QAAS,SAASpH,GACd,MAAO6U,GAAQrO,QAAQxG,IAAO6U,EAAQ4P,cAAczkB,GAAIoB,MAG5DioB,SAAU,SAASrpB,GACf,MAAO6U,GAAQrO,QAAQxG,IAAO6U,EAAQ4P,cAAczkB,GAAIqkB,OAO5Djc,sBAAuB,WACnB,GAAIwlB,KAuBJ,OArBA/Y,GAAQgZ,sBAAsB,SAASvqC,EAAKmiB,GACxCoP,EAAQgS,0BAA0B,KAAMphB,EAAWrK,SAAS+qB,WAAa1gB,EAAWrK,SAASgrB,UAE7F,IAAI5iC,IACAW,KAAMshB,EAAWthB,KACjBiiC,UAAW3gB,EAAWrK,SAASgrB,UAC/BjlB,KAAMsE,EAAWtE,KACjBhB,KAAMsF,EAAWtF,KAGjBsF,GAAWniB,MACXE,EAAKF,IAAMmiB,EAAWniB,KAGtBmiB,EAAWuM,mBACXxuB,EAAKwuB,iBAAmBvM,EAAWuM,kBAGvC4b,EAAmB3oC,KAAKzB,KAGrBoqC,GAGXlD,mBAAoB,SAAS1qB,GACzB,MAAO6U,GAAQ4P,cAAczkB,GAAIolB,kBAGrCvc,YAAa,SAAS7I,GAClB,QAAS5E,GAAYyZ,EAAQrO,QAAQxG,KAChC6U,EAAQ4P,cAAczkB,GAAI8tB,cAGnCjH,0BAA2B,SAAS7mB,EAAI+tB,EAAeC,GACnD,GAAI1J,GAAYzP,EAAQ4P,cAAczkB,OAClCiuB,EAAiB3J,EAAUlpB,aAC3B+qB,EAAa4H,GAAiBE,EAAc9H,WAC5CC,EAAY4H,GAAgBC,EAAc7H,SAE1CD,KACA5gC,EAAIpC,GAAGwL,OAAO,yDAA0D4I,KAAK0qB,UAAUkE,KACvFA,EAAW+H,UACX/qC,GAAGY,KAAKoiC,EAAY,SAASphC,EAAKmgC,GAC9BkB,EAAUC,QAAQnB,KAEtBiB,EAAW3+B,OAAS,IAI5BwU,MAAO,SAASgE,GACZ,GAAI6U,EAAQrO,QAAQxG,GAIhB,MAHAza,GAAIpC,GAAGwL,OAAO,4DAA6DqR,EAAI2F,EAAQ3F,KACvF6U,EAAQ4P,cAAczkB,GAAImuB,QAAS,EACnCxH,EAAM3mB,IACC,GAIfonB,mBAAoB,SAASpnB,GACzB,GAAI5E,GAAYyZ,EAAQrO,QAAQxG,GAAK,CACjC,GACIouB,GACA13B,EAFAyG,EAAQ0X,EAAQ4P,cAAczkB,EAQlC,UAJO7C,GAAM/B,SAEb+B,EAAM/B,YACNgzB,EAAcvZ,EAAQsS,gBAAgBnnB,GAClCouB,EAAc,GAAKhzB,EAAS2iB,UAAW,CAKvC,IAJA5gB,EAAM/B,SAAS8K,SAAU,EACzB/I,EAAM/B,SAASizB,MAAQD,EACvBjxB,EAAM/B,SAASgrB,aAEV1vB,EAAI,EAAGA,EAAI03B,EAAa13B,IACzByG,EAAM/B,SAASgrB,UAAUnhC,KAAKyR,EAGlCme,GAAQsY,eAAentB,OAGvB7C,GAAM/B,SAAS8K,SAAU,IAKrC2jB,WAAY,SAAS7pB,EAAIsuB,GACjBzZ,EAAQrO,QAAQxG,KAChB6U,EAAQ4P,cAAczkB,GAAIoB,KAAOktB,IAIzClF,WAAY,SAASppB,GACjB,GAAIstB,GAAYzY,EAAQ4P,cAAczkB,GAAI5J,IAE1CjT,IAAGY,KAAKupC,EAAUE,eAAgB,SAASe,SAChCjB,GAAUE,eAAee,KAGpCprC,GAAGY,KAAKupC,EAAUC,KAAM,SAASgB,SACtBjB,GAAUC,KAAKgB,MAW9BC,WAAY,SAASxuB,EAAIyuB,GACrB,MAAO5Z,GAAQ6Z,aAAa1uB,EAAIyuB,EAAatrC,GAAGmN,sBAGpDw8B,kBAAmB,SAAS9sB,EAAIyuB,GAC5B,GAAIvJ,GAA0B,MAAfuJ,GAAsB,EAAKA,CAC1C,OAAO5Z,GAAQ4P,cAAczkB,GAAI5J,KAAKo3B,eAAetI,IAGzDC,cAAe,SAASnlB,EAAI2uB,GACxB,GAAIzQ,GAAY6O,EAAa/sB,GACzB4uB,EAAWvmB,EAAQrI,GACnB7O,EAAa0jB,EAAQzN,QAAQpH,GAC7B6uB,EAAa3Q,EAAYyQ,EACzBG,EAAWD,EAAa3Q,GAAa0Q,EAAWA,EAAWC,EAAa3Q,EACxEkQ,EAAcvZ,EAAQsS,gBAAgBnnB,GACtCqtB,EAAejoC,KAAKq/B,cAAczkB,GAAI5J,KAAKi3B,aAI3Cz7B,EAAOy7B,EAAasB,IAAexrC,GAAG+N,UAAUC,EAAY09B,EAAYC,EAI5E,OAFAzB,GAAasB,GAAc/8B,GAGvBm9B,KAAMJ,EACNv9B,MAAOy9B,EACPx9B,IAAKy9B,EACLE,MAAOZ,EACPx8B,KAAMA,EACNuP,KAAM2tB,EAAWD,IAIzBvJ,yBAA0B,SAAS7T,GAC/B,OACIG,UAAWH,EAAUsd,KACrBE,UAAWxd,EAAUrgB,MAAQ,EAC7B89B,QAASzd,EAAUpgB,IACnB+sB,WAAY3M,EAAUud,QAQ9BvE,mBAAoB,SAASzqB,GACzB,GACI7b,GAAOwhB,EAAQ3F,GACfmB,EAAOkH,EAAQrI,GACfke,EAAY6O,EAAa/sB,GACzB8D,EAAW8D,EAAY5H,GACvB0e,EAAaxiB,EAAOwiB,WAAW1e,GAC/BmvB,EAAiBhsC,GAAGwL,OAAO,2BAA4B7L,EANvC,MAMiEqB,EAAMgd,EAAM+c,EAAWpa,EAM5G,OAJA4a,GAAW0Q,QAAQ,SAAS9rC,GACxB6rC,GAAkB,IAAM7rC,IAGrB6rC,GAGXE,aAAc,SAASrvB,GACnB,MAAO6U,GAAQzN,QAAQpH,GAAIzZ,MAG/B+oC,oBAAqB,SAAStvB,GAC1B,MAAO6U,GAAQ4P,cAAczkB,GAAI5E,UAOrC+rB,gBAAiB,SAASnnB,GACtB,GAAI5E,EAAU,CACV,GAAIwzB,GAAWvmB,EAAQrI,GACnBke,EAAY6O,EAAa/sB,EAE7B,OAAOzW,MAAKgmC,KAAKX,EAAW1Q,KAIpCyP,QAAS,SAAS3tB,EAAIyuB,GAClB,GAAIvJ,GAA0B,MAAfuJ,GAAsB,EAAKA,CAC1C,OAAO5Z,GAAQ4P,cAAczkB,GAAI5J,KAAKm3B,KAAKrI,IAG/CsB,SAAU,SAASxmB,GACf,MAAO6U,GAAQ4P,cAAczkB,GAAI5J,KAAKm3B,MAK1CM,sBAAuB,SAASp4B,GACxBw3B,GACA9pC,GAAGY,KAAK8V,aAAc,SAASvW,EAAK6K,GAChC,GAAwD,IAApD7K,EAAIwJ,QAAQ3J,GAAGwL,OAAO,aAAc7L,IAAmB,CAEvD2S,EAASnS,EADQiU,KAAKC,MAAMrJ,QAO5Cg/B,eAAgB,SAASntB,GACrB6U,EAAQ4P,cAAczkB,GAAI5J,MACtBo3B,kBACAnI,iBACAkI,QACAF,kBAIRmC,kBAAmB,SAASxvB,GACxB6U,EAAQ4P,cAAczkB,GAAI8tB,cAAe,GAK7CnI,+BAAgC,SAAS3lB,GACrC,GAAImvB,EAEJ,UAAIlC,GAAiBpY,EAAQhM,YAAY7I,KACrCmvB,EAAiBta,EAAQ4V,mBAAmBzqB,GAExCmvB,GAAkBt1B,aAAajE,QAAQu5B,OACvCt1B,aAAa41B,WAAWN,IACjB,IASnB/B,uBAAwB,SAASptB,GAC7B,GACImvB,GAAgBO,EADhBvyB,EAAQ0X,EAAQ4P,cAAczkB,EAK9BitB,IAA+BxpC,SAAd0Z,EAAM7Z,MACvB6rC,EAAiBta,EAAQ4V,mBAAmBzqB,GAC5C0vB,EAAgB71B,aAAajE,QAAQu5B,GAGjCO,IACAA,EAAgBn4B,KAAKC,MAAMk4B,GAIvBnd,EAAcmd,EAAcvvB,MAC5B0U,EAAQ2a,kBAAkBxvB,IAG1Bza,EAAIpC,GAAGwL,OAAO,0DAA2DqR,EAAI2F,EAAQ3F,KAErFoS,EAAcpS,EAAI0vB,EAAcvvB,MAEhChD,EAAM7Z,IAAMosC,EAAcpsC,IAC1B6Z,EAAM/B,SAAWs0B,EAAct0B,SAC/B+B,EAAMuT,OAASgf,EAAchf,OAC7BvT,EAAM6U,iBAAmB0d,EAAc1d,iBACvC7U,EAAMioB,kBAAmB,EAEzBvQ,EAAQgS,0BAA0B7mB,OAOlD6nB,0BAA2B,SAAS7nB,GAChC,GACImvB,GAAgBO,EADhBvyB,EAAQ0X,EAAQ4P,cAAczkB,EAIlC,IAAIitB,GAAiBpY,EAAQhM,YAAY7I,GAAK,CAC1C,GAAIgS,GAAmBU,EAAoB1S,EAE3CmvB,GAAiBta,EAAQ4V,mBAAmBzqB,GAE5C0vB,GACIvrC,KAAMwhB,EAAQ3F,GACdmB,KAAMkH,EAAQrI,GACdG,KAAMyI,EAAQ5I,GACd1c,IAAK6Z,EAAM7Z,IACX8X,SAAU+B,EAAM/B,SAChBsV,OAAQvT,EAAMuT,OACdif,YAAa1L,KAAKkG,OAGlBnY,IACA0d,EAAc1d,iBAAmBA,EAGrC,KACInY,aAAaC,QAAQq1B,EAAgB53B,KAAK0qB,UAAUyN,IAExD,MAAOpqC,GACHC,EAAIpC,GAAGwL,OAAO,0DAA2DqR,EAAI1a,EAAMoI,YAAa,WAK5GkiC,yBAA0B,SAAS5vB,EAAIklB,EAAUhH,GAC7C,GAAIpN,GAAM+D,EAAQ8Y,QAAQ3tB,EAAIklB,GAC1B/gC,EAAOwhB,EAAQ3F,GACf6vB,GACI5G,OAAQ,SAASvY,EAAQC,GACrB,GAAIie,GAAWvmB,EAAQrI,EAEnB0Q,KAAWC,EACXF,EAAWzQ,EAAI7b,EAAMyqC,EAAUA,GAG/Bne,EAAWzQ,EAAI7b,EAAOusB,GAAUke,EAAWA,EAAW,EAAIle,EAASke,IAI3E3J,QAAS,SAASvU,EAAQC,GACtB,GAAI0U,GAAgBxQ,EAAQ4P,cAAczkB,GAAI5J,KAAKivB,cAC/CyK,EAAiCjb,EAAQ4P,cAAczkB,GAAI0Q,OAC3Dqf,EAAmBrf,EACnBsf,EAAkBrf,EAClBwN,EAAgB9V,EAAQrI,GACxBiwB,EAAuBF,GAAoBC,EAAkB9R,GAC7DgS,EAAqBJ,CAEzBzK,GAAcH,GAAY+K,EAE1B9sC,GAAGY,KAAKshC,EAAe,SAASH,EAAUiL,GACtCD,GAAsBC,IAG1B1f,EAAWzQ,EAAI7b,EAAM+rC,EAAoB/R,IAIrDrN,GAAIvgB,OAAO4vB,WAAa,SAASjrB,GAC7B,GAAIA,EAAEktB,iBAAkB,CAGpByN,EADwB,MAAb3R,EAAoB,SAAW,WACjBhpB,EAAEwb,OAAQxb,EAAEyb,UAcjD+d,aAAc,SAAS1uB,EAAIyuB,EAAa3d,EAAKsf,GACzC,GAAIC,GAAwB,MAAf5B,GAAsB,EAAKA,EACpCnB,EAAYzY,EAAQ4P,cAAczkB,GAAI5J,IAW1C,OATAk3B,GAAUC,KAAOD,EAAUC,SAC3BD,EAAUE,eAAiBF,EAAUE,mBAErCF,EAAUC,KAAK8C,GAAUvf,EAErBsf,IACA9C,EAAUE,eAAe6C,GAAUD,GAGhCtf,GAIX2Y,8BAA+B,WAC3B,GAAI6G,GAAiBp0B,EAAOsiB,eAE5B3J,GAAQgZ,sBAAsB,SAASvqC,EAAKmiB,GACxC,GAAI8qB,GAAiB,GAAItM,MAAKxe,EAAWkqB,YAGzCY,GAAeC,QAAQD,EAAeE,UAAYH,GAE9CC,EAAerM,WAAaD,KAAKkG,QACjC5kC,EAAI,2CAA6CjC,GACjDuW,aAAa41B,WAAWnsC,OAWpC+mC,qBAAsB,SAASrqB,GAC3B,GAAI7C,GAAQ0X,EAAQ4P,cAAczkB,EAGlC,IAAI7C,EAKA,MAJKA,GAAM/B,UACPyZ,EAAQuS,mBAAmBpnB,GAGxB7C,EAAM/B,SAAS8K,YCziBtC/iB,GAAGupB,wBAA0B,SAAS9O,GAClC,YAqBA,SAAS8yB,KACL,MAAqC,SAAjCvuC,EAAQwqB,OAAO3pB,eAEX2tC,QAAS,aAtBrB,GAAIC,GACAzuC,GACIwqB,OAAQ,SACRE,cAAe,SACfK,iBACAN,eAAgB,EAChBI,cAAe,SAAShN,GAAK,UAC7BiN,eACAE,MACI6I,UAAU,EACV4I,iBAAiB,GAErBr5B,IAAK,SAASqJ,EAAKvB,KACnB+f,SAAU,SAASpN,KACnBsN,iBAAkB,SAAStN,EAAIuN,EAAUC,KAGjDrqB,IAAGsG,OAAOtH,EAASyb,GAYnBgzB,EAAYztC,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGw8B,eAC/B6C,aAAc,mBACdM,cAAe,OAAQ,UACvBnW,OAAQxqB,EAAQwqB,OAChBO,cAAe/qB,EAAQ+qB,cACvBD,YAAa9qB,EAAQ8qB,YACrB+T,eAAgB0P,IAChB9jB,eAAgBzqB,EAAQyqB,eACxBI,cAAe,SAAShN,GACpB,MAAO7d,GAAQ6qB,cAAclF,IAAI9H,IAErCza,IAAKpD,EAAQoD,IACb67B,OAAQj/B,EAAQirB,SAChByD,WAAY1uB,EAAQmrB,iBACpBH,KAAMhrB,EAAQgrB,QAGlBhqB,GAAGsG,OAAOrE,MACNu0B,WAAY,SAAS3Z,EAAIG,EAAMoZ,GAC3B,GAAIlJ,GAAoBkJ,KAExBp3B,GAAQoD,IAAI,sCAAwCya,GAE7B,WAAnB7d,EAAQwqB,OACRikB,EAAUxN,cAAcpjB,GACnBujB,SAASpjB,GACTsjB,WAAWpT,GACXyR,QAGLzR,EAAkBluB,EAAQ0qB,eAAiB1M,EAC3CywB,EAAUxN,cAAcpjB,GACnByjB,WAAWpT,GACXyR,YCpDrB,WAMI,QAAS+O,GAAkBC,GACvB,GAGIC,GAHAC,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACT1lC,EAASyE,SAASC,cAAc,SAGpC,OAAI6gC,GAAKE,EAAK,UACVzlC,EAAO2lC,MAAQ3lC,EAAOmT,OAAS,EAC/BmyB,EAAMtlC,EAAO4lC,WAAW,MACxBN,EAAIO,UAAUR,GAAME,EAAK,EAAG,GAIoB,IAAzCD,EAAIQ,aAAa,EAAG,EAAG,EAAG,GAAG/tC,KAAK,IAUjD,QAASguC,GAAqBV,EAAKE,EAAIE,GACnC,GAIIH,GAAKvtC,EAAMiuC,EAAOC,EAJlBjmC,EAASyE,SAASC,cAAc,UAChCwhC,EAAK,EACLC,EAAKV,EACLW,EAAKX,CAUT,KAPAzlC,EAAO2lC,MAAQ,EACf3lC,EAAOmT,OAASsyB,EAChBH,EAAMtlC,EAAO4lC,WAAW,MACxBN,EAAIO,UAAUR,EAAK,EAAG,GACtBttC,EAAOutC,EAAIQ,aAAa,EAAG,EAAG,EAAGL,GAAI1tC,KAG9BquC,EAAKF,GACRF,EAAQjuC,EAAgB,GAAVquC,EAAK,GAAS,GACd,IAAVJ,EACAG,EAAKC,EAELF,EAAKE,EAETA,EAAMD,EAAKD,GAAO,CAItB,OADAD,GAASG,EAAKX,EACI,IAAVQ,EAAe,EAAIA,EAM/B,QAASI,GAAqBhB,EAAKl/B,EAAMzP,EAAS4vC,GAC9C,GAAItmC,GAASyE,SAASC,cAAc,UAChCzE,EAAOvJ,EAAQuJ,MAAQ,aACvBuG,EAAU,GAAI9O,IAAG+O,OASrB,OAPA8/B,GAAoBlB,EAAKl/B,EAAMnG,EAAQtJ,EAAS4vC,GAC3Cl1B,KAAK,WACF5K,EAAQG,QACJ3G,EAAOI,UAAUH,EAAMvJ,EAAQwJ,SAAW,OAI/CsG,EAGX,QAASggC,GAAoCjxB,GAGzC,IAAK7d,GAAGuR,MACJ,KAAM,IAAIvR,IAAGiG,MAAM,kEAGvB,IAAI4X,EAAKkxB,WAAalxB,EAAKmxB,UANX,OAOZ,OACIC,UAAW7oC,KAAKC,MAAMD,KAAK8oC,KARnB,QAQqCrxB,EAAKkxB,WAAalxB,EAAKmxB,aACpEG,SAAU/oC,KAAKC,MAAMD,KAAK8oC,KATlB,QASoCrxB,EAAKmxB,UAAYnxB,EAAKkxB,eAQ9E,QAASF,GAAoBlB,EAAKl/B,EAAMnG,EAAQtJ,EAAS4vC,GACrD,GAMIQ,GANAvB,EAAKF,EAAIG,aACTC,EAAKJ,EAAIK,cACTC,EAAQjvC,EAAQivC,MAChBxyB,EAASzc,EAAQyc,OACjBmyB,EAAMtlC,EAAO4lC,WAAW,MACxBp/B,EAAU,GAAI9O,IAAG+O,OAKrB,OAFA6+B,GAAIyB,OAEArwC,EAAQswC,OACDC,GACH9gC,KAAMA,EACNnG,OAAQA,EACRkwB,MAAOmV,EACP6B,YAAazB,EACb0B,WAAY5B,EACZ6B,YAAa1wC,EAAQ0wC,YACrBJ,OAAQtwC,EAAQswC,OAChBK,aAAcl0B,EACdm0B,YAAa3B,KAIhBjuC,GAAG2V,kBAAkBuD,2BACtBk2B,EAAqBN,GACjBE,UAAWf,EACXc,WAAYtzB,IAGZ2zB,IACApvC,GAAGoC,IAAIpC,GAAGwL,OAAO,iFACbyiC,EAAOxyB,EAAQ2zB,EAAmBD,SAAUC,EAAmBH,WAC/D,QAEJhB,EAAQmB,EAAmBD,SAC3B1zB,EAAS2zB,EAAmBH,YAIpCY,EAAoBvnC,EAAQ2lC,EAAOxyB,EAAQzc,EAAQ0wC,aAI/C1vC,GAAGuR,MACF,WACOm8B,EAAkBC,KAClBE,GAAM,EACNE,GAAM,EAGV,IAOI+B,GAAQC,EAAIC,EAPZC,EAAI,KACJC,EAAYnjC,SAASC,cAAc,UACnCmjC,EAAkBvB,EAAWP,EAAqBV,EAAKE,EAAIE,GAAM,EACjEqC,EAAKhqC,KAAKgmC,KAAK6D,EAAIhC,EAAQJ,GAC3BwC,EAAKjqC,KAAKgmC,KAAK6D,EAAIx0B,EAASsyB,EAAKoC,GACjC3B,EAAK,EACL8B,EAAK,CAMT,KAHAJ,EAAUjC,MAAQiC,EAAUz0B,OAASw0B,EACrCH,EAASI,EAAUhC,WAAW,MAEvBM,EAAKT,GAAI,CAGZ,IAFAgC,EAAK,EACLC,EAAK,EACED,EAAKlC,GACRiC,EAAOS,UAAU,EAAG,EAAGN,EAAGA,GAC1BH,EAAO3B,UAAUR,GAAMoC,GAAKvB,GAC5BZ,EAAIO,UAAU+B,EAAW,EAAG,EAAGD,EAAGA,EAAGD,EAAIM,EAAIF,EAAIC,GACjDN,GAAME,EACND,GAAMI,CAEV5B,IAAMyB,EACNK,GAAMD,EAEVzC,EAAI4C,UACJN,EAAYJ,EAAS,QAIzBlC,EAAIO,UAAUR,EAAK,EAAG,EAAGM,EAAOxyB,GAGpCnT,EAAOmoC,iBAAmBnoC,EAAOmoC,kBACjC3hC,EAAQG,UAEDH,GAGX,QAASygC,GAAqCmB,GAC1C,GAAIjiC,GAAOiiC,EAAWjiC,KAClB+pB,EAAQkY,EAAWlY,MACnBgX,EAAckB,EAAWlB,YACzBC,EAAaiB,EAAWjB,WACxBC,EAAcgB,EAAWhB,YACzB5gC,EAAU,GAAI9O,IAAG+O,QACjBugC,EAASoB,EAAWpB,OACpBqB,EAAe5jC,SAASC,cAAc,UACtC4jC,EAAsBD,EAAazC,WAAW,MAC9C2C,EAAeH,EAAWpoC,OAC1BqnC,EAAee,EAAWf,aAC1BC,EAAcc,EAAWd,WAyB7B,OAvBAC,GAAoBc,EAAclB,EAAYD,EAAaE,GAE3DmB,EAAap1B,OAASk0B,EACtBkB,EAAa5C,MAAQ2B,EAErBgB,EAAoBzC,UAAU3V,EAAO,EAAG,GAExC8W,GACI7gC,KAAMA,EACNgN,OAAQk0B,EACRnX,MAAOA,EACPmY,aAAcA,EACdE,aAAcA,EACd5C,MAAO2B,IAENl2B,KACG,WACIm3B,EAAaJ,iBAAmBI,EAAaJ,kBAC7C3hC,EAAQG,WAEZH,EAAQK,SAGTL,EAOX,QAAS+gC,GAAoBvnC,EAAQ2lC,EAAOxyB,EAAQi0B,GAChD,OAAQA,GACJ,IAAK,GACL,IAAK,GACL,IAAK,GACL,IAAK,GACDpnC,EAAO2lC,MAAQxyB,EACfnT,EAAOmT,OAASwyB,CAChB,MACJ,SACI3lC,EAAO2lC,MAAQA,EACf3lC,EAAOmT,OAASA,EAExB,GAAImyB,GAAMtlC,EAAO4lC,WAAW,KAC5B,QAAQwB,GACJ,IAAK,GAED9B,EAAIkD,UAAU7C,EAAO,GACrBL,EAAI5pB,OAAM,EAAI,EACd,MACJ,KAAK,GAED4pB,EAAIkD,UAAU7C,EAAOxyB,GACrBmyB,EAAImD,OAAO3qC,KAAK4qC,GAChB,MACJ,KAAK,GAEDpD,EAAIkD,UAAU,EAAGr1B,GACjBmyB,EAAI5pB,MAAM,GAAG,EACb,MACJ,KAAK,GAED4pB,EAAImD,OAAO,GAAM3qC,KAAK4qC,IACtBpD,EAAI5pB,MAAM,GAAG,EACb,MACJ,KAAK,GAED4pB,EAAImD,OAAO,GAAM3qC,KAAK4qC,IACtBpD,EAAIkD,UAAU,GAAIr1B,EAClB,MACJ,KAAK,GAEDmyB,EAAImD,OAAO,GAAM3qC,KAAK4qC,IACtBpD,EAAIkD,UAAU7C,GAAQxyB,GACtBmyB,EAAI5pB,OAAM,EAAI,EACd,MACJ,KAAK,GAED4pB,EAAImD,QAAO,GAAO3qC,KAAK4qC,IACvBpD,EAAIkD,WAAW7C,EAAO,IAUlC,QAASgD,GAAaC,EAAUC,GAC5B,GAAIntC,GAAO/B,IAEPiH,QAAOO,MAAQynC,YAAoBznC,OAClC,WACG,GAAIkkC,GAAM,GAAIyD,OACVC,EAAMnoC,OAAOmoC,KAAOnoC,OAAOmoC,IAAIC,gBAAkBpoC,OAAOmoC,IACpDnoC,OAAOqoC,WAAaroC,OAAOqoC,UAAUD,gBAAkBpoC,OAAOqoC,UAAY,IAClF,KAAKF,EAAO,KAAMprC,OAAM,uDACxB0nC,GAAI6D,IAAMH,EAAIC,gBAAgBJ,GAC9BltC,EAAKyK,KAAOyiC,EACZA,EAAWvD,KAGduD,EAASpD,cAAiBoD,EAASlD,gBACpCkD,EAASliC,OAAS,WACd,GAAIyiC,GAAYztC,EAAK0tC,kBACjBD,KACAztC,EAAK0tC,mBAAqB,KAG1B1lB,WAAW,WACP,IAAK,GAAIzY,GAAI,EAAGvD,EAAMyhC,EAAUptC,OAAQkP,EAAIvD,EAAKuD,IAC7Ck+B,EAAUl+B,MAEf,KAGX29B,EAAShiC,QAAUiiC,EACnBlvC,KAAKyvC,uBAETzvC,KAAKivC,SAAWA,EAMpBD,EAAazvC,UAAUmwC,OAAS,SAASniC,EAAQxQ,GAC7CA,EAAUA,KAEV,IASI4yC,GATA5tC,EAAO/B,KACP4vC,EAAW5vC,KAAKivC,SAASpD,aACzBgE,EAAY7vC,KAAKivC,SAASlD,cAC1BC,EAAQjvC,EAAQivC,MAChBxyB,EAASzc,EAAQyc,OACjBie,EAAW16B,EAAQ06B,SACnBD,EAAYz6B,EAAQy6B,UACpBmV,GAAY3sC,KAAKwM,MAA2B,eAAnBxM,KAAKwM,KAAKrL,KACnCsJ,EAAU8C,EAAO9C,QAAQ3M,aAG7B,IAAIkC,KAAKyvC,mBAEL,WADAzvC,MAAKyvC,mBAAmB5vC,KAAK,WAAakC,EAAK2tC,OAAOniC,EAAQxQ,IAI9DivC,KAAUxyB,EACVA,EAAUq2B,EAAY7D,EAAQ4D,GAAa,EACpCp2B,IAAWwyB,EAClBA,EAAS4D,EAAWp2B,EAASq2B,GAAc,GAE3C7D,EAAQ4D,EACRp2B,EAASq2B,GAETpY,GAAYuU,EAAQvU,IACpBuU,EAAQvU,EACRje,EAAUq2B,EAAY7D,EAAQ4D,GAAa,GAE3CpY,GAAahe,EAASge,IACtBhe,EAASge,EACTwU,EAAS4D,EAAWp2B,EAASq2B,GAAc,GAG/CF,GAAQ3D,MAAOA,EAAOxyB,OAAQA,GAC9Bzb,GAAGY,KAAK5B,EAAS,SAAS+yC,EAAYC,GAClCJ,EAAIG,GAAcC,IAGN,QAAZtlC,EACC,WACG,GAAIulC,GAAeziC,EAAOgiC,GAC1B7C,GAAqB3qC,EAAKktC,SAAUltC,EAAKyK,KAAMmjC,EAAKhD,GAC/Cl1B,KAAK,SAAS/Q,GACX6G,EAAOgiC,IAAM7oC,EACbspC,IAAiBziC,EAAOgiC,KAAOhiC,EAAOR,cAG/B,WAAZtC,GACPmiC,EAAoB5sC,KAAKivC,SAAUjvC,KAAKwM,KAAMe,EAAQoiC,EAAKhD,GAElC,kBAAlB3sC,MAAKiwC,UACZjwC,KAAKiwC,SAAS1iC,IAItBxP,GAAGixC,aAAeA,KCtYtBjxC,GAAGm8B,eAAiB,SAAS/5B,GACzB,YAEA,SAAS+vC,GAAM/tC,GACX,MAAoC,QAA7BA,EAAGsI,QAAQ3M,cAGtB,QAASqyC,GAAShuC,GACd,MAAoC,WAA7BA,EAAGsI,QAAQ3M,cAGtB,QAASsyC,KACL,MAAmC/xC,WAA5B,GAAI8wC,QAAQkB,YAGvB,QAASC,KACL,GAAIjqC,GAASyE,SAASC,cAAc,SAEpC,OAAO1E,GAAO4lC,YAAc5lC,EAAO4lC,WAAW,MAMlD,QAASsE,GAAwBC,GAE7B,GAAIC,GAAeD,EAAa/oC,MAAM,KAClC1I,EAAO0xC,EAAaA,EAAaruC,OAAS,GAAGqF,MAAM,KAAK,GACxDuoB,EAAYjyB,GAAGuU,aAAavT,EAIhC,QAFAixB,EAAYA,GAAaA,EAAUlyB,eAG/B,IAAK,OACL,IAAK,MACD,MAAO,YACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,MACD,MAAO,WACX,KAAK,OACL,IAAK,MACD,MAAO,cASnB,QAAS4yC,GAAc5U,GACnB,GACI6U,GAAgBC,EAAgBC,EADhCC,EAAehmC,SAASC,cAAc,IAS1C,OANA+lC,GAAaC,KAAOjV,EAEpB6U,EAAiBG,EAAaE,SAC9BH,EAAaC,EAAaG,KAC1BL,EAAiBE,EAAaI,SAE1BP,EAAe7yC,gBAAkBmJ,OAAOkqC,SAASH,SAASlzC,gBAI1D8yC,EAAe9yC,gBAAkBmJ,OAAOkqC,SAASD,SAASpzC,eAK1D+yC,IAAe5pC,OAAOkqC,SAASF,OAASlzC,GAAGsQ,MAOnD,QAAS+iC,GAAyB1F,EAAK7+B,GACnC6+B,EAAI3+B,OAAS,WACT2+B,EAAI3+B,OAAS,KACb2+B,EAAIz+B,QAAU,KACdJ,EAAQG,QAAQ0+B,IAGpBA,EAAIz+B,QAAU,WACVy+B,EAAI3+B,OAAS,KACb2+B,EAAIz+B,QAAU,KACd9M,EAAI,6BAA8B,SAClC0M,EAAQK,QAAQw+B,EAAK,+BAI7B,QAAS2F,GAAgChrC,EAAQwG,GAO7CxG,EAAOmoC,gBAAkB,WACrB3hC,EAAQG,QAAQ3G,IAQxB,QAASirC,GAAkC/vB,EAAa1U,GACpD,GAAI0kC,GAAarB,EAAM3uB,IAAgB4uB,EAAS5uB,EAahD,OAXI2uB,GAAM3uB,GACN6vB,EAAyB7vB,EAAa1U,GAEjCsjC,EAAS5uB,GACd8vB,EAAgC9vB,EAAa1U,IAG7CA,EAAQK,QAAQqU,GAChBphB,EAAIpC,GAAGwL,OAAO,iDAAkDgY,EAAY9W,SAAU,UAGnF8mC,EAKX,QAASC,GAAKzlC,EAAYkW,EAAWllB,GACjC,GAAI00C,GAAc,GAAI1zC,IAAG+O,QACrB+b,EAAa,GAAI9qB,IAAG2zC,SAAS3lC,EAAY5L,GACzCqhB,EAAUzkB,EAAQykB,QAElBoY,EAA2B,MAAlB78B,EAAQ68B,QAAwB78B,EAAQ68B,OACjD+X,EAAsB,WAClB1vB,EAAUhV,QAAU,KACpBgV,EAAUlV,OAAS,KACnB5M,EAAI,mDAAoD,SACxDsxC,EAAYvkC,QAAQ+U,EAAW,gCAiDvC,OA9CA4G,GAAW+oB,gBAAgBn6B,KACvB,SAASnR,GAGL,GAAIurC,IACIz/B,MAAO,WACH,OAAO,GAAIrU,IAAG+O,SAAUE,YAGhC8kC,EAAOlY,EAAS,GAAI77B,IAAGg0C,KAAKhmC,EAAY5L,GAAO0xC,EAC/CG,EAAQ,GAAIj0C,IAAGixC,aAAajjC,EAAY4lC,EAExCL,GAAkCrvB,EAAWwvB,IAC7CK,EAAK1/B,QAAQqF,KACT,SAASq6B,GACL,GAAIrE,GAAcqE,GAAQA,EAAKG,WAE/BD,GAAMtC,OAAOztB,GACTwV,SAAUjW,EACVgW,UAAWhW,EACXisB,YAAaA,EACbnnC,KAAMA,EACN+mC,OAAQtwC,EAAQ2kB,wBAIxB,SAASwwB,GACL/xC,EAAIpC,GAAGwL,OAAO,iEAAkE2oC,IAEhFF,EAAMtC,OAAOztB,GACTwV,SAAUjW,EACVgW,UAAWhW,EACXlb,KAAMA,EACN+mC,OAAQtwC,EAAQ2kB,0BAOpC,WACIvhB,EAAI,mBACJsxC,EAAYvkC,QAAQ+U,EAAW,qBAIhCwvB,EAGX,QAASU,GAAyBrW,EAAKsW,EAAaZ,EAAMhwB,EAASE,GAC/D,GAAI2wB,GAAU,GAAIlD,OACdmD,EAAgB,GAAIv0C,IAAG+O,OAE3BwkC,GAAkCe,EAASC,GAEvC5B,EAAc5U,KACduW,EAAQhC,YAAc,aAG1BgC,EAAQ9C,IAAMzT,EAEdwW,EAAc76B,KACV,WACI65B,EAAkCc,EAAaZ,GAEnC,GAAIzzC,IAAGixC,aAAaqD,GAC1B3C,OAAO0C,GACT3a,SAAUjW,EACVgW,UAAWhW,EACXlb,KAAMiqC,EAAwBzU,GAC9BuR,OAAQ3rB,KAIhB8vB,EAAKtkC,SAIb,QAASqlC,GAA+BzW,EAAK4P,EAAK8F,EAAMhwB,GACpD8vB,EAAkC5F,EAAK8F,GAKvCzzC,GAAG2tC,GAAK5nC,KACJ2zB,SAAUjW,EAAU,KACpBgW,UAAWhW,EAAU,OAGzBkqB,EAAI6D,IAAMzT,EAWd,QAAS0W,GAAY1W,EAAK7Z,EAAWllB,GACjC,GAAIy0C,GAAO,GAAIzzC,IAAG+O,QACdiV,EAAQhlB,EAAQglB,MAChBP,EAAUO,EAAQhlB,EAAQykB,QAAU,IA8BxC,OA3BIO,IAASmuB,EAAMjuB,GAGXquB,IAIII,EAAc5U,KAASsU,IACvBmC,EAA+BzW,EAAK7Z,EAAWuvB,EAAMhwB,GAGrD2wB,EAAyBrW,EAAK7Z,EAAWuvB,EAAMhwB,GAInD+wB,EAA+BzW,EAAK7Z,EAAWuvB,EAAMhwB,GAIpD2uB,EAASluB,GACdkwB,EAAyBrW,EAAK7Z,EAAWuvB,EAAMhwB,GAG1C8vB,EAAkCrvB,EAAWuvB,KAClDvvB,EAAUstB,IAAMzT,GAGb0V,EAGXzzC,GAAGsG,OAAOrE,MAWNkiB,SAAU,SAASuwB,EAAexwB,EAAWllB,GACzC,MAAIgB,IAAGkL,SAASwpC,IACZtyC,EAAI,4DACGqyC,EAAYC,EAAexwB,EAAWllB,SAG7CoD,EAAI,iDACGqxC,EAAKiB,EAAexwB,EAAWllB,WAMlDiD,KAAK0yC,YACL1yC,KAAK0yC,SAASxC,MAAQA,EACtBlwC,KAAK0yC,SAASvC,SAAWA,EACzBnwC,KAAK0yC,SAAShC,cAAgBA,EAC9B1wC,KAAK0yC,SAASnC,wBAA0BA,GChT5CxyC,GAAGg0C,KAAO,SAAShmC,EAAY5L,GAC3B,YAYA,SAASwyC,GAAkBC,GAIvB,IAHA,GAAI1tC,GAAS,EACT2tC,EAAM,EAEHD,EAAIxwC,OAAS,GAChB8C,GAAUu+B,SAASmP,EAAI1zC,UAAU,EAAG,GAAI,IAAMiF,KAAK0uC,IAAI,EAAGA,GAC1DD,EAAMA,EAAI1zC,UAAU,EAAG0zC,EAAIxwC,QAC3BywC,GAAO,CAGX,OAAO3tC,GAKX,QAAS4tC,GAAWC,EAAQlmC,GACxB,GAAImmC,GAAYD,EACZE,EAAapmC,CAwBjB,OAvBkBxO,UAAd20C,IACAA,EAAY,EACZC,EAAa,GAAIl1C,IAAG+O,SAGxB/O,GAAGwO,cAAcR,EAAYinC,EAAW,GAAGv7B,KAAK,SAASm7B,GACrD,GACIM,GADA9xC,EAAQ,cAAcnC,KAAK2zC,EAG3BxxC,GACiB,MAAbA,EAAM,IACN8xC,EAAgBzP,SAASmP,EAAI/0C,MAAM,EAAG,GAAI,IAC1Ci1C,EAAWE,EAAYE,EAAgB,EAAGD,IAG1CA,EAAWjmC,QAAQgmC,GAIvBC,EAAW/lC,QAAQ,iCAIpB+lC,EAIX,QAASE,KACL,GAAItmC,GAAU,GAAI9O,IAAG+O,OAgBrB,OAdA/O,IAAGwO,cAAcR,EAAY,EAAG,GAAG0L,KAAK,SAASm7B,GACjB,IAAxBA,EAAIlrC,QAAQ,QACZmF,EAAQK,QAAQ,qBAGhB4lC,IAAar7B,KAAK,SAASs7B,GACvBlmC,EAAQG,QAAQ+lC,IAEpB,SAAS7yC,GACL2M,EAAQK,QAAQhN,OAKrB2M,EAIX,QAASumC,GAAeC,GACpB,GAAIxmC,GAAU,GAAI9O,IAAG+O,OAMrB,OAJA/O,IAAGwO,cAAcR,EAAYsnC,EAAY,GAAI,GAAG57B,KAAK,SAASm7B,GAC1D/lC,EAAQG,QAAgB,SAAR4lC,KAGb/lC,EAIX,QAASymC,GAAiBD,EAAWE,GACjC,GAAI1mC,GAAU,GAAI9O,IAAG+O,OAWrB,OATA/O,IAAGwO,cAAcR,EAAYsnC,EAAY,GAAI,GAAG57B,KAAK,SAASm7B,GAC1D,GAAIW,EACA,MAAO1mC,GAAQG,QAAQ2lC,EAAkBC,GAGzC/lC,GAAQG,QAAQy2B,SAASmP,EAAK,OAI/B/lC,EAIX,QAAS2mC,GAAOH,EAAWI,GACvB,GAAIV,GAASM,EAAY,GACrBjnC,EAAqB,GAAbqnC,CAEZ,OAAO11C,IAAGwO,cAAcR,EAAYgnC,EAAQ3mC,GAIhD,QAASsnC,GAAcC,GAInB,IAHA,GAAIh5B,MACAo4B,EAAS,EAENA,EAAS,IAAMY,EAAOvxC,QACzBuY,EAAQ9a,KAAK8zC,EAAO91C,MAAMk1C,EAAQA,EAAS,KAC3CA,GAAU,EAGd,OAAOp4B,GAIX,QAASi5B,GAAaL,EAAcE,GAChC,GACII,GAAa91C,GAAGsG,UAAWyvC,GAC3BC,IAsBJ,OApBAh2C,IAAGY,KAAK80C,EAAY,SAAS9zC,EAAK26B,GAC9B,GAGI0Z,GAAWvpC,EAASwpC,EAHpBC,EAAQ5Z,EAAMz8B,MAAM,EAAG,GACvB+c,EAAK24B,EAAeZ,EAAkBuB,GAASzQ,SAASyQ,EAAO,IAC/DC,EAAgBN,EAAWnsC,QAAQkT,EAYvC,IATIu5B,GAAiB,IACjB1pC,EAAU2pC,EAASx5B,GAAI7b,KACvBk1C,EAAeG,EAASx5B,GAAIxO,MAC5B4nC,EAAY1Z,EAAMz8B,MAbL,GAAA,GAa4D,EAAfo2C,GAC1DF,EAAKtpC,GAAW8oC,EAAeZ,EAAkBqB,GAAavQ,SAASuQ,EAAW,IAElFH,EAAWh3B,OAAOs3B,EAAe,IAGX,IAAtBN,EAAWzxC,OACX,OAAO,IAIR2xC,EApJX,GAAID,IAAW,KACXM,GACIC,KACIt1C,KAAM,cACNqN,MAAO,GAmJnBrO,IAAGsG,OAAOrE,MAONoS,MAAO,WACH,GAAIkiC,GAAS,GAAIv2C,IAAG+O,QAChBynC,EAAiB,SAASn0C,GACtBD,EAAIpC,GAAGwL,OAAO,kCAAmCnJ,IACjDk0C,EAAOpnC,QAAQ9M,GA0BvB,OAvBA+yC,KAAgB17B,KAAK,SAAS+8B,GAC1Br0C,EAAIpC,GAAGwL,OAAO,mDAAwElL,SAApB0N,EAAWhN,KAAqB,OAASgN,EAAWhN,OAEtHq0C,EAAeoB,GAAY/8B,KAAK,SAAS87B,GAErCpzC,EAAIpC,GAAGwL,OAAO,+BAAgCgqC,EAAe,SAAW,QAExED,EAAiBkB,EAAYjB,GAAc97B,KAAK,SAASg9B,GAErDt0C,EAAIpC,GAAGwL,OAAO,kCAAmCkrC,IAEjDjB,EAAOgB,EAAYC,GAAeh9B,KAAK,SAASk8B,GAC5C,GAAIF,GAAaC,EAAcC,GAC3Be,EAAYd,EAAaL,EAAcE,EAE3CtzC,GAAI,sCAEJm0C,EAAOtnC,QAAQ0nC,IAChBH,IACJA,IACJA,IACJA,GAEID,KAKft0C,KAAK0yC,YACL1yC,KAAK0yC,SAASC,kBAAoBA,GC7MtC50C,GAAG2zC,SAAW,SAAS3lC,EAAY5L,GAC/B,YAEA,SAASw0C,GAAeC,EAAYC,GAChC,GAAIC,IAAe,EACfC,KAAuBlkC,OAAO+jC,EASlC,OAPA72C,IAAGY,KAAKo2C,EAAmB,SAASp1C,EAAKq1C,GACrC,GAAwD,IAApDH,EAAkBntC,QAAQstC,GAE1B,MADAF,IAAe,GACR,IAIRA,EAGX/2C,GAAGsG,OAAOrE,MASN4xC,cAAe,WACX,GAAI7vC,GAAO/B,KACP6oB,EAAa,GAAI9qB,IAAG+O,QACpBmoC,GAAc,EACdl2C,EAA2BV,SAApB0N,EAAWhN,KAAqB,OAASgN,EAAWhN,IAsC/D,OApCAoB,GAAIpC,GAAGwL,OAAO,gEAAiExK,IAE/EoB,EAAI,oDAEAH,KAAKk1C,qBACL/0C,EAAI,sDAEJpC,GAAGwO,cAAcR,EAAY,EAAG,GAAG0L,KAAK,SAASm7B,GAC7C70C,GAAGY,KAAKoD,EAAKozC,uBAAwB,SAAS7uC,EAAM8F,GAChD,GAAIuoC,EAAevoC,EAAOwmC,GAQtB,OALa,eAATtsC,GAAyBvI,GAAG2V,kBAAkBsD,gBAC9Ci+B,GAAc,EACdpsB,EAAW7b,QAAQ1G,KAGhB,IAIfnG,EAAIpC,GAAGwL,OAAO,iDAAkDxK,EAAMk2C,EAAc,GAAK,QAEpFA,GACDpsB,EAAW3b,WAGnB,WACI/M,EAAI,+BAAiCpB,EAAO,gDAC5C8pB,EAAW3b,aAIf2b,EAAW3b,UAGR2b,GAWXqsB,kBAAmB,WACf,GAAIE,GAAWrpC,EAAW5K,KAEtBk0C,EAAoBt3C,GAAG2J,QAAQW,OAAO84B,KAAKnhC,KAAKm1C,wBAAyBC,IAAa,EACtFH,GAAc,EACdl2C,EAA2BV,SAApB0N,EAAWhN,KAAqB,OAASgN,EAAWhN,IAa/D,OAXIs2C,KAEIJ,EADa,eAAbG,GACcr3C,GAAG2V,kBAAkBsD,eAO1Ci+B,GAAe90C,EAAIpB,EAAO,gEAEpBk2C,MAKnBl3C,GAAG2zC,SAASnyC,UAAU41C,wBAClBG,aAAc,SACdC,YAAa,SACbC,YAAa,SACbC,YAAa,OACbC,cAAe,WAAY,aCpG/B33C,GAAGs4B,gBAAkB,SAAS7pB,EAAMrM,GAChC,YAMA,SAASw1C,GAAiBC,GACtB,GAAIC,IAAa,CASjB,OAPA93C,IAAGY,KAAKi3C,EAAQ,SAASE,EAAOttC,GAC5B,GAAIA,EAAQ,EAER,MADAqtC,IAAa,GACN,IAIRA,EAQX,QAASE,KACL,GAAIC,GAAoB,GAAIj4C,IAAG+O,OA6B/B,OA3BA,IAAI/O,IAAG2zC,SAASllC,EAAMrM,GAAKyxC,gBAAgBn6B,KAAK,WAC5C,GAAI8e,GAAQ,GAAI4Y,OACZrT,EAAM70B,OAAOmoC,KAAOnoC,OAAOmoC,IAAIC,gBAAkBpoC,OAAOmoC,IAClDnoC,OAAOqoC,WAAaroC,OAAOqoC,UAAUD,gBAAkBpoC,OAAOqoC,UAC9D,IAENxT,IACAvF,EAAMtpB,QAAU,WACZ9M,EAAI,4DAA6D,SACjE61C,EAAkB9oC,WAGtBqpB,EAAMxpB,OAAS,WACXipC,EAAkBhpC,SACdg/B,MAAOhsC,KAAKgsC,MACZxyB,OAAQxZ,KAAKwZ,UAIrB+c,EAAMgZ,IAAMzT,EAAIuT,gBAAgB7iC,KAGhCrM,EAAI,+DAAgE,SACpE61C,EAAkB9oC,YAEvB8oC,EAAkB9oC,SAEd8oC,EASX,QAASC,GAAgBL,EAAQM,GAC7B,GAAIC,EA0BJ,OAxBAp4C,IAAGY,KAAKi3C,EAAQ,SAASQ,EAAWC,GAChC,GAAIA,EAAa,EAAG,CAChB,GAAIC,GAAe,0BAA0Br3C,KAAKm3C,GAC9CG,EAAoBD,EAAa,GAAG34C,OAAO,GAAGG,cAAgBw4C,EAAa,GAAGz4C,MAAM,GACpF24C,EAAcN,EAAWK,EAG7B,QAAQD,EAAa,IACjB,IAAK,MACD,GAAIE,EAAcH,EAEd,MADAF,GAAeC,GACR,CAEX,MACJ,KAAK,MACD,GAAII,EAAcH,EAEd,MADAF,GAAeC,GACR,MAOpBD,EAWXn2C,KAAKs2B,SAAW,SAASsf,GACrB,GAAIa,GAAmB,GAAI14C,IAAG+O,OAoB9B,OAlBA3M,GAAI,iCAEAw1C,EAAiBC,GACjBG,IAAiBt+B,KAAK,SAASy+B,GAC3B,GAAIC,GAAeF,EAAgBL,EAAQM,EAEvCC,GACAM,EAAiBvpC,QAAQipC,GAGzBM,EAAiBzpC,WAEtBypC,EAAiBzpC,SAGpBypC,EAAiBzpC,UAGdypC,IC7Hf14C,GAAGw3B,QAAU,SAAS3Z,GAClB,YAaA,SAAS86B,GAAoBpkB,GACzB,GAAIv0B,GAAG8C,QAAQyxB,GACX,OAAO,CAGXv1B,GAAQoD,IAAI,oCAAqC,SAGrD,QAASw2C,GAAgBC,EAAW5pC,EAASmb,EAAUtb,GACnD,GAAIgqC,IAAmB,CAEvB7pC,GAAUA,GAAW0pC,EAAoBE,GAErC5pC,GACAjP,GAAGY,KAAKi4C,EAAW,SAASj3C,EAAKw/B,GAE7B,GAAqB,MAAjBA,EAASpkB,KACT87B,GAAmB,EACnB95C,EAAQoD,IAAIpC,GAAGwL,OAAO,oEAAqE5J,GAAM,aAEhG,IAAqB,MAAjBw/B,EAASpgC,KACd83C,GAAmB,EACnB95C,EAAQoD,IAAIpC,GAAGwL,OAAO,oEAAqE5J,GAAM,aAGjG,KAEI,MADA5C,GAAQ04B,cAAc0J,IACf,EAEX,MAAO2X,GACHD,GAAmB,EACnB95C,EAAQoD,IAAI22C,EAAI12C,QAAS,SAIjC,OAAO,IAIfyM,EAAQG,IAAY6pC,EAAmB,UAAY,WAAWD,EAAWzuB,GAlD7E,GAAIprB,IACA2hB,SAAU,KACVnhB,UACAqqB,iBACAG,QACA0N,cAAe,SAAS9O,KACxBxmB,IAAK,SAASC,EAAS6H,KAG3BlK,IAAGsG,OAAOtH,EAAS6e,GAAM,GA8CzB5b,KAAK01B,QAAU,WAEX,GAAIqhB,GAAgB,GAAIh5C,IAAG+O,QACvBkqC,EAA0B,SAAS1kB,EAAUtlB,EAASmb,GAClDwuB,EAAgBrkB,EAAUtlB,EAASmb,EAAU4uB,IAEjDE,EAAmBl5C,GAAGsG,UAAWtH,EAOrC,OANgB,IAAIgB,IAAGm5C,qBACfn5C,GAAGsG,OAAO4yC,GAAmBxrB,WAAYurB,KAGvCG,cAEHJ,ICrEfh5C,GAAGm5C,qBAAuB,SAASt7B,GAC/B,YAiBA,SAAS6P,GAAW7Q,EAAIuN,EAAUC,GAC9B,GAAIkK,GAAW,IAGf,IAA6B,MAAzBnK,EAASivB,aACT,IACI9kB,EAAWv0B,GAAGkU,UAAUkW,EAASivB,cAErC,MAAON,GACH/5C,EAAQoD,IAAI,qCAAuC22C,EAAI12C,QAAS,SAChEgoB,GAAU,EAIlBrrB,EAAQ0uB,WAAW6G,GAAWlK,EAASD,GA7B3C,GAAIqjB,GACAzuC,GACI2hB,SAAU,KACVkJ,iBACArqB,UACAwqB,MACI6I,UAAU,EACV4I,iBAAiB,GAErB/N,WAAY,SAAS6G,EAAUtlB,EAASmb,KACxChoB,IAAK,SAASqJ,EAAKvB,KAG3BlK,IAAGsG,OAAOtH,EAAS6e,GAmBnB4vB,EAAYztC,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGw8B,eAC/B6C,aAAc,mBACdM,cAAe,OACfnW,OAAQ,MACRO,eACIpF,IAAK,WACD,MAAO3lB,GAAQ2hB,WAGvBkJ,cAAe7qB,EAAQ6qB,cACvBznB,IAAKpD,EAAQoD,IACbsrB,WAAYA,EACZ1D,KAAMhrB,EAAQgrB,QAGlBhqB,GAAGsG,OAAOrE,MACNm3C,YAAa,WACT,GAAI55C,GAASQ,GAAGsG,UAAWtH,EAAQQ,OAEnCR,GAAQoD,IAAI,0BAEZqrC,EAAUxN,cAAc,kBACnBK,WAAW9gC,GACXohC,kBACAjC,WCzDjB3+B,GAAGinB,OAAS,SAASpJ,EAAMzb,GACvB,YAEA,IACIuhB,GAAuB9F,EAAK8d,cAC5B2d,EAAkBz7B,EAAK+d,aACvBC,EAAShe,EAAKge,OACdC,EAAcje,EAAKie,YACnBC,EAAiBle,EAAKke,eAAiB,IACvCwd,EAAoB17B,EAAKme,YACzBC,EAAcpe,EAAKoe,YACnBC,EAAQj6B,KAAKu3C,gBAAgB37B,EAAKqe,MAGtCl8B,IAAGsG,OAAOrE,MAGN8gB,QAAS/iB,GAAG2V,kBAAkBqD,SAAWkjB,EAAM73B,OAAS,EAExDo1C,eAAgB,SAASC,EAAkBC,EAAkBC,GACzD,GAAI51C,GAAO/B,KACP43C,KACAC,EAAeF,EAAuBnrC,KAAOmrC,EAAuBnrC,KAAOmrC,CAkD/E,OAjDiB,IAAI55C,IAAG2zC,SAASmG,EAAc13C,GAGhC+0C,qBAEXn3C,GAAGY,KAAKs7B,EAAO,SAASt6B,EAAKm4C,GACzB,GAAIC,GAAah2C,EAAKi2C,sBAClBne,YAAaA,EACboe,cAAeH,EAAW32C,KAC1B+2C,QAASL,EAAa12C,MAG1By2C,GAAQ/3C,MACJkb,KAAMhd,GAAGkQ,cACTlP,KAAMgD,EAAKo2C,SAAST,GAChB34C,KAAM+4C,EAAW/4C,KACjBoC,KAAM42C,EACNG,QAASL,EAAa12C,OAE1BqL,KAAM,GAAIzO,IAAGoa,UAAU0/B,EACvB95C,GAAG0S,KAAK1O,EAAKq2C,qBAAsBr2C,GAC/B2f,qBAAsBA,EACtBF,QAASs2B,EAAWt2B,QACpBoY,OAAQA,EACRz4B,KAAM42C,EACNxxC,QAASuzB,EACTue,WAAYf,EACZtd,YAAaA,EACb75B,IAAKA,SAKjBy3C,EAAQ/3C,MACJkb,KAAM08B,EACN14C,KAAM24C,EACN37B,KAAM87B,EAAa97B,KACnBvP,KAAM6qC,EAAkBQ,EAAe,QAI3CD,EAAQ/3C,MACJkb,KAAM08B,EACN14C,KAAM24C,EACN37B,KAAM87B,EAAa97B,KACnBvP,KAAMqrC,IAIPD,GAGXxd,cAAe,SAASpe,EAAMjd,EAAMgc,EAAMgB,EAAM+T,EAAU7T,EAASwL,EAAe6wB,GAC9E,GAAIv2C,GAAO/B,KAEPu4C,GADWv8B,EAAKiL,YAAejL,EAAKxP,MAAQwP,EAAKxP,KAAKya,eAEtDuxB,EAAa,KACb5oB,EAAmB0oB,EAAI1oB,iBACvBvP,EAAai4B,EAAIj4B,WACjBwH,EAAcywB,EAAIzwB,YAClB3L,EAAene,GAAGkQ,aAEtBlQ,IAAGY,KAAKoD,EAAKy1C,eAAez8B,EAAMhc,EAAMid,GAAO,SAASrc,EAAK6c,GACzD,GACI5B,GADA69B,EAAWj8B,EAAOT,IAGlBS,GAAOhQ,eAAgBzO,IAAGoa,YAC1BsgC,GAAW;wCAGf79B,EAAKyF,EAAW1E,SACZZ,KAAMyB,EAAOzB,KACbhc,KAAMyd,EAAOzd,KACbgd,KAAM08B,EACNx8B,QAASA,EACTC,aAAcA,IAGdM,EAAOhQ,eAAgBzO,IAAGoa,UAC1BogC,EAAU14C,KAAK+a,GAGf49B,EAAa59B,EAGb4B,EAAOhQ,MACPojB,EAAiBhV,EAAI4B,EAAOhQ,MAC5BsjB,EAASjwB,MAAM+a,GAAIA,EAAIoB,KAAMQ,EAAOhQ,QAGpC6T,EAAW5D,UAAU7B,EAAI7c,GAAGmd,OAAOyC,YAOxB,OAAf66B,IACAz6C,GAAGY,KAAK45C,EAAW,SAAS54C,EAAK+4C,GAC7B,GAAIn7C,IACAo7C,aAAct4B,EAAWhE,UAAUzB,GAAI49B,IAAaz9B,KACpD69B,aAAcv4B,EAAWhE,UAAUzB,GAAI49B,IAAaz8B,KAKxDxe,GAAOkqB,GAAiBpH,EAAWhE,UAAUzB,GAAI89B,IAAW39B,KAE5DsF,EAAWhD,YAAYq7B,EAAUF,GACjC3wB,EAAY8B,YAAY+uB,EAAUn7C,KAKlCg7C,EAAUn2C,QACT,WACG,GAAIy2C,KACJA,GAAMpxB,GAAiBpH,EAAWhE,UAAUzB,GAAI49B,IAAaz9B,KAC7D8M,EAAY8B,YAAY6uB,EAAYK,WAQ5D96C,GAAGsG,OAAOtG,GAAGinB,OAAOzlB,WAChBulB,WAAY,SAASlK,EAAImK,EAAOuzB,GAC5B,YAEA,KAAKv6C,GAAG2V,kBAAkBqD,QACtB,KAAM,IAAIhZ,IAAGiG,MAAM,4CAGvB,IAAI80C,GAAgB,GAAI/6C,IAAG+O,QACvB3M,EAAMm4C,EAAIn4C,IACV6b,EAAOs8B,EAAIt2B,QAAQpH,GACnByF,EAAai4B,EAAIj4B,WAAWhE,UAAUzB,GAAIA,IAC1C7b,EAAOshB,GAAcA,EAAWthB,KAChCgc,EAAOsF,GAAcA,EAAWtF,KAChCg+B,GACIrf,cAAe3U,EAAM2U,cACrBC,cAAc,EACdC,OAAQ7U,EAAM6U,OACdC,YAAa9U,EAAM5jB,MAAQ,KAC3B24B,eAAgB/U,EAAMxe,QACtB+wC,kBAAmB,kBACnBrd,QAASl7B,KAAM,GAAIyiB,QAASuD,EAAMvD,WAEtCw3B,EAAS,GAAIj7C,IAAGinB,OAAO+zB,EAAgB54C,EAuB3C,OArBKpC,IAAGinB,QAAWjnB,GAAG2V,kBAAkB+C,eAAkBuF,EAOrDje,GAAG0S,KAAK,WAEL,GAAI+L,GAASw8B,EAAOxB,eAAez8B,EAAMhc,EAAMid,GAAM,EAEjDQ,IAAUA,EAAOhQ,eAAgBzO,IAAGoa,UACpCqE,EAAOhQ,KAAK8L,SAASb,KAAKqhC,EAAc9rC,QAAS8rC,EAAc5rC,UAG/D/M,EAAIya,EAAK,4BAA6B,SACtCk+B,EAAc5rC,YAEnBlN,SAjBH84C,EAAc5rC,UAEd/M,EAAI,iDAAmDya,EAAK,uFAC6B,UAiBtFk+B,GAKXd,qBAAsB,SAASp8B,GAC3B,YAEA,IAAIq8B,GAAgBr8B,EAAKq8B,cACrBpe,EAAcje,EAAKie,YACnBof,EAAgBr9B,EAAKs8B,OAIzB,OAAKre,IAAgBoe,EAQhBA,GAKDl6C,GAAG2J,QAAQW,OAAO84B,KAAKpjC,GAAG2zC,SAASnyC,UAAU41C,wBAAyB8C,IAAkB,EAClE,eAAlBA,EACOl6C,GAAG2V,kBAAkBsD,aAAeihC,EAAgBpe,EAGxDoe,EATApe,EARe,eAAlBof,EACO,YAEJA,GAqBfd,SAAU,SAASr8B,EAAco9B,GAC7B,YAEA,IAAIC,GAAar9B,EAAarJ,YAAY,KACtC2mC,EAAcF,EAAwB/3C,MAAQ,YAC9C83C,EAAgBC,EAAwBhB,QACxCmB,EAAa,GACbC,EAAYv7C,GAAGuU,aAAawJ,GAC5By9B,EAAgB,EAmBpB,OAjBIL,GAAwBn6C,MAAQm6C,EAAwBn6C,KAAKuK,OAAOlH,SACpEm3C,EAAgB,KAAOL,EAAwBn6C,KAAO,KAGtDo6C,GAAc,GACdE,EAAav9B,EAAapJ,OAAO,EAAGymC,GAEhCF,IAAkBG,IAClBE,EAAYF,EAAY3xC,MAAM,KAAK,IAGvC4xC,GAAcE,EAAgB,IAAMD,GAGpCD,EAAav9B,EAAey9B,EAGzBF,GAIX9B,gBAAiB,SAAStd,GACtB,YAIA,OAFAA,GAAQl8B,GAAGsG,UAAW41B,GAEfA,EAAMuf,KAAK,SAASC,EAAGC,GAC1B,MAAID,GAAEj4B,QAAUk4B,EAAEl4B,QACP,EAEPi4B,EAAEj4B,QAAUk4B,EAAEl4B,SACP,EAEJ,KAIf42B,qBAAsB,SAASx8B,EAAM+9B,GACjC,YAEA,IAAI53C,GAAO/B,KACP0hB,EAAuB9F,EAAK8F,qBAC5BvhB,EAAMyb,EAAKzb,IACXqhB,EAAU5F,EAAK4F,QACfoY,EAAShe,EAAKge,OACdz4B,EAAOya,EAAKza,KACZoF,EAAUqV,EAAKrV,QACf8xC,EAAaz8B,EAAKy8B,WAClBre,EAAcpe,EAAKoe,aAAmC,eAApB2f,EAAWx4C,MAAkC,eAATA,EACtE23C,EAAgB,GAAI/6C,IAAG+O,QACvB8sC,EAAiB,GAAI77C,IAAGm8B,eAAe/5B,GACvCkG,EAASyE,SAASC,cAAc,SA8BpC,OA5BA5K,GAAI,6CAA+Cw5C,EAAW56C,MAE9D66C,EAAe13B,SAASy3B,EAAYtzC,GAASmb,QAASA,EAASoY,OAAQA,EAAQlY,qBAAsBA,IAAuBjK,KAAK,WAC7H,GAAIoiC,GAAqBxzC,EAAOI,UAAUtF,EAAMoF,GAC5CuzC,EAAgB,WACZ35C,EAAI,yCAA2Cw5C,EAAW56C,KAC1D,IAAIyN,GAAOzO,GAAGyI,cAAcqzC,EAC5Bf,GAAc9rC,QAAQR,GAG1BwtB,GACAj4B,EAAKg4C,kBAAkBJ,EAAYE,EAAoB15C,GAAKsX,KAAK,SAASuiC,GACtEH,EAAqBG,EACrBF,KAEJ,WACI35C,EAAI,wFAAyF,SAC7F25C,MAIJA,KAEL,WACC35C,EAAI,iDAAmDw5C,EAAW56C,KAAM,SACxE+5C,EAAc5rC,QAAQmrC,KAGnBS,GAIXiB,kBAAmB,SAASE,EAAeJ,EAAoB15C,GAC3D,YAEA,IAAI+5C,GAAS,GAAIttC,YACbutC,EAAkB,GAAIp8C,IAAG+O,QACzBstC,EAAuB,EAc3B,OAZAF,GAAOntC,OAAS,WACZqtC,EAAuBF,EAAOh1C,OAC9Bi1C,EAAgBntC,QAAQjP,GAAGs8C,aAAa9L,QAAQ6L,EAAsBP,KAG1EK,EAAOjtC,QAAU,WACb9M,EAAI,mBAAqB85C,EAAcl7C,KAAO,2DAA4D,SAC1Go7C,EAAgBjtC,WAGpBgtC,EAAOI,cAAcL,GAEdE,GAGXI,eAAgB,SAAS7zC,GACrB,YAEA,IAAIE,GAAYE,EAAYH,EAAaE,CAsBzC,OAlBID,GADAF,EAAQe,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKjB,EAAQe,MAAM,KAAK,IAGxBG,UAAUlB,EAAQe,MAAM,KAAK,IAI9CX,EAAaJ,EAAQe,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBd,EAAc,GAAIkB,aAAYjB,EAAWxE,QACzCyE,EAAW,GAAIiB,YAAWnB,GAC1B5I,GAAGY,KAAKiI,EAAY,SAASjH,EAAKoI,GAC9BlB,EAASlH,GAAOoI,EAAUC,WAAW,KAGlChI,KAAKw6C,YAAY7zC,EAAaG,IAGzC0zC,YAAa,SAASp8C,EAAMkI,GACxB,YAEA,IAAIU,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOlJ,GACZiJ,EAAYE,QAAQjB,IAGpB,GAAIkB,OAAMpJ,IAAQ+C,KAAMmF,OChZ3CvI,GAAGs8C,aAAe,WAGjB,GAAIA,KA+KD,OA7KAA,GAAaI,QAAU,oEAMvBJ,EAAaK,SAAW,SAAS7vC,GAE7B,GACI8vC,GAAMC,EACNC,EAAMC,EAAMC,EAFZC,EAAS,GACGC,EAAO,GACDC,EAAO,GACzB5pC,EAAI,CAER,GACIqpC,GAAO9vC,EAAMyG,KACbspC,EAAO/vC,EAAMyG,KACb2pC,EAAOpwC,EAAMyG,KAEbupC,EAAOF,GAAQ,EACfG,GAAgB,EAAPH,IAAa,EAAMC,GAAQ,EACpCG,GAAgB,GAAPH,IAAc,EAAMK,GAAQ,EACrCC,EAAc,GAAPD,EAEHE,MAAMP,GACPG,EAAOG,EAAO,GACNC,MAAMF,KACdC,EAAO,IAGVF,EAASA,EACNh7C,KAAKy6C,QAAQ98C,OAAOk9C,GACpB76C,KAAKy6C,QAAQ98C,OAAOm9C,GACpB96C,KAAKy6C,QAAQ98C,OAAOo9C,GACpB/6C,KAAKy6C,QAAQ98C,OAAOu9C,GACvBP,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SACvB5pC,EAAIzG,EAAMzI,OAEnB,OAAO44C,IAGXX,EAAa9L,QAAU,SAAS6M,EAAgBC,GAI5C,IAAKD,EAAeh6C,MAFO,2BAI1B,MAAOi6C,EAGR,IAAIC,GAAWt7C,KAAKu7C,SAASH,EAAet2C,QAPjB,0BAO+C,KACtE02C,EAAWx7C,KAAKy7C,eAAeH,GAE/B/kB,EAAQv2B,KAAK07C,iBAAiBL,EAAmBG,EAErD,OAZ2B,0BAYGx7C,KAAK06C,SAASnkB,IAKhD8jB,EAAaqB,iBAAmB,SAASL,EAAmBG,GAEpD,GAAIG,GAAY37C,KAAK47C,aAAaJ,GAC9BK,EAAgB77C,KAAK87C,WAAWT,EAAmBM,EAGvD,OAFc,IAAI7zC,YAAW+zC,IAMrCxB,EAAauB,aAAe,SAASJ,GAG7B,IAAK,GADDO,GACKC,EAAI,EAAGA,EAAIR,EAASp5C,OAAQ45C,IAGjC,GADAD,EAAMP,EAASQ,GACD,KAAVD,EAAI,GAAsB,KAAVA,EAAI,GAEpB,MAAOA,EAGf,WAIR1B,EAAayB,WAAa,SAAST,EAAmBM,GAE9C,GAAIM,GAAYZ,EAAkBv2C,QAAQ,0BAA2B,IACjEo3C,EAAMl8C,KAAKu7C,SAASU,GACpBE,EAAgBD,EAAIx0C,QAAQ,IAAI,GAChC00C,EAAMF,EAAIr+C,MAAM,EAAGs+C,GACnBE,EAAMH,EAAIr+C,MAAMs+C,GAChBG,EAAQF,CAIb,OAFCE,GAAQA,EAAMzrC,OAAO8qC,GACrBW,EAAQA,EAAMzrC,OAAOwrC,IAM7BhC,EAAaoB,eAAiB,SAASc,GAKnC,IAHA,GAAIC,GAAO,EACPhB,OAGJ,CACI,GAA2B,KAAvBe,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAAW,KACjE,IAA2B,KAAvBD,EAAcC,GAA0C,KAA3BD,EAAcC,EAAO,GAElDA,GAAQ,MAGZ,CACI,GAAIp6C,GAAmC,IAA1Bm6C,EAAcC,EAAO,GAAWD,EAAcC,EAAO,GAC9DC,EAAWD,EAAOp6C,EAAS,EAC3B25C,EAAMQ,EAAc1+C,MAAM2+C,EAAMC,EACpCjB,GAAS37C,KAAKk8C,GACdS,EAAOC,EAEX,GAAID,EAAOD,EAAcn6C,OAAQ,MAGrC,MAAOo5C,IAKXnB,EAAakB,SAAW,SAAS1wC,GAE7B,GACI8vC,GAAMC,EACNC,EAAMC,EAAMC,EADAE,EAAO,GACDC,EAAO,GACzB5pC,EAAI,EACJ4qC,IAIJ,IADiB,sBACFj9C,KAAK4L,GAChB,KAAM,IAAI7G,OAAM,uHAGpB6G,GAAQA,EAAM/F,QAAQ,sBAAuB,GAE7C,GACI+1C,GAAO76C,KAAKy6C,QAAQ/yC,QAAQmD,EAAMlN,OAAO2T,MACzCwpC,EAAO96C,KAAKy6C,QAAQ/yC,QAAQmD,EAAMlN,OAAO2T,MACzCypC,EAAO/6C,KAAKy6C,QAAQ/yC,QAAQmD,EAAMlN,OAAO2T,MACzC4pC,EAAOl7C,KAAKy6C,QAAQ/yC,QAAQmD,EAAMlN,OAAO2T,MAEzCqpC,EAAQE,GAAQ,EAAMC,GAAQ,EAC9BF,GAAgB,GAAPE,IAAc,EAAMC,GAAQ,EACrCE,GAAgB,EAAPF,IAAa,EAAKG,EAE3BgB,EAAIr8C,KAAK86C,GAEG,IAARI,GACDmB,EAAIr8C,KAAK+6C,GAEA,IAARM,GACDgB,EAAIr8C,KAAKo7C,GAGZN,EAAOC,EAAOK,EAAO,GACrBJ,EAAOC,EAAOC,EAAOG,EAAO,SAEvB5pC,EAAIzG,EAAMzI,OAEnB,OAAO85C,IAIJ7B,KC7KXt8C,GAAGs8B,cAAgB,SAAShqB,EAAU4S,GAClC,YAEA,IAAIy5B,MACAC,EAAc,EACdC,EAAY,EAEZC,GAAiB,EACjBC,GAAgB,EAChBC,EAAgB,SAASzxB,EAAQC,GACzBD,IAAWuxB,GAAkBtxB,IAAUuxB,GACvCzsC,EAASib,EAAQC,GAGrBsxB,EAAiBvxB,EACjBwxB,EAAgBvxB,GAQpByxB,EAAmB,SAAS/pB,EAAQgqB,GAChC,GAAIC,IAAO,CASX,OAPAn/C,IAAGY,KAAKs0B,EAAQ,SAAStzB,EAAKw9C,GAC1B,GAAIp/C,GAAG2J,QAAQu1C,EAAWE,IAAa,EAEnC,MADAD,IAAO,GACA,IAIRA,GAGXtxB,EAAW,SAAShR,GAChBwiC,EAAoBxiC,GAAI,GAAI,SACrB8hC,GAAgB9hC,IAG3BsY,EAAgB,SAASF,EAAYC,EAAQgqB,IACnB,IAAlBhqB,EAAO7wB,QAAgB46C,EAAiB/pB,EAAQgqB,MAChDF,EAAcH,EAAWA,GACzB58C,KAAKsa,UAIb+iC,EAAQ,SAASziC,GACb,GAAImB,GAAOkH,EAAQrI,EAGfmB,GAAO,IACPqhC,EAAoBxiC,EAAI,EAAGmB,GAC3B2gC,EAAgB9hC,IAAO0Q,OAAQ,EAAGC,MAAOxP,KAYjDqhC,EAAsB,SAASxiC,EAAI0iC,EAAWC,GAC1C,GAAIC,GAAYd,EAAgB9hC,GAAM8hC,EAAgB9hC,GAAI0Q,OAAS,EAC/DmyB,EAAWf,EAAgB9hC,GAAM8hC,EAAgB9hC,GAAI2Q,MAAQ,CAE7D+xB,MAAc,GAAMC,KAAa,GACjCZ,GAAea,EACfZ,GAAaa,IAGTH,IACAX,GAAeW,EAAYE,GAE3BD,IACAX,GAAaW,EAAWE,IAIhCV,EAAcJ,EAAaC,GAGnC7+C,IAAGsG,OAAOrE,MAENkzB,cAAeA,EAGf9W,eAAgB,SAASxB,EAAI+B,EAAWD,GAChCA,IAAc3e,GAAGmd,OAAO2C,UAAYnB,IAAc3e,GAAGmd,OAAOyC,SAC5DiO,EAAShR,GAEJ8B,IAAc3e,GAAGmd,OAAOW,YAC7BwhC,EAAMziC,IAKdgZ,qBAAsB,SAAShZ,EAAI0Q,EAAQC,GACvC6xB,EAAoBxiC,EAAI0Q,EAAQC,GAChCmxB,EAAgB9hC,IAAO0Q,OAAQA,EAAQC,MAAOA,IAIlDsK,UAAW,SAASjb,GAChByiC,EAAMziC,IAGVN,MAAO,WACHoiC,KACAC,EAAc,EACdC,EAAY,MCzHxB7+C,GAAGuqB,aAAe,SAAS9P,GACvB,YAYA,SAASklC,GAAQ30C,GACb,MAAOA,GAAK5H,MACwB,IAAhC4H,EAAK5H,KAAKuG,QAAQ,UAG1B,QAASi2C,KACLC,EAAqB7/C,GAAGhB,EAAQwrB,eAAevlB,OAAO,QAAS,SAASqyB,GACpE,GAAIwoB,GAAgBxoB,EAAMwoB,aAEtBA,IACA9/C,GAAGY,KAAKk/C,EAAcryC,MAAO,SAAS7L,EAAKoJ,GACvC,GAAI20C,EAAQ30C,GAAO,CACf,GAAIyD,GAAOzD,EAAK+0C,WAChB/gD,GAAQ2B,UAAU+pB,cAAcjc,QAOpD,QAASuxC,KACDH,GACAA,IAhCR,GAAI7gD,GAAS6gD,CAEb7gD,IACIwrB,cAAe,KACf7pB,WACIyB,IAAK,SAASC,EAAS6H,KACvBwgB,cAAe,SAASjc,OA8BhCzO,GAAGsG,OAAOtH,EAASyb,GACnBmlC,IAEA5/C,GAAGsG,OAAOrE,MACNsa,MAAO,WACHyjC,QCpCZhgD,GAAGsyB,YAAc,SAAStzB,EAASihD,EAAa79C,GAC5C,YAgCA,SAAS89C,GAAqBC,GACtBA,EAAO/3C,aAAa,YACpBpE,EAAK2uB,YAAcwtB,EAAO/3C,aAAa,WAM/C,QAASg4C,GAAaD,EAAQE,GAC1B,IAAIF,EAAOG,eAAkBH,EAAOG,gBAKhC,OAAO,CAJPl+C,GAAI,yDAA0D,SAC9Di+C,IAQR,QAASE,GAAoBJ,GACzB,GAAIE,GAAeF,EAAOK,MAG1BxgD,IAAGmgD,GAAQl7C,OAAO,SAAU,SAASqyB,GACjCA,EAAQA,GAASpuB,OAAOouB,MAEpBA,EAAMxlB,eACNwlB,EAAMxlB,iBAGNwlB,EAAMtlB,aAAc,EAGxBouC,EAAaD,EAAQE,IAAiBJ,MAK1CE,EAAOK,OAAS,WACZJ,EAAaD,EAAQE,IAAiBJ,KAM9C,QAASQ,GAAgBN,GAarB,MAZIA,KACIngD,GAAGkL,SAASi1C,KACZA,EAASpzC,SAASs7B,eAAe8X,IAGjCA,IACA/9C,EAAI,8BACJ89C,EAAqBC,GACrBzkB,GAAmB6kB,EAAoBJ,KAIxCA,EAzFX,GAAIn8C,GAAQ/B,KACRy5B,EAAkB18B,EAAQ08B,gBAC1BykB,EAASnhD,EAAQ0D,QACjB+vB,EAAazzB,EAAQyzB,UAGzBzyB,IAAGsG,OAAOrE,MAIN0wB,YAAa,KAIbD,cAAeD,EAGfF,gBAAgB,EAGhBC,sBAAuB,WAEnB,MAAc,OAAV2tB,EACO,KAGJn8C,EAAK08C,UAAUP,MAkE9BA,EAASM,EAAgBN,GACzBl+C,KAAKswB,iBAAmB4tB,GAG5BngD,GAAGsG,OAAOtG,GAAGsyB,YAAY9wB,WAGrBk/C,UAAW,SAAS3sC,GAChB,YACA,IAAIf,MACA2tC,EAAoB,SAASv9C,GACzB,GAAIw9C,IACA,SACA,QACA,QACA,SAGJ,OAAO5gD,IAAG2J,QAAQi3C,EAAiBx9C,EAAKrD,eAAiB,GAE7D8gD,EAAkB,SAASz9C,GACvB,MAAOpD,IAAG2J,SAAS,WAAY,SAAUvG,EAAKrD,gBAAkB,GAEpE+gD,EAAc,SAAS18C,GACnB,SAAIy8C,EAAgBz8C,EAAGhB,OAAUgB,EAAG28C,UAI7B38C,EAAG2R,UAAsC,WAA1B3R,EAAGhB,KAAKrD,eAElCihD,EAAc,SAASC,GACnB,GAAIx2C,GAAQ,IASZ,OAPAzK,IAAGY,KAAKZ,GAAGihD,GAAQz5C,WAAY,SAAS5F,EAAK6F,GACzC,GAAoC,WAAhCA,EAAMiF,QAAQ3M,eAA8B0H,EAAMy5C,SAElD,MADAz2C,GAAQhD,EAAMgD,OACP,IAIRA,EAmBf,OAhBAzK,IAAGY,KAAKmT,EAAKotC,SAAU,SAASv/C,EAAKwC,GACjC,IAAKpE,GAAGoM,QAAQhI,GAAI,IAAsC,aAA7BA,EAAGsI,QAAQ3M,gBACpC4gD,EAAkBv8C,EAAGhB,OACpB09C,EAAY18C,IAIZ,GAAiC,WAA7BA,EAAGsI,QAAQ3M,gBAA+B+gD,EAAY18C,GAAK,CAChE,GAAIqG,GAAQu2C,EAAY58C,EAEV,QAAVqG,IACAuI,EAAI5O,EAAGpD,MAAQyJ,QANnBuI,GAAI5O,EAAGpD,MAAQoD,EAAGqG,QAWnBuI,KCzJfhT,GAAGomC,YAAcpmC,GAAGomC,gBACpBpmC,GAAGomC,YAAY0B,kBAAoB,SAAS9oC,EAASkiC,GACjD,YAUA,SAASkgB,GAAqBvkC,EAAIurB,GAG9B,GAAI7T,GAAU8sB,EAAKC,CAGnB,KAEID,EAAMjZ,EAAOe,iBAAmBf,EAAOmZ,cAAcx0C,SACrDu0C,EAAYD,EAAI3Y,KAAKt2B,UAErBhQ,EAAI,yCACJA,EAAI,eAAiBk/C,GAEjBA,GAAaA,EAAUj+C,MAAM,YAC7Bi+C,EAAYD,EAAI3Y,KAAKhhC,WAAWA,WAAW85C,WAG/CjtB,EAAW7C,EAAQoX,mBAAmBwY,GAE1C,MAAOn/C,GACHC,EAAI,wDAA0DD,EAAME,QAAU,IAAK,SACnFkyB,GAAYtlB,SAAS,GAGzB,MAAOslB,GAMX,QAASktB,GAAW5kC,EAAIurB,GACpB,GAAI5oC,GAASR,EAAQ8qB,YAAYnF,IAAI9H,GACjC2M,EAA0C,QAAjCxqB,EAAQwqB,OAAOzpB,cAA0B,MAAQ,OAC1D4gB,EAAW3hB,EAAQ+qB,cAAcpF,IAAI9H,GACrC7b,EAAOwhB,EAAQ3F,EAKnB,OAHArd,GAAOR,EAAQ4qB,UAAYnE,EAAQ5I,GACnCrd,EAAOR,EAAQm6B,eAAiBn4B,EAEzB0wB,EAAQ2X,oBACX7f,OAAQA,EACR7I,SAAUA,EACVnhB,OAAQA,EACR85B,aAAct6B,EAAQs6B,aACtBgQ,WAAYlB,EAAOpnC,OArD3B,GAAI0wB,GAAUzvB,KACVugB,EAAU0e,EAAM1e,QAChBiD,EAAUyb,EAAMzb,QAChBrjB,EAAM8+B,EAAM9+B,GAsDhBH,MAAK8jC,WAAa,SAASlpB,GACvB,GAGI9I,GAHAjH,EAAQ4kB,EAAQzV,SAASY,GACzBurB,EAAS1W,EAAQ0X,cAAcvsB,GAC/B/N,EAAU,GAAI9O,IAAG+O,OA8BrB,OA3BAgF,GAAO0tC,EAAW5kC,EAAIurB,GACtBr0B,EAAKE,YAAYnH,GAEjB4kB,EAAQuX,iBAAiBb,EAAQ,SAASsZ,GACtCt/C,EAAI,gBAEJ,IAAImyB,GAAWmtB,EAAsBA,EAAsBN,EAAqBvkC,EAAIurB,EAEpF1W,GAAQqX,iBAAiBlsB,GAGpB7d,EAAQgrB,KAAK6I,UACd7yB,GAAGooC,GAAQviC,SAGX0uB,EAAStlB,QACTH,EAAQG,QAAQslB,GAGhBzlB,EAAQK,QAAQolB,KAIxBnyB,EAAI,8BAAgCya,GACpC9I,EAAKysC,SACLxgD,GAAG+T,GAAMlO,SAEFiJ,GAGX9O,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAG8nC,mBACnB9oC,SACIipC,OAAQjpC,EAAQgrB,KAAK6I,SACrBhG,UAAW7tB,EAAQ6tB,WAGvBqU,OACIrT,SAAU7uB,EAAQ6uB,SAClBrL,QAASA,EACTiD,QAASA,EACTrjB,IAAKA,OC5GjBpC,GAAGomC,YAAcpmC,GAAGomC,gBACpBpmC,GAAGomC,YAAYoD,iBAAmB,SAAS3rB,EAAMqjB,GAC7C,YAEA,IAAIxP,GAAUzvB,KACVugB,EAAU0e,EAAM1e,QAChB0C,EAAUgc,EAAMhc,QAChBO,EAAUyb,EAAMzb,QAChBrjB,EAAM8+B,EAAM9+B,IACZu/C,EAAY9jC,EAAKub,gBAAkBvb,EAAKyb,aAExCsoB,EAA4B,SAAS/kC,EAAIrd,EAAQ8uB,GAC7C,GAAItQ,GAAOkH,EAAQrI,GACf7b,EAAOwhB,EAAQ3F,EAEdgB,GAAKwb,oBACN75B,EAAOqe,EAAK5F,SAAS4iB,WAAWpM,WAAaH,EAAUsd,KACvDpsC,EAAOqe,EAAK5F,SAAS4iB,WAAWC,gBAAkBxM,EAAUrgB,MAC5DzO,EAAOqe,EAAK5F,SAAS4iB,WAAWE,WAAazM,EAAUtQ,KACvDxe,EAAOqe,EAAK5F,SAAS4iB,WAAWI,YAAc3M,EAAUud,MACxDrsC,EAAOqe,EAAK2b,mBAAqBxb,GAOjC2jC,IAAc9jC,EAAKwb,oBACnB75B,EAAOqe,EAAKsb,eAAiBn4B,IAIrC6gD,EAAyB,GAAI7hD,IAAGomC,YAAY0b,4BACxC93B,KAAMnM,EAAKmM,KACXrJ,SAAU9C,EAAK5F,SAAShJ,QAAQ0R,SAChCwG,QAAStJ,EAAK5F,SAAShJ,QAAQkY,QAC/BgU,YAAatd,EAAK5F,SAAShJ,QAAQksB,YACnC/4B,IAAKA,EACLonB,OAAQ3L,EAAK5F,SAAShJ,QAAQua,OAC9BhqB,OAAQqe,EAAK5F,SAAShJ,QAAQzP,SAGlCuiD,EAAiC,SAASllC,EAAI8Q,GAC1C,GAAI7e,GAAU,GAAI9O,IAAG+O,OAerB,OAbA4e,GAAI2Q,mBAAqB,WACrB,GAAuB,IAAnB3Q,EAAIqR,WAAkB,CACtB,GAAI73B,GAAS66C,EAAwBnlC,EAAI8Q,EAErCxmB,GAAO8H,QACPH,EAAQG,QAAQ9H,EAAOotB,SAAU5G,GAGjC7e,EAAQK,QAAQhI,EAAOotB,SAAU5G,KAKtC7e,GAGXmzC,EAA0B,SAASplC,GAC/B,GAAIrd,GAASqe,EAAKiM,YAAYnF,IAAI9H,GAC9B7b,EAAOwhB,EAAQ3F,GACfmB,EAAOkH,EAAQrI,EAOnB,OALArd,GAAOqe,EAAK+L,UAAYnE,EAAQ5I,GAChCrd,EAAOqe,EAAKsb,eAAiBn4B,EAC7BxB,EAAOqe,EAAK2b,mBAAqBxb,EACjCxe,EAAOqe,EAAK5F,SAAS4iB,WAAWI,YAAcvJ,EAAQsS,gBAAgBnnB,GAE/Drd,GAGX0iD,EAAwB,SAASv0B,EAAK4G,GAClC,MAAOv0B,IAAG2J,SAAS,IAAK,IAAK,IAAK,IAAK,KAAMgkB,EAAIxQ,QAAU,GACtDU,EAAK0b,qBAAuBhF,EAAStlB,SACtCslB,EAAShY,OAGjBylC,EAA0B,SAASnlC,EAAI8Q,GACnC,GAAI4G,EAOJ,OALAnyB,GAAI,sCAAwCya,GAC5Cza,EAAI,kBAAoBurB,EAAI0rB,cAE5B9kB,EAAW4tB,GAAc,EAAMx0B,IAG3B1e,SAAUizC,EAAsBv0B,EAAK4G,GACrCA,SAAUA,IAKlB4tB,EAAgB,SAAS/0C,EAAQugB,GAC7B,GAAI4G,KAEJ,KACInyB,EAAIpC,GAAGwL,OAAO,4CAA6CmiB,EAAIxQ,OAAQwQ,EAAI0rB,eAC3E9kB,EAAWv0B,GAAGkU,UAAUyZ,EAAI0rB,cAEhC,MAAOl3C,GACHiL,GAAUyQ,EAAK0b,oBAAsBn3B,EAAI,qDAAuDD,EAAME,QAAU,IAAK,SAGzH,MAAOkyB,IAGX6tB,EAA4B,SAASvlC,GACjC,GAAI/N,GAAU,GAAI9O,IAAG+O,OAcrB,OAZA8yC,GAAuBQ,SACfxlC,EACA6U,EAAQ2Z,WAAWxuB,GACnBolC,EAAwBplC,GACxBgB,EAAKgM,cAAclF,IAAI9H,IAE1BnD,KAAK,SAASiU,GACX7e,EAAQG,QAAQkzC,GAAc,EAAOx0B,GAAMA,IAC5C,SAASA,GACR7e,EAAQK,QAAQgzC,GAAc,EAAOx0B,GAAMA,KAG5C7e,GAGXwzC,EAA8B,SAASC,GACnC,GAOI/iD,GAPAwO,EAAau0C,EAAmBv0C,WAChC6O,EAAK0lC,EAAmB1lC,GACxB8Q,EAAM40B,EAAmB50B,IACzB60B,EAAeD,EAAmBC,iBAClCC,EAAeF,EAAmBE,iBAClCC,EAAgBH,EAAmB/iD,WACnCmjD,EAAoBH,EAAahjD,WAGjCoU,EAAW+tC,EAAY,GAAIz0C,UAAa,KACxCsc,EAASg5B,EAAah5B,QAAU3L,EAAK2L,OACrC7I,EAAW6hC,EAAa7hC,UAAY9C,EAAKkM,cAAcpF,IAAI9H,GAC3D7b,EAAOwhB,EAAQ3F,GACfmB,EAAOkH,EAAQrI,EAiCnB,OA/BIgB,GAAKwb,mBACL75B,EAASQ,GAAGsG,UAAWm8C,GACvBziD,GAAGsG,OAAO9G,EAAQmjD,KAGlBnjD,EAASQ,GAAGsG,UAAWm8C,GACvBziD,GAAGsG,OAAO9G,EAAQmjD,GAClB3iD,GAAGsG,OAAO9G,EAAQkjD,GAElBljD,EAAOqe,EAAK+L,UAAYnE,EAAQ5I,GAChCrd,EAAOqe,EAAKsb,eAAiBn4B,EAEzB2gD,EACAniD,EAAOqe,EAAK2b,mBAAqBxb,EAE3BH,EAAKyb,eACX95B,EAAOqe,EAAKgP,WAAa7rB,IAK5B6c,EAAKyb,eACN3Y,EAAW3gB,GAAG+S,QAAQvT,EAAQmhB,IAGlCgN,EAAI8Q,KAAKjV,EAAQ7I,GAAU,GAEvB9C,EAAKmM,KAAK6I,UAAYhV,EAAKmM,KAAKyR,kBAChC9N,EAAIxX,iBAAkB,GAGtBwrC,GACI9jC,EAAKyb,cACLt5B,GAAG2T,aAAanU,EAAQoU,GAG5BA,EAASrK,OAAOsU,EAAKgP,UAAW7e,GACzB4F,GAGJ5F,GAGX40C,EAAmB,SAASC,GACxB,GAAIC,GAAkBD,EAAeC,gBACjCjmC,EAAKgmC,EAAehmC,GACpB8Q,EAAMk1B,EAAel1B,GAEzB,IAAIm1B,EACA9iD,GAAGY,KAAKkiD,EAAiB,SAASC,EAAYC,GAC1Cr1B,EAAI2R,iBAAiByjB,EAAYC,SAGpC,CACD,GAAIC,GAAeplC,EAAKgM,cAAclF,IAAI9H,GACtC7O,EAAa0jB,EAAQzN,QAAQpH,EAEjC8Q,GAAI2R,iBAAiB,SAAU,oBAC/B3R,EAAI2R,iBAAiB,mBAAoB,kBACzC3R,EAAI2R,iBAAiB,gBAAiB,YAEjCqiB,IACDh0B,EAAI2R,iBAAiB,eAAgB,4BAErC3R,EAAI2R,iBAAiB,cAAetxB,EAAW5K,OAGnDpD,GAAGY,KAAKqiD,EAAc,SAASjiD,EAAMZ,GACjCutB,EAAI2R,iBAAiBt+B,EAAMZ,MAK3CJ,IAAGsG,OAAOrE,MACNuiC,YAAa,SAAS0e,GAClB,GAOIp0C,GAASq0C,EAAQV,EAPjB5lC,EAAKqmC,EAAkBrmC,GACvBklB,EAAWmhB,EAAkBnhB,SAC7BwC,EAAY2e,EAAkB3e,cAC9BjJ,EAAW4nB,EAAkB5nB,SAE7BhN,EAAYoD,EAAQsQ,cAAcnlB,EAAIklB,GACtCpU,EAAM+D,EAAQ2Z,WAAWxuB,EAAIklB,GACEviC,IA4BnC,OA1BAsP,GAAUizC,EAA+BllC,EAAI8Q,GAC7C+D,EAAQ+a,yBAAyB5vB,EAAIklB,EAAUzT,EAAUtQ,MACzDykC,EAAe5kC,EAAKiM,YAAYnF,IAAI9H,GACpC+kC,EAA0B/kC,EAAIrd,EAAQ8uB,GAElCgN,IACA97B,EAAOqe,EAAK9E,OAAO8hB,WAAWS,WAAY,GAG9C6nB,EAASb,GACLt0C,WAAYsgB,EAAU7f,KACtBoO,GAAIA,EACJ4lC,aAAcA,EACdjjD,OAAQA,EACRmuB,IAAKA,EACL60B,aAAcje,IAGlBqe,GACIE,gBAAiBve,EAAUpd,QAC3BtK,GAAIA,EACJ8Q,IAAKA,IAGTA,EAAIgR,KAAKwkB,GAEFr0C,GAGXi3B,WAAY,SAASlpB,GACjB,GACI/N,GAAS6e,EAAK80B,EAAcU,EAD5Bn1C,EAAa0jB,EAAQzN,QAAQpH,EAsBjC,OAnBA8Q,GAAM+D,EAAQ2Z,WAAWxuB,GACzB6U,EAAQ+a,yBAAyB5vB,GACjC/N,EAAUizC,EAA+BllC,EAAI8Q,GAC7C80B,EAAe5kC,EAAKiM,YAAYnF,IAAI9H,GAEpCsmC,EAASb,GACLt0C,WAAYA,EACZ6O,GAAIA,EACJ4lC,aAAcA,EACd90B,IAAKA,IAGTi1B,GACI/lC,GAAIA,EACJ8Q,IAAKA,IAGTA,EAAIgR,KAAKwkB,GAEFr0C,KAIf9O,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGwpC,kBACnBxqC,QAASgB,GAAGsG,QAAQ3G,UAAW,eAAgBke,GAC/CqjB,MAAOlhC,GAAGsG,QAAQme,YAAa5G,EAAKkM,cAAcpF,KAAMuc,MAG5DlhC,GAAGuP,SAAStN,KAAM,SAASyN,GACvB,OACI2yB,eAAgB,SAASxlB,GAGrB,MAFAqkB,GAAMmF,aAAaxpB,GAEfgB,EAAK5F,SAAShJ,QAAQ0R,SACfyhC,EAA0BvlC,GAG1BnN,EAAO2yB,eAAexlB,EAAI7c,GAAG0S,KAAKyvC,EAAelgD,MAAM,SCzSlFjC,GAAGomC,YAAY0b,2BAA6B,SAASrnC,GACjD,YAEA,IAAIgzB,GACAzuC,GACIgrB,MACI8I,UAAU,EACVD,UAAU,EACV4I,iBAAiB,GAErB9a,SAAU,KACVve,IAAK,SAASqJ,EAAKvB,KACnBsf,OAAQ,QAEZ45B,KACAC,GACI1+B,IAAK,SAAS9H,GACV,MAAI7c,IAAGwK,WAAWxL,EAAQ2hB,UACf3hB,EAAQ2hB,SAAS9D,GAGrB7d,EAAQ2hB,UAI3B3gB,IAAGsG,OAAOtH,EAASyb,GAEnBgzB,EAAYztC,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGw8B,eAC/B6C,aAAc,mBACdR,YAAa7/B,EAAQm8B,YAAc,mBAAqB,oCACxDwE,cAAe3gC,EAAQwqB,QACvBA,OAAQxqB,EAAQwqB,OAChBO,cAAes5B,EACf9jB,oCAAoC,EACpCvV,KAAMhrB,EAAQgrB,KACd5nB,IAAKpD,EAAQoD,IACbsrB,WAAY,SAAS7Q,EAAI8Q,EAAKtD,GAC1B,GAAIvb,GAAUs0C,EAASvmC,SAEhBumC,GAASvmC,GAEZwN,EACAvb,EAAQK,QAAQwe,GAGhB7e,EAAQG,QAAQ0e,OAK5B3tB,GAAGsG,OAAOrE,MACNogD,SAAU,SAASxlC,EAAI8Q,EAAKnuB,EAAQ2nB,GAChC,GAAIrY,GAAU,GAAI9O,IAAG+O,OAWrB,OATA/P,GAAQoD,IAAI,0CAA4Cya,GAExDumC,EAASvmC,GAAM/N,EAEf2+B,EAAUxN,cAAcpjB,GACnByjB,WAAWthC,EAAQQ,OAAOqd,IAAOrd,GACjCihC,YAAYzhC,EAAQmoB,QAAQtK,IAAOsK,GACnCwX,KAAKhR,GAEH7e,MCtEnB9O,GAAGyE,YAAc,SAASgW,GACtB,YAoBA,SAAS6oC,GAAmBrhC,EAAOshC,GAE/B,GAAIC,GAAejiD,MAAMC,UAAU1B,MAAM2B,KAAKwgB,EAE9CjjB,GAAQ2B,UAAU8iD,QAAQ,WAAaxhC,EAAM5d,OAAS,mBACtDk/C,EAAeG,cAAa,GAC5B1kD,EAAQ2B,UAAUgjD,+BAA+BH,EAAcD,EAAeK,cAGlF,QAASC,GAAiBtnB,GACtB,GAAIunB,GAAoB,GAAI9jD,IAAG+O,OAwC/B,OAtCIwtB,GAAM3wB,OACN2wB,EAAMte,KAAK,SAASA,GAChBA,EAAK8lC,OAASC,EAAqBznB,GACnC0nB,EAAaniD,KAAKmc,GAClB6lC,EAAkB70C,WAEtB,SAASi1C,GACLllD,EAAQ2B,UAAU8iD,QAAQ,oBAAsBlnB,EAAM4nB,SAAW,sBAAwBD,EAAU/wB,KAAO,IAAK,SAC/G2wB,EAAkB30C,YAGjBotB,EAAM6nB,aACXC,EAAoB9nB,GAAO7iB,KACvB,SAAwBkD,GACpB,GAAI0nC,GAAc1nC,EAAQvY,MAE1BrE,IAAGY,KAAKgc,EAAS,SAAShb,EAAK26B,GAC3BsnB,EAAiBtnB,GAAOpiB,KAAK,WACzBmqC,GAAe,EAEK,IAAhBA,GACAR,EAAkB70C,cAKzB2N,EAAQvY,QACTy/C,EAAkB70C,WAI1B,SAAqBi1C,GACjBllD,EAAQ2B,UAAU8iD,QAAQ,oBAAsBlnB,EAAM4nB,SAAW,sBAAwBD,EAAU/wB,KAAO,IAAK,SAC/G2wB,EAAkB30C,YAKvB20C,EAGX,QAASE,GAAqBznB,GAC1B,GAAIv7B,GAAOu7B,EAAMv7B,KACbmjD,EAAW5nB,EAAM4nB,SACjBI,EAAwBJ,EAASzvC,YAAY1T,EAUjD,OAPAmjD,GAAWA,EAASxvC,OAAO,EAAG4vC,GAGH,MAAvBJ,EAASvkD,OAAO,KAChBukD,EAAWA,EAASxvC,OAAO,IAGxBwvC,EAIX,QAASE,GAAoB9nB,EAAO4f,EAAQqI,EAAcC,GACtD,GAAI31C,GAAU21C,GAAmB,GAAIzkD,IAAG+O,QACpC21C,EAAYvI,GAAU5f,EAAMooB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqBhoC,GACjB,GAAIioC,GAAaL,EAAeA,EAAa1xC,OAAO8J,GAAWA,CAE3DA,GAAQvY,OACR2nB,WAAW,WACPq4B,EAAoB9nB,EAAOmoB,EAAWG,EAAY/1C,IACnD,GAGHA,EAAQG,QAAQ41C,IAIxB/1C,EAAQK,SAGLL,EAGX,QAASg2C,GAAmBt3C,EAAc+1C,GACtC,GAAIwB,MACAC,EAA4B,GAAIhlD,IAAG+O,OA4CvC,OA1CA/P,GAAQ2B,UAAUskD,yBAClB1B,EAAeG,cAAa,GAExBl2C,EAAayU,MAAM5d,OAAS,IAAMrF,EAAQkmD,oBAC1ClmD,EAAQ2B,UAAUgjD,mCAClB3kD,EAAQ2B,UAAUwkD,UAAU,oBAAqB,IACjD5B,EAAeG,cAAa,GAC5BsB,EAA0B71C,YAG1B80C,KAEIjkD,GAAGuN,sBAAsBC,GACzBxN,GAAGY,KAAK4M,EAAaC,MAAO,SAAS7L,EAAKoJ,GACtC,GAAIuxB,GAAQvxB,EAAK0C,kBAEb6uB,KAEIA,EAAM3wB,OACNq4C,EAAaniD,KAAKkJ,EAAK+0C,aAIvBgF,EAAsBjjD,KAAK+hD,EAAiBtnB,GAAOpiB,KAAK,WACpD4qC,EAAsBnf,MACe,IAAjCmf,EAAsB1gD,QACtB2gD,EAA0B/1C,gBAQ9Cg1C,EAAez2C,EAAayU,MAGK,IAAjC8iC,EAAsB1gD,QACtB2gD,EAA0B/1C,WAI3B+1C,EAGX,QAASI,GAAcC,GACnB,GAAIC,GAAW,GAAItlD,IAAGulD,gBAClBC,sBAlKoB,eAmKpB9iD,QAAS2iD,EACTI,QAAS,SAAS1zC,GACd/R,GAAGqlD,GAAUx+C,SAAS7H,EAAQytB,QAAQi5B,YACtC3zC,EAAE4zC,mBAENC,sBAAuB,SAAS7zC,GAC5B/R,GAAGqlD,GAAUv+C,YAAY9H,EAAQytB,QAAQi5B,aAE7CG,OAAQ,SAAS9zC,GACb+yC,EAAmB/yC,EAAEvE,aAAc83C,GAAU5rC,KACzC,WACI4pC,EAAmBW,EAAcqB,IAErC,WACItmD,EAAQ2B,UAAU8iD,QAAQ,sEAAuE,aAcjH,OARA/nC,GAAetG,YAAY,WACvBkwC,EAASrwC,YAGbjV,GAAGqlD,GAAUp9C,aA1LY,qBA0L4BjI,GAAGqlD,GAAUvgD,OAElEghD,EAAgBhkD,KAAKwjD,GAEdA,EAGX,QAASS,GAAWC,GAChB,GAAIC,EASJ,OAPAjmD,IAAGY,KAAKolD,EAAUx4C,aAAa04C,MAAO,SAAS/lD,EAAKC,GAChD,GAAY,UAARA,EAEA,MADA6lD,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBp0C,GACxB,MAAI/R,IAAG8Q,SACIiB,EAAEksC,EAAI,GAAKlsC,EAAEq0C,EAAI,EAGb,IAARr0C,EAAEksC,GAAmB,IAARlsC,EAAEq0C,EAG1B,QAASC,KACL,GAAIC,GAAYtnD,EAAQuF,iBAEpBgiD,EAAqB,WACjBv6B,WAAW,WACPhsB,GAAGY,KAAK0lD,EAAW,SAAS1kD,EAAK0jD,GAC7BtlD,GAAGslD,GAAUr9C,aApOJ,qBAoO4CjI,GAAGslD,GAAUxgD,OAClE9E,GAAGslD,GAAUx+C,YAAY9H,EAAQytB,QAAQi5B,eAE9C,IAGX1lD,IAAGY,KAAK0lD,EAAW,SAAS1kD,EAAK0jD,GAC7B,GAAI/B,GAAiB6B,EAAcE,EAG/BgB,GAAUjiD,QAAUrE,GAAG2V,kBAAkB4C,UACzCmD,EAAezW,OAAO8H,SAAU,YAAa,SAASgF,IAC7CwxC,EAAeG,gBAAkBqC,EAAWh0C,IAC7C/R,GAAGY,KAAK0lD,EAAW,SAAS1kD,EAAK0jD,GAGzBA,YAAoBkB,cACpBxmD,GAAGslD,GAAUr9C,aArPZ,qBAuPDjI,GAAGslD,GAAUv/C,KAAKf,QAAS,gBAQnD0W,EAAezW,OAAO8H,SAAU,YAAa,SAASgF,GAC9Co0C,EAAmBp0C,IACnBw0C,MAOR7qC,EAAezW,OAAOjF,GAAG+M,UAAUvF,WAAW,GAAI,aAAc,SAASuK,GACrEw0C,MAGJ7qC,EAAezW,OAAO8H,SAAU,OAAQ,SAASgF,GACzCg0C,EAAWh0C,KACXA,EAAED,iBACFy0C,OAIR7qC,EAAezW,OAAO8H,SApRE,eAoR+Bw5C,GArR3D,GAAIvnD,GAGA8mD,KACA7B,KACAvoC,EAAiB,GAAI1b,IAAG+U,cAE5B/V,IACIuF,oBACA2gD,oBAAoB,EACpBz4B,SACIi5B,WAAY,MAEhB/kD,UAAW,GAAIX,IAAGyE,YAAY9D,WAGlCX,GAAGsG,OAAOtH,EAASyb,GAAG,GAwQtB4rC,IAEArmD,GAAGsG,OAAOrE,MACNwkD,mBAAoB,SAAS/jD,GACzB1D,EAAQuF,iBAAiBzC,KAAKY,GAC9B0iD,EAAc1iD,IAGlBgkD,eAAgB,SAAShkD,GACrB,GAAI6Q,GACAozC,EAAM3nD,EAAQuF,gBAElB,KAAKgP,IAAKozC,GACN,GAAIA,EAAIpzC,KAAO7Q,EACX,MAAOikD,GAAI7nC,OAAOvL,EAAG,IAKjC0B,QAAS,WACLyG,EAAezG,UACfjV,GAAGY,KAAKklD,EAAiB,SAASlkD,EAAK0jD,GACnCA,EAASrwC,eAKrBhT,KAAK0yC,YACL1yC,KAAK0yC,SAASqP,qBAAuBA,GAGzChkD,GAAGyE,YAAY9D,UAAY,WACvB,YAEA,QACIskD,uBAAwB,aACxBtB,+BAAgC,SAAS1hC,EAAO2kC,KAChDzB,UAAW,SAAShyB,EAAM0zB,GACtB7mD,GAAGoC,IAAI,2BAA6B+wB,EAAO,2BAA6B0zB,EAAiB,IAAK,UAElGpD,QAAS,SAASphD,EAAS6H,GACvBlK,GAAGoC,IAAIC,EAAS6H,MAK5BlK,GAAGulD,eAAiB,SAAS9qC,GACzB,YAiBA,SAASqsC,KACL,MAAO9mD,IAAG8Q,UAAa9Q,GAAGkR,WAAalR,GAAGmR,UAG9C,QAAS41C,GAAmBh1C,GAEnBi1C,IAGGF,EACAprC,EAAezW,OAAO8H,SAAU,WAAY,SAASgF,GACjDA,EAAED,mBAGN4J,EAAezW,OAAO8H,SAAU,WAAY,SAASgF,GAC7CA,EAAEvE,eACFuE,EAAEvE,aAAay5C,WAAa,OAC5Bl1C,EAAED,oBAKdk1C,GAAsB,GAI9B,QAASE,GAAgBn1C,GAGrB,IAAK/R,GAAG2V,kBAAkB4C,SACtB,OAAO,CAGX,IAAI4uC,GAAYC,EAAKr1C,EAAEvE,aAEvB65C,EAAWrnD,GAAG8Q,QAOd,OADAq2C,MAAannD,GAAGsQ,OAAQtQ,GAAG2V,kBAAkB4C,WAAuC,SAArB6uC,EAAGE,cAC3DF,GAAMD,IAEAC,EAAGnlC,OAASmlC,EAAGnlC,MAAM5d,SACpBgjD,GAAYD,EAAGlB,MAAM3gD,UAAY6hD,EAAGlB,MAAM3gD,SAAS,UACpD6hD,EAAGlB,MAAMqB,UAAYH,EAAGlB,MAAMqB,SAAS,UAIxD,QAASC,GAAoBC,GAIzB,MAHmBnnD,UAAfmnD,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiB96C,SAAS+6C,YAAY,SACtCD,EAAeE,UAAU/oD,EAAQwmD,uBAAuB,GAAM,GAJlE,GAAIqC,EAOJ,IAAI3+C,OAAO8+C,YACP,IACIH,EAAiB,GAAIG,aAAYhpD,EAAQwmD,uBAE7C,MAAOzM,GACH6O,QAIJA,IAGJ76C,UAASk7C,cAAcJ,GAG3B,QAASK,KACLxsC,EAAezW,OAAOvC,EAAS,WAAY,SAASqP,GAChD,GAAKm1C,EAAgBn1C,GAArB,CAMA,GAAIo2C,GAASnoD,GAAGsQ,MAAQtQ,GAAG2V,kBAAkB4C,SAAW,KAAOxG,EAAEvE,aAAa85C,aAE1Ev1C,GAAEvE,aAAay5C,WADJ,SAAXkB,GAAgC,aAAXA,EACO,OAEA,OAGhCp2C,EAAE4zC,kBACF5zC,EAAED,oBAGN4J,EAAezW,OAAOvC,EAAS,YAAa,SAASqP,GACjD,IAAKy1C,IAAuB,CACxB,IAAKN,EAAgBn1C,GACjB,MAEJ/S,GAAQymD,QAAQ1zC,MAIxB2J,EAAezW,OAAOvC,EAAS,YAAa,SAASqP,GACjD,GAAKm1C,EAAgBn1C,GAArB,CAIA/S,EAAQu4B,QAAQxlB,EAEhB,IAAIq2C,GAAgBr7C,SAASs7C,iBAAiBt2C,EAAEu2C,QAASv2C,EAAEw2C,QAEvDvoD,IAAGiC,MAAMsD,SAAS6iD,IAItBppD,EAAQ4mD,sBAAsB7zC,MAGlC2J,EAAezW,OAAOvC,EAAS,OAAQ,SAASqP,GAC5C,IAAKy1C,IAAuB,CACxB,IAAKN,EAAgBn1C,GACjB,MAGJA,GAAED,iBACFC,EAAE4zC,kBACF3mD,EAAQ6mD,OAAO9zC,GAEf41C,OArJZ,GACI3oD,GAAS0D,EAASglD,EAAaV,EAD/BtrC,EAAiB,GAAI1b,IAAG+U,cAG5B/V,IACI0D,QAAS,KACT+iD,QAAS,SAAS1zC,KAClBwlB,QAAS,SAASxlB,KAElB6zC,sBAAuB,SAAS7zC,KAChC8zC,OAAQ,SAAS9zC,MAGrB/R,GAAGsG,OAAOtH,EAASyb,GACnB/X,EAAU1D,EAAQ0D,QA6IlBqkD,IACAmB,IAEAloD,GAAGsG,OAAOrE,MACNyhD,aAAc,SAAS+D,GACnB,MAAOD,GAAoBC,IAG/BxyC,QAAS,WACLyG,EAAezG,WAGnB2uC,WAAY,WACR,MAAOlhD,MAIfT,KAAK0yC,YACL1yC,KAAK0yC,SAASuS,gBAAkBA,GCrfnC,WACG,YAEAlnD,IAAGwoD,aACC3nC,gBAAiB,SAASC,GACtB7e,KAAKwmD,QAAQjnD,UAAUqf,gBAAgB7e,MAAMC,KAAMP,WACnDO,KAAKymD,YAAYC,iBAGrB9lC,iBAAkB,WACd5gB,KAAKwmD,QAAQjnD,UAAUqhB,iBAAiB7gB,MAAMC,KAAMP,WACpDO,KAAKymD,YAAYE,cAGrBC,iBAAkB,SAASnmD,GACvBT,KAAK6mD,MAAQ7mD,KAAK6mD,KAAKrC,mBAAmB/jD,IAG9CqmD,oBAAqB,SAASrmD,GAC1B,GAAIT,KAAK6mD,KACL,MAAO7mD,MAAK6mD,KAAKpC,eAAehkD,IAIxCsmD,gBAAiB,SAASnsC,GACtB,IAAK5a,KAAKymD,YAAYO,gBAAgBpsC,GAClC,MAAO5a,MAAKymD,YAAYQ,iBAAiBrsC,IAIjDN,MAAO,WACHta,KAAKwmD,QAAQjnD,UAAU+a,MAAMva,MAAMC,KAAMP,WACzCO,KAAKymD,YAAYnsC,SAEZta,KAAKpB,SAASslB,QAAUlkB,KAAKymD,YAAYpkC,cAC1CriB,KAAKquB,iBAAmBruB,KAAKgqB,qBACzBvpB,QAAST,KAAKymD,YAAYpkC,YAC1BzJ,MAAO5Y,KAAKpB,SAASgH,KAAKklB,iBAC3B7Q,eAGHja,KAAK6mD,OACL7mD,KAAK6mD,KAAK7zC,UACVhT,KAAK6mD,KAAO7mD,KAAKknD,qBAGrBlnD,KAAKmnD,mBAAqB,EAC1BnnD,KAAKonD,uBAAyB,EAE9BpnD,KAAKqnD,mCAGTnhC,QAAS,SAAStL,EAAIsC,GAClB,GAAIoqC,GAAoBtnD,KAAKpB,SAAS+yB,eAAezU,EAErDld,MAAKwmD,QAAQjnD,UAAU2mB,QAAQnmB,MAAMC,KAAMP,WAC3CO,KAAKymD,YAAYc,eAAe3sC,EAAI0sC,IAGxC1jC,YAAa,SAAShJ,GAClB,GAAImuB,GAAS/oC,KAAKwmD,QAAQjnD,UAAUqkB,YAAY7jB,MAAMC,KAAMP,UAG5D,OADAspC,IAAU/oC,KAAKymD,YAAYe,aAAa5sC,GACjCmuB,GAGXloB,eAAgB,SAASjG,GACrB,GAAI6sC,GAAYznD,KAAKwmD,QAAQjnD,UAAUshB,eAAe9gB,MAAMC,KAAMP,UAGlE,OADAgoD,IAAaznD,KAAKymD,YAAYiB,gBAAgB9sC,GACvC6sC,GAGXE,MAAO,SAASC,GACZ,MAAO5nD,MAAKymD,YAAYoB,UAAUD,IAGtCE,cAAe,SAASxmC,GAGpB,MAFWthB,MAAKgiB,QAAQV,GAEZymC,eAOpBhqD,GAAGiqD,cACC1lC,WAAY,SAAS3J,GACjB,GAAIuL,GAASlkB,KAAKwmD,QAAQjnD,UAAU+iB,WAAWviB,MAAMC,KAAMP,UAQ3D,OANKykB,IACGvL,IAAa3Y,KAAKquB,mBAClBnK,EAASlkB,KAAKymD,YAAYpkC,aAI3B6B,GAGX+jC,gBAAiB,SAAS3mC,GACtBthB,KAAKymD,YAAYyB,WAAW5mC,IAGhC+lC,gCAAiC,WAC7BrnD,KAAKmoD,yBAA2BpqD,GAAGqqD,yBAA2BpoD,KAAKqoD,6BAInEroD,KAAKsoD,wBAA0BvqD,GAAGkR,UAE9BjP,KAAKuoD,2BAELvoD,KAAKwoD,sBAAwBxoD,KAAKyoD,0BAClCzoD,KAAK0oD,6BAA+B1oD,KAAK2oD,iCACzC3oD,KAAK4oD,2BAA6B5oD,KAAK6oD,iCAI/C3B,kBAAmB,WACf,GAAInlD,GAAO/B,KACPsC,EAAmBtC,KAAKpB,SAASkqD,YAAYC,eAC7CC,EAAahpD,KAAKymD,YAClBwC,EAAkBD,EAAWE,aAIjC,OAFAD,IAAmB3mD,EAAiBzC,KAAKopD,GAElC,GAAIlrD,IAAGyE,aACVF,iBAAkBA,EAClB2gD,mBAAoBjjD,KAAKpB,SAASoM,SAClCwf,SACIi5B,WAAYzjD,KAAKpB,SAAS4rB,QAAQi5B,YAEtC/kD,WACIskD,uBAAwB,WACpBgG,EAAWG,sBAEfzH,+BAAgC,SAAS1hC,EAAO2kC,GAC5CqE,EAAWI,qBAEXrrD,GAAGY,KAAKqhB,EAAO,SAASrgB,EAAKqc,GACzBA,EAAK+rC,aAAepD,IAGpB3kC,EAAM5d,QACNL,EAAK4c,SAASqB,EAAO,KAAM,OAGnCkjC,UAAW,SAAShyB,EAAMm4B,GACtBtnD,EAAKykB,WAAW0K,EAAMm4B,IAE1B7H,QAAS,SAASphD,EAAS6H,GACvBlG,EAAK5B,IAAIC,EAAS6H,QAMlCogD,2BAA4B,WACxB,GAAItmD,GAAO/B,IAEX,OAAO,IAAIjC,IAAGqqD,yBACVY,WAAYhpD,KAAKymD,YAEjBtmD,IAAK,SAASC,EAASkpD,GACnBvnD,EAAK5B,IAAIC,EAASkpD,IAGtBC,aAAc,SAASjoC,GACnBvf,EAAKif,WAAWM,IAGpBsK,SAAU,SAAStK,GACfvf,EAAKqe,OAAOkB,IAGhBkoC,QAAS,SAASloC,GACdvf,EAAK6iB,MAAMtD,IAGfmoC,QAAS,SAASnoC,GACdvf,EAAK6hB,YAAYtC,IAGrBooC,WAAY,SAASpoC,GACjBvf,EAAK8e,eAAeS,IAGxBqoC,UAAW,SAASroC,GAChB,MAAOvf,GAAKwe,QAAQe,OAKhCinC,uBAAwB,WAEpB,MAAOvoD,MAAKymD,YAAYmD,2BAChB5pD,KAAKpB,SAAS4xB,YACfzyB,GAAG8rD,sBACH9rD,GAAG+rD,2BACH/rD,GAAG+rD,2BAGdC,qBAAsB,WAClB,GAAIhoD,GAAO/B,KACPgpD,EAAahpD,KAAKymD,WAEtB,QACIuC,WAAYA,EACZ7oD,IAAK,SAASC,EAASkpD,GACnBvnD,EAAK5B,IAAIC,EAASkpD,IAEtBU,kBAAmB,SAAS1oC,GACxB,MAAOvf,GAAKghB,YAAYnI,GAAI0G,IAASpG,QAEzCyuC,UAAW,SAASroC,GAChB,MAAOvf,GAAKwe,QAAQe,IAExB2oC,UAAW,SAASrvC,EAAIsC,GACpBnb,EAAKmkB,QAAQtL,EAAIsC,IAErBgtC,sBAAuB,SAAStvC,EAAIuvC,GAChC,GAAIC,GAAUrsD,GAAGirD,EAAWqB,aAAazvC,IACrC0vC,EAAkBvsD,GAAGirD,EAAW/B,iBAAiBrsC,GAEjDuvC,IACAC,EAAQxlD,SAAS,cACjBokD,EAAWuB,aAAa3vC,GACxBouC,EAAWwB,aAAa5vC,KAGxBwvC,EAAQvlD,YAAY,cACpBmkD,EAAWyB,aAAa7vC,GACxBouC,EAAW0B,aAAa9vC,IAI5B0vC,EAAgB1lD,SAAS,WAAWC,YAAY,cAK5DglB,sBAAuB,SAASjP,EAAI+B,EAAWD,GAC3C1c,KAAKwmD,QAAQjnD,UAAUsqB,sBAAsB9pB,MAAMC,KAAMP,WAErDO,KAAKuoD,0BAEDvoD,KAAKymD,YAAYQ,iBAAiBrsC,IAAO8B,IAAc3e,GAAGmd,OAAOwC,YACjE1d,KAAKymD,YAAYkE,qBAAqB/vC,GACtC5a,KAAKymD,YAAY+D,aAAa5vC,IAIlC+B,IAAc5e,GAAGmd,OAAO+C,iBAAmBvB,IAAc3e,GAAGmd,OAAO6C,WACnE/d,KAAKymD,YAAYmE,UAAUhwC,GAC3B5a,KAAKymD,YAAYoE,cAAcjwC,GAC/B7c,GAAGiC,KAAKymD,YAAYQ,iBAAiBrsC,IAAK/V,YAAY7E,KAAK8qD,SAASC,WAE/DruC,IAAc3e,GAAGmd,OAAOiD,eAC7Bne,KAAKymD,YAAYuE,UAAUpwC,IAInC+tC,+BAAgC,WAC5B,GAAI/sC,GAAO7d,GAAGsG,UAAWrE,KAAK+pD,uBAE9B,OAAO,IAAIhsD,IAAGktD,4BAA4BrvC,IAG9CitC,6BAA8B,WAC1B,GAAIjtC,GAAO7d,GAAGsG,UAAWrE,KAAK+pD,uBAE9B,OAAO,IAAIhsD,IAAG+rD,0BAA0BluC,IAG5C6sC,wBAAyB,WACrB,GAAI7sC,GAAO7d,GAAGsG,UAAWrE,KAAK+pD,uBAE9B,OAAO,IAAIhsD,IAAG8rD,qBAAqBjuC,IAGvCqY,eAAgB,SAASrZ,GACrB5a,KAAKwmD,QAAQjnD,UAAU00B,eAAel0B,MAAMC,KAAMP,WAClDO,KAAKymD,YAAYyE,YAAYtwC,IAGjCqX,eAAgB,SAASe,EAAYC,GACjCjzB,KAAKwmD,QAAQjnD,UAAU0yB,eAAelyB,MAAMC,KAAMP,WAClDO,KAAKymD,YAAY0E,sBAGrBt3B,UAAW,SAASjZ,EAAI7b,GACpB,GAAIid,GAAOhc,KAAKgiB,QAAQpH,EAEpBoB,IAAQA,EAAK8lC,QAAU9hD,KAAKpB,SAASkqD,YAAYsC,sBACjDprD,KAAKmkB,aAAawF,YAAY/O,GAC1BywC,OAAQrvC,EAAK8lC,SAIrB9hD,KAAKwmD,QAAQjnD,UAAUs0B,UAAU9zB,MAAMC,KAAMP,WAC7CO,KAAKsrD,WAAW1wC,EAAI7b,IAIxBg1B,aAAc,SAASnZ,GAEf5a,KAAKuoD,2BACLvoD,KAAKymD,YAAYkE,qBAAqB/vC,GACtC5a,KAAKymD,YAAYiE,aAAa9vC,GAGzB5a,KAAKsoD,wBACNtoD,KAAK4oD,2BAA2B2C,WAAWvrD,KAAKymD,YAAY4D,aAAazvC,MAMrF4Q,YAAa,SAAS5Q,EAAI7b,EAAMusB,EAAQC,GACpCvrB,KAAKwmD,QAAQjnD,UAAUisB,YAAYzrB,MAAMC,KAAMP,WAE/CO,KAAKymD,YAAY+E,eAAe5wC,EAAI0Q,EAAQC,GAE9B,IAAVA,GAAoD,MAArCpnB,KAAKC,MAAMknB,EAASC,EAAQ,MAC3CvrB,KAAKymD,YAAYgF,WAAW7wC,GAC5B5a,KAAKymD,YAAYuE,UAAUpwC,GAC3B5a,KAAKymD,YAAYiF,aAAa9wC,GAC9B5a,KAAKymD,YAAYoE,cAAcjwC,EAAI5a,KAAKpB,SAASgH,KAAK+lD,oBAGtD3rD,KAAK4rD,iBAAiBhxC,IAItB5a,KAAK4rD,iBAAiBhxC,EAAI0Q,EAAQC,IAI1CiJ,iBAAkB,SAASlJ,EAAQC,GAC/BvrB,KAAKwmD,QAAQjnD,UAAUi1B,iBAAiBz0B,MAAMC,KAAMP,WACpDO,KAAKymD,YAAYrJ,oBAAoB9xB,EAAQC,IAGjDI,YAAa,SAAS/Q,EAAI7b,EAAMmG,EAAQwmB,GAMpC,QAASmgC,GAAe3mD,GAGfgb,IAIL8oC,EAAW6B,cAAcjwC,GAEzB7c,GAAGmiB,GAAerb,YAAY9C,EAAK+oD,SAASC,UAC5C/B,EAAW0C,aAAa9wC,GAEpB7Y,EAAKghB,YAAYnI,GAAIA,IAAKM,SAAWnd,GAAGmd,OAAOiD,eAC/C6qC,EAAWyC,WAAW7wC,GAE1BouC,EAAWkC,YAAYtwC,GAEnB1V,EAAO8H,QACPjL,EAAK+pD,sBAAsBlxC,IAG3B7c,GAAGmiB,GAAetb,SAAS7C,EAAK+oD,SAASiB,MACzC/C,EAAWgD,WAAWpxC,GAElBouC,EAAWiD,oBAAsBlqD,EAAKiiB,gBAAgBpJ,KACtD7c,GAAGmiB,GAAetb,SAAS7C,EAAK+oD,SAAS7N,WACzC+L,EAAWkD,UAAUtxC,IAEzB7Y,EAAKoqD,2BAA2BvxC,EAAI1V,KAjC5C,GAAIknD,GAAepsD,KAAKwmD,QAAQjnD,UAAUosB,YAAY5rB,MAAMC,KAAMP,WAC9DupD,EAAahpD,KAAKymD,YAClBvmC,EAAgB8oC,EAAW/B,iBAAiBrsC,GAC5C7Y,EAAO/B,IA6CX,OAVIosD,aAAwBruD,IAAG+O,QAC3Bs/C,EAAal0C,KAAK,SAASm0C,GACvBR,EAAeQ,KAKnBR,EAAe3mD,GAGZknD,GAGXN,sBAAuB,SAASlxC,GAC5B,GAAIouC,GAAahpD,KAAKymD,WAElBzmD,MAAK2wB,qBACLq4B,EAAWsD,iBAAiB1xC,GAGhC7c,GAAGirD,EAAW/B,iBAAiBrsC,IAAKhW,SAAS5E,KAAK8qD,SAAS99C,SAE3DhN,KAAKusD,sBAAsB3xC,IAG/BoR,cAAe,SAASpR,GACpB5a,KAAKwmD,QAAQjnD,UAAUysB,cAAcjsB,MAAMC,KAAMP,WACjDO,KAAKymD,YAAY+F,YAAY5xC,IAGjCsR,UAAW,SAAStR,EAAI7b,GACpB,GAAIqtD,GAAepsD,KAAKwmD,QAAQjnD,UAAU2sB,UAAUnsB,MAAMC,KAAMP,UAIhE,OAFAO,MAAKymD,YAAY+F,YAAY5xC,GAEtBwxC,GAGX9/B,eAAgB,SAAS1R,EAAIyR,GACzBrsB,KAAKwmD,QAAQjnD,UAAU+sB,eAAevsB,MAAMC,KAAMP,WAI9C4sB,EAAUG,UAAY,GAAKxsB,KAAKwgB,SAASiD,YAAY7I,IACrD5a,KAAKymD,YAAYgG,WAAW7xC,IAIpCkR,UAAW,SAASlR,EAAI7b,GACpBiB,KAAKwmD,QAAQjnD,UAAUusB,UAAU/rB,MAAMC,KAAMP,WAC7CO,KAAKioD,gBAAgBrtC,GAEU,IAA3B5a,KAAK0uB,mBACL1uB,KAAKymD,YAAY0E,sBAIzB73B,mBAAoB,SAAS1Y,GACzB,GAAI8xC,GAAoBC,EAASC,CAEjC5sD,MAAKwmD,QAAQjnD,UAAU+zB,mBAAmBvzB,MAAMC,KAAMP,WAEtDO,KAAK6sD,gBAAgBjyC,GAEjB5a,KAAKpB,SAASgmB,MAAMkoC,oBACpBJ,EAAqB1sD,KAAK8jB,aAAalJ,GACvC+xC,EAAU3sD,KAAKpB,SAASgmB,MAAMkR,gBAE9B82B,EAAY5sD,KAAKpB,SAASgmB,MAAMmoC,cAAcjoD,QAAQ,gBAAiB4nD,GACvEE,EAAYA,EAAU9nD,QAAQ,eAAgB6nD,GAE9C3sD,KAAKymD,YAAYoE,cAAcjwC,EAAIgyC,GACnC7uD,GAAGiC,KAAKymD,YAAYQ,iBAAiBrsC,IAAKhW,SAAS5E,KAAK8qD,SAASC,YAKzEh5B,qBAAsB,SAASnX,GAC3B,MAAI5a,MAAKwmD,QAAQjnD,UAAUwyB,qBAAqBhyB,MAAMC,KAAMP,YACxDO,KAAKymD,YAAYuG,cAAcpyC,GAC/B7c,GAAGiC,KAAKymD,YAAYQ,iBAAiBrsC,IAAK/V,YAAY7E,KAAK8qD,SAASiB,MACpE/rD,KAAKymD,YAAYoE,cAAcjwC,GAC/B5a,KAAKymD,YAAY+F,YAAY5xC,GAC7B5a,KAAK6sD,gBAAgBjyC,IACd,IAGP7c,GAAGiC,KAAKymD,YAAYQ,iBAAiBrsC,IAAKhW,SAAS5E,KAAK8qD,SAAS7N,WACjEj9C,KAAKymD,YAAYyF,UAAUtxC,IACpB,IAIfqG,gBAAiB,SAASrG,GACtB,GAAIsZ,GAAoBn2B,GAAG0S,KAAKzQ,KAAKitD,uBAAwBjtD,KAE7DA,MAAKwmD,QAAQjnD,UAAU0hB,gBAAgBzhB,KAAKQ,KAAM4a,EAAIsZ,IAG1D+4B,uBAAwB,SAASryC,EAAIG,EAAMoZ,GACnCn0B,KAAKpB,SAASoiB,WAAWksC,aACzBltD,KAAKmtD,mBAAmBptD,MAAMC,KAAMP,WAGpCO,KAAKotD,mBAAmBrtD,MAAMC,KAAMP,YAI5C4mB,kBAAmB,SAASzL,EAAI8Q,EAAKtD,GACjCpoB,KAAKwmD,QAAQjnD,UAAU8mB,kBAAkBtmB,MAAMC,KAAMP,WAErDO,KAAKymD,YAAYyE,YAAYtwC,GAEzBwN,GACApoB,KAAKymD,YAAYoE,cAAcjwC,EAAI5a,KAAKpB,SAASoiB,WAAWqsC,oBAC5DrtD,KAAKymD,YAAY6F,iBAAiB1xC,IAGlC5a,KAAKioD,gBAAgBrtC,IAI7BwyC,mBAAoB,SAASxyC,EAAIG,EAAMoZ,GACnCn0B,KAAKymD,YAAY6G,iBAAiB1yC,GAClC5a,KAAKymD,YAAY+F,YAAY5xC,GAC7B5a,KAAKymD,YAAYoE,cAAcjwC,EAAI5a,KAAKpB,SAASoiB,WAAWusC,oBAC5DvtD,KAAKs0B,eAAeC,WAAWx0B,MAAMC,KAAMP,YAG/C0tD,mBAAoB,SAASvyC,EAAIG,EAAM6gB,GAEnC,GAKIt6B,GALAuR,EAAW7S,KAAKugB,QAAQ3F,GACxB4yC,EAAiBxtD,KAAKpB,SAASoiB,WAAWwsC,eAAe1oD,QAAQ,gBAAiB+N,GAElF46C,GADOztD,KAAKwjB,QAAQ5I,GACAnb,WACpBsC,EAAO/B,IAGXsB,GAAStB,KAAKpB,SAAS8uD,YAAYF,GAE/BzvD,GAAGwZ,iBAAiBjW,GACpBA,EAAOmW,KAAK,WACR1V,EAAKqrD,mBAAmBrtD,MAAMgC,EAAM0rD,KAGnCnsD,KAAW,GAChBS,EAAKqrD,mBAAmBrtD,MAAMgC,EAAM0rD,IAI5CnC,WAAY,SAAS1wC,EAAI7b,EAAM4uD,GAC3B,GAAIC,GAGApxC,EAFAqxC,EAAe,EACfC,EAAc9tD,KAAKwgB,SAAS4kB,UAAUxqB,IAAO5a,KAAKpB,SAASmY,QAAQg3C,UAGnE/tD,MAAKpB,SAASmE,QAAQirD,eAClBhuD,KAAKmnD,mBAAqB,GAAKnnD,KAAKonD,uBAAyB,IAC7DyG,EAAe7tD,KAAKonD,uBAAyB,GAGjDwG,GACI1rD,MAAO2rD,IAIVF,IACG3tD,KAAKpB,SAASo4B,8BAAgCj5B,GAAG2V,kBAAkBmC,eACnE7V,KAAKymD,YAAYwH,gBAMhBjuD,KAAKpB,SAASoM,WACfwR,EAASxc,KAAK+iB,YAAYnI,GAAIA,IAE9B5a,KAAKkuD,mBAAqBluD,KAAKkuD,oBAAsB1xC,EAAON,aAExDM,EAAON,eAAiBlc,KAAKkuD,oBAAuB1xC,EAAON,eAC3Dlc,KAAKwgB,SAASC,YACdzgB,KAAKmuD,aACLnuD,KAAKkuD,mBAAqB,QAKlCP,GACA3tD,KAAKymD,YAAY2H,eAAexzC,EAAI5a,KAAKpB,SAAS+yB,eAAe5yB,GAAO6uD,EAAaE,GACrF9tD,KAAKymD,YAAY4H,gBAAgBzzC,EAAI5a,KAAK8hB,eAAelH,IAAK,EAAM5a,KAAKpB,SAAS0vD,WAAW50B,iBAG7F15B,KAAKymD,YAAY9qC,QAAQf,EAAI5a,KAAKpB,SAAS+yB,eAAe5yB,GAAO6uD,EAAaE,GAC9E9tD,KAAKymD,YAAY8H,gBAAgB3zC,EAAI5a,KAAKgiB,QAAQpH,GAAK5a,KAAKpB,SAAS0vD,WAAW50B,gBAGpF15B,KAAKonD,wBAA0B,GAE3BuG,GACC3tD,KAAKpB,SAASmE,QAAQyrD,kBAAoBzwD,GAAG2V,kBAAkBmC,gBAEhE7V,KAAK4rD,iBAAiBhxC,IAI9BuzC,WAAY,WACRnuD,KAAKymD,YAAYE,aACjB3mD,KAAK4gB,oBAGTgrC,iBAAkB,SAAShxC,EAAI6zC,EAAY7R,GACvC,GAAI7gC,GAAO/b,KAAKijB,QAAQrI,GACpB8zC,EAAiB1uD,KAAK0tB,YAAY3R,EAElCA,IAAQ,IACW1d,SAAfowD,GAA0CpwD,SAAdu+C,IAC5B8R,EAAiB1uD,KAAK2uD,gBAAgBF,EAAY7R,IAGtD58C,KAAKymD,YAAYtpC,WAAWvC,EAAI8zC,KAIxCC,gBAAiB,SAASC,EAAchS,GAEpC,QAASzuC,GAAEpP,EAAMqyB,GAAehxB,EAAUA,EAAQ0E,QAAQ/F,EAAMqyB,GADhE,GAAIhxB,GAAUJ,KAAKpB,SAASgH,KAAKipD,cAKjC,OAFA1gD,GAAE,YAAahK,KAAKC,MAAMwqD,EAAehS,EAAY,MACrDzuC,EAAE,eAAgBnO,KAAK0tB,YAAYkvB,IAC5Bx8C,GAGX+rD,2BAA4B,SAASvxC,EAAI0X,GACrC,GAAIw8B,GAAMC,EAAkBC,CAE5BF,GAAO9uD,KAAKpB,SAASqwD,wBAAwBH,KAC7CC,EAAmB/uD,KAAKpB,SAASqwD,wBAAwBF,iBAE5C,WAATD,GACAE,EAAgB18B,EAASy8B,GACpBC,IACDA,EAAgBhvD,KAAKpB,SAASgH,KAAKspD,YAGvClvD,KAAKymD,YAAYoE,cAAcjwC,EAAIo0C,GAE/BhvD,KAAKpB,SAASqwD,wBAAwBE,eACtCnvD,KAAKovD,aAAax0C,EAAIo0C,IAGZ,YAATF,EACL9uD,KAAKymD,YAAYoE,cAAcjwC,EAAI5a,KAAKpB,SAASgH,KAAKspD,YAExC,SAATJ,GACL9uD,KAAKG,IAAI,0CAA4C2uD,EAAO,iBAAkB,SAItFM,aAAc,SAASx0C,EAAIhV,GACvB5F,KAAKymD,YAAYQ,iBAAiBrsC,GAAIhC,MAAQhT,GAGlDinD,gBAAiB,SAASjyC,GACjB5a,KAAKpB,SAASo4B,8BAA+Bj5B,GAAG2V,kBAAkBmC,eACnE7V,KAAKymD,YAAYuF,WAAWpxC,IAIpC4L,WAAY,SAAS0K,EAAMnyB,EAAMgK,GAC7B,GAAI3I,GAAUJ,KAAKwmD,QAAQjnD,UAAUinB,WAAWzmB,MAAMC,KAAMP,UAC5DO,MAAKpB,SAASywD,YAAYjvD,IAG9B+mB,YAAa,SAAS/mB,GAClBJ,KAAKwmD,QAAQjnD,UAAU4nB,YAAYpnB,MAAMC,KAAMP,WAC/CO,KAAKpB,SAASywD,YAAYjvD,IAG9BkvD,kBAAmB,WACf,GAAIvtD,GAAO/B,IAEXA,MAAKpB,SAASF,UAAUiqB,gBAAkB,WACtC,GAAIvoB,GAAU2B,EAAKnD,SAAS4pB,MAAM+mC,kBAC9BC,EAAaztD,EAAKnD,SAAS4pB,MAAMlJ,WAErC,OAAOvd,GAAKnD,SAAS6wD,WAAWrvD,EAASovD,KAIjD/hC,oBAAqB,SAAS7S,EAAI7b,GAC9BiB,KAAKmnD,oBAAsB,EAC3BnnD,KAAKwmD,QAAQjnD,UAAUkuB,oBAAoB1tB,MAAMC,KAAMP,YAG3D0gB,uBAAwB,SAAS3U,EAAOjO,EAAQmhB,GAC5C1e,KAAKmnD,mBAAqB37C,EAAMpJ;iCAChCpC,KAAKonD,uBAAyB,EAC9BpnD,KAAKwmD,QAAQjnD,UAAU4gB,uBAAuBpgB,MAAMC,KAAMP,YAG9D8sD,sBAAuB,SAASjrC,GAC5B,GAAIwF,GAAe9mB,KAAK8hB,eAAeR,EACtBthB,MAAK+iB,YAAYnI,GAAI0G,IAASpG,SAE5Bnd,GAAGmd,OAAOoD,UACxBwI,IACD9mB,KAAKpB,SAAS0vD,WAAWoB,aAAaC,mBACrC5xD,GAAG2V,kBAAkB+C,eAItBzW,KAAKymD,YAAY4H,gBAAgB/sC,EAAQwF,EAAc9mB,KAAKpB,SAAS0vD,WAAW50B,gBAIxF3a,eAAgB,SAAS4H,GACrB,GAAI/L,GAAK5a,KAAKwmD,QAAQjnD,UAAUwf,eAAehf,MAAMC,KAAMP,UAO3D,OALAO,MAAKsrD,WAAW1wC,EAAI5a,KAAKugB,QAAQ3F,IAAK,GACtC5a,KAAKymD,YAAYyE,YAAYtwC,GAC7B5a,KAAKymD,YAAYgF,WAAW7wC,GAC5B5a,KAAK8rD,sBAAsBlxC,GAEpBA,GAGXsS,SAAU,SAAStS,EAAIwC,GACnBpd,KAAKwmD,QAAQjnD,UAAU2tB,SAASntB,MAAMC,KAAMP,WAE5CO,KAAKymD,YAAYtpC,WAAWvC,EAAI5a,KAAK0tB,YAAYtQ,KAGrDuY,wBAAyB,WACrB31B,KAAKymD,YAAYC,gBACjB1mD,KAAKwmD,QAAQjnD,UAAUo2B,wBAAwB51B,MAAMC,KAAMP,gBC7sBvE1B,GAAGC,aAAe,SAASwa,EAAG9a,GAC1B,YAEA,IAAIqE,GAAO/B,IAKXA,MAAKwmD,QAAU9oD,EAAYK,GAAGL,GAAWq5B,kBAAoBh5B,GAAGg5B,kBAChE/2B,KAAKwmD,QAAQzmD,MAAMC,KAAMP,WAGzB1B,GAAGsG,OAAOrE,KAAKpB,UACX6B,QAAS,KAETyjB,OAAQ,KAER0rC,YAAa,KAEb9G,aACIC,kBACAqC,sBAAsB,GAG1BxlD,MACIipD,eAAgB,6BAChBK,WAAY,gBACZvD,mBAAoB,gBACpB5iB,OAAQ,UAGZ8mB,SAAU,cAEVrlC,SACIugC,SAAU,qBACV9N,UAAW,sBACXjwC,QAAS,oBACT++C,KAAM,iBACN+D,SAAU,cACVjtD,KAAM,UACN4gD,WAAY,8BAGhBwL,yBACIH,KAAM,UACNC,iBAAkB,QAClBI,eAAe,GAGnB59B,UACIw+B,kBAAmB,6BACnBC,mBAAoB,kFAGxBprC,OACIkoC,mBAAmB,EACnBC,cAAe,oCAGnB/rC,YACIksC,cAAc,EACdM,eAAgB,8CAChBD,mBAAoB,cACpBF,mBAAoB,iBAIxBtqD,SACIyrD,kBAAkB,EAClBR,cAAc,GAGlBxlC,OACIynC,eAAe,EACfV,kBAAmB,0BAGvBjB,YACI50B,cAAe,KACfw2B,SAAU,EACVR,cACIC,mBAAmB,EACnBQ,iBAAkB,KAClBC,YAAa,MAEjBC,kBAAmB,KAGvBt5C,SACIg3C,YAAY,GAGhBsB,YAAa,SAASjvD,GAClB,GAAI2B,EAAK0kD,YAAY6J,UAAU,SAC3B,MAAOvuD,GAAK0kD,YAAY8J,WAAW,QAASnwD,EAG5C2pB,YAAW,WACP9iB,OAAOkrB,MAAM/xB,IACd,IAIXstD,YAAa,SAASttD,GAClB,MAAI2B,GAAK0kD,YAAY6J,UAAU,WACpBvuD,EAAK0kD,YAAY8J,WAAW,UAAWnwD,GAGvC6G,OAAOupD,QAAQpwD,IAI9BqvD,WAAY,SAASrvD,EAASqwD,GAC1B,MAAI1uD,GAAK0kD,YAAY6J,UAAU,UACpBvuD,EAAK0kD,YAAY8J,WAAW,SAAUnwD,EAASqwD,GAG/CxpD,OAAOypD,OAAOtwD,EAASqwD,MAGvC,GAGH1yD,GAAGsG,OAAOrE,KAAKpB,SAAU4Z,GAAG,GAE5BxY,KAAKymD,YAAc,GAAI1oD,IAAG4yD,YACtBxwD,IAAKpC,GAAG0S,KAAKzQ,KAAKG,IAAKH,MACvB4wD,eAAgB5wD,KAAKpB,SAASixD,SAC9BgB,YAAa7wD,KAAKpB,SAAS6B,QAC3BqwD,gBAAiB9wD,KAAKpB,SAASgxD,YAC/B1rC,OAAQlkB,KAAKpB,SAASslB,OACtB01B,eAAgB55C,KAAK6hB,gBACrB2I,SACI3nB,KAAM7C,KAAKpB,SAAS4rB,QAAQ3nB,KAC5BitD,SAAU9vD,KAAKpB,SAAS4rB,QAAQslC,UAEpCla,QACImb,UAAW/wD,KAAKpB,SAAS0vD,WAAW4B,SACpCG,kBAAmBrwD,KAAKpB,SAAS0vD,WAAW+B,mBAEhDX,cACIsB,gBAAiBhxD,KAAKpB,SAAS0vD,WAAWoB,aAAaC,kBACvDsB,sBAAuBjxD,KAAKpB,SAAS0vD,WAAWoB,aAAaS,iBAC7De,oBAAqBlxD,KAAKpB,SAAS0vD,WAAWoB,aAAaU,aAE/DxqD,KAAM5F,KAAKpB,SAASgH,OAGpB5F,KAAKpB,SAASsrB,YAAYgI,mBAAqBn0B,GAAG0R,UAAY1R,GAAG4R,YACjE3P,KAAKymD,YAAY0K,cAAcnxD,KAAKpB,SAAS2yB,SAASa,+BAEhDr0B,GAAG2V,kBAAkBwD,WAAclX,KAAKpB,SAASmpB,KAAK6I,WAAa7yB,GAAG2V,kBAAkByD,WAC9FnX,KAAKymD,YAAY0K,cAAcnxD,KAAKpB,SAAS2yB,SAASy+B,qBAGtDhwD,KAAKy2B,iBAELz2B,KAAKymD,YAAY/W,SAEjB1vC,KAAK8qD,SAAW9qD,KAAKpB,SAAS4rB,SAEzBxqB,KAAKpB,SAASslB,QAAUlkB,KAAKymD,YAAYpkC,cAC1CriB,KAAKquB,iBAAmBruB,KAAKgqB,qBACzBvpB,QAAST,KAAKymD,YAAYpkC,YAC1BzJ,MAAO5Y,KAAKpB,SAASgH,KAAKklB,iBAC3B7Q,eAGPja,KAAKqnD,kCAEDtpD,GAAGyE,aAAezE,GAAG2V,kBAAkB4C,WACvCtW,KAAK6mD,KAAO7mD,KAAKknD,qBAGjBlnD,KAAKpB,SAAS4pB,MAAMD,eAAiBvoB,KAAKpB,SAAS4pB,MAAMynC,gBACrDlyD,GAAGuqB,aACHtoB,KAAKsvD,oBAGLtvD,KAAKG,IAAI,kCAAmC,UAIpDH,KAAKmnD,mBAAqB,EAC1BnnD,KAAKonD,uBAAyB,IAKtCrpD,GAAGsG,OAAOtG,GAAGC,aAAauB,UAAWxB,GAAGwgB,eACxCxgB,GAAGsG,OAAOtG,GAAGC,aAAauB,UAAWxB,GAAG2oB,gBAGxC3oB,GAAGsG,OAAOtG,GAAGC,aAAauB,UAAWxB,GAAGwoD,aACxCxoD,GAAGsG,OAAOtG,GAAGC,aAAauB,UAAWxB,GAAGiqD,cC5LxCjqD,GAAG4yD,WAAa,SAAS/0C,GACrB,YAEA,IA4EIzb,GACAixD,EACAC,EACAC,EACArvC,EACA6N,EACAyhC,EACAC,EA1EAC,GACIC,QAAS5mD,SAAS6mD,yBAClBC,QAEJC,GAAmB,EACnBC,EAAsB,EACtBC,GAA+B,EAC/BC,KACAC,GAAmB,EACnBl1D,GACIoD,IAAK,KACLy1C,QACImb,UAAW,EACXV,kBAAmB,KAEvBO,eAAgB,cAChBC,YAAa,KACbC,gBAAiB,KACjB5sC,OAAQ,KACR01B,eAAgB,KAChBpvB,SACI3nB,KAAM,UACNitD,SAAU,eAEdJ,cACIsB,iBAAiB,EACjBC,sBAAuB,KACvBC,oBAAqB,MAEzBtrD,MACImjC,OAAQ,WAGhBmpB,GACIhuC,OAAQ,4BACRiuC,YAAa,2BACbC,mBAAoB,4BACpBC,cAAe,6BACfC,cAAe,6BACfC,eAAgB,wBAChBC,aAAc,4BACdp1D,SAAU,uBACVq1D,KAAM,+BACNC,KAAM,0BACNC,qBAAsB,qCACtB97C,YAAa,2BACb+7C,0BAA2B,2CAC3BC,iBAAkB,iCAClB72C,KAAM,0BACN82C,QAAS,6BACT/2C,KAAM,0BACNqE,OAAQ,4BACRxJ,MAAO,2BACPm8C,eAAgB,8BAChBC,aAAc,4BACdpuC,MAAO,2BACPquC,WAAY,iCACZC,kBAAmB,4BACnBC,aAAc,iCACdC,SAAU,oCACVC,eAAgB,8BAChBC,sBAAuB,sCACvBC,UAAW,yBAEfC,KACAC,EAAiC,GAAI11D,IAAG+O,QACxC4mD,EAA+B,GAAI31D,IAAG+O,QAatC6mD,EAA6B,WACzB,GAAIC,GAAmB72D,EAAQ2yD,aAAauB,sBACxC4C,EAAa92D,EAAQ2yD,aAAawB,oBAClCt1C,GACI4F,QAASywC,EACTlwC,MAAOyvC,EAGXD,KACIqC,EACA72D,EAAQ68C,eAAe13B,SAAS0xC,EAAiB,GAAIzkB,OAASvzB,GAAMnE,KAChE,SAASq8C,GACLL,EAA+BzmD,QAAQ8mD,IAE3C,WACIL,EAA+BvmD,UAC/B/M,EAAI,wDAA0DyzD,EAAiB,WAKvFH,EAA+BvmD,UAG/B2mD,EACA92D,EAAQ68C,eAAe13B,SAAS2xC,EAAY,GAAI1kB,OAASvzB,GAAMnE,KAC3D,SAASq8C,GACLJ,EAA6B1mD,QAAQ8mD,IAEzC,WACIJ,EAA6BxmD,UAC7B/M,EAAI,gEAAkE0zD,EAAY,WAK1FH,EAA6BxmD,YAOzC6mD,EAAoB,SAASR,GACzB,GAAIS,GAAsB,GAAIj2D,IAAG+O,OAwBjC,OAtBA4mD,GAA6Bj8C,KAAK,SAASi0B,GACvCuoB,EAA4BvoB,EAAK6nB,GAE5BA,EAAUhkB,IASXykB,EAAoBhnD,WARpBumD,EAAUhkB,IAAM7D,EAAI6D,IACpBgkB,EAAUxmD,OAAS,WACfwmD,EAAUxmD,OAAS,KACnBmnD,EAAKX,GACLS,EAAoBhnD,aAM7B,WAICnK,EAAK0wD,GACLS,EAAoBhnD,YAGjBgnD,GAGXG,EAAqB,SAASv5C,EAAIpO,EAAMoP,GACpC,GAAI23C,GAAYa,EAAax5C,EAK7B,OAHAza,GAAI,gCAAkCya,GACtCpO,EAAK6nD,cAAgBz5C,EAEd7d,EAAQ68C,eAAe13B,SAAS1V,EAAM+mD,EAAW33C,GAAMnE,KAC1D,WACIq6C,IACAoC,EAAKX,GACLC,EAAkB54C,GAAI5N,WAE1B,WACIwmD,EAAkB54C,GAAI1N,UAIjBnQ,EAAQ2yD,aAAasB,iBACtBsD,EAA+B15C,EAAI24C,MAKnDgB,EAA4B,WACxB,GAAIvC,EAAqB5vD,OAAQ,CAC7B2vD,GAA+B,CAE/B,IAAIyC,GAAqBxC,EAAqB9+C,OAE1CshD,GAAmBC,OACnBC,EAAkCF,GAGlCG,EAA+BH,OAInCzC,IAA+B,GAIvC6C,EAAY,SAASh6C,GACjB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgB9xC,SAGtD00C,EAAc,SAASl6C,GACnB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBa,iBAGtDgC,EAAY,SAAS5zD,GACjB,MAAO0zD,GAAc5yC,EAAWiwC,EAAgB/wD,EAAO,YAG3D6zD,EAAY,SAASp6C,GACjB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBc,eAGtDiC,EAAoB,WAChB,MAAOJ,GAAc5yC,EAAWiwC,EAAgBmB,iBAGpD6B,EAAc,SAASt6C,GACnB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBiB,eAGtDnxC,EAAU,SAASpH,GACf,MAAO62C,GAAUG,IAAIh3C,IAAO7c,GAAG+xB,GAAUxqB,gBAhOzB,cAgO6DsV,IAGjFjI,EAAc,SAASiI,GACnB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBl2C,OAGtDm5C,EAAW,SAASv6C,GAChB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBt7C,QAGtDw+C,EAAc,SAASx6C,GAGnB,MAAU,OAANA,EACOi6C,EAAc5yC,EAAWiwC,EAAgBU,4BAC5CiC,EAAc5yC,EAAWiwC,EAAgBW,kBAI1CgC,EAAc7yC,EAAQpH,GAAKs3C,EAAgBS,uBAC9CkC,EAAc7yC,EAAQpH,GAAKs3C,EAAgBr7C,cAGnDw+C,EAAW,SAASz6C,GAChB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBttC,QAGtD3B,EAAU,SAASrI,GACf,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBn2C,OAGtDu5C,EAAa,SAAS16C,GAClB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBY,UAGtD+B,EAAgB,SAASlkD,EAAS4kD,GAC9B,MAAO5kD,IAAW5S,GAAG4S,GAASrL,gBAAgBiwD,IAGlDnB,EAAe,SAASx5C,GACpB,MAAO22C,IAAkBsD,EAAc7yC,EAAQpH,GAAKs3C,EAAgBqB,YAGxE1wD,EAAO,SAASV,GACZA,GAAMpE,GAAGoE,GAAIyC,SAAS7H,EAAQytB,QAAQ3nB,OAM1CoxD,EAA8B,SAASniC,EAAayhC,GAChD,GAAI97B,GAAW3F,EAAYhvB,MAAM20B,SAC7BD,EAAY1F,EAAYhvB,MAAM00B,SAE9BA,IAAaC,IAAa87B,EAAUzwD,MAAM20B,WAAa87B,EAAUzwD,MAAM00B,WACvEz5B,GAAGw1D,GAAWzvD,KACV2zB,SAAUA,EACVD,UAAWA,KAQvB88B,EAAiC,SAAS15C,EAAI24C,GAC1C,GAAIiC,GAAahC,EAAkB54C,KAAO,GAAI7c,IAAG+O,SAAUI,UACvDuoD,EAA2B,GAAI13D,IAAG+O,OAqBtC,OAnBA2mD,GAA+Bh8C,KAAK,SAASi0B,GACzC8pB,EAAW/9C,KACP,WACIg+C,EAAyBzoD,WAE7B,WACIinD,EAA4BvoB,EAAK6nB,GAEjCA,EAAUxmD,OAAS,WACfwmD,EAAUxmD,OAAS,KACnB0oD,EAAyBzoD,WAG7BumD,EAAUhkB,IAAM7D,EAAI6D,IACpB2kB,EAAKX,OAKVkC,GAWXC,EAAsB,WAClB,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACA5S,EACAmQ,EACAF,EACA4C,EACAC,CAKJ,IAHA/1D,EAAI,oBAG0B,MAA1BpD,EAAQ6zD,eACR,KAAM,IAAI5sD,OAAM,oDAIpB,IAAIjG,GAAGkL,SAASlM,EAAQ6zD,gBAAiB,CAGrC,GAFA+E,EAAW7qD,SAASs7B,eAAerpC,EAAQ6zD,gBAE1B,OAAb+E,EACA,KAAM,IAAI3xD,OAAMjG,GAAGwL,OAAO,0CAA2CxM,EAAQ6zD,gBAGjFgF,GAAaD,EAASxlD,cAErB,CACD,GAAyC9R,SAArCtB,EAAQ6zD,eAAezgD,UACvB,KAAM,IAAInM,OAAM,gGAIpB4xD,GAAa74D,EAAQ6zD,eAAezgD,UA4ExC,GAzEAylD,EAAa73D,GAAGoL,QAAQysD,GACxBE,EAAiBhrD,SAASC,cAAc,OACxC+qD,EAAe9jD,YAAYjU,GAAGiS,UAAU4lD,IACxCM,EAAan4D,GAAG+3D,GAAgBxwD,gBAAgB4sD,EAAgB90D,UAI5DL,EAAQmnB,SACR8xC,EAAgBj4D,GAAG+3D,GAAgBxwD,gBAAgB4sD,EAAgBhuC,QAC/D8xC,GACAj4D,GAAGi4D,GAAepyD,UASrB7F,GAAGyE,aAAgBzE,GAAG2V,kBAAkB4C,WACzC+8C,EAAiBt1D,GAAG+3D,GAAgBxwD,gBAAgB4sD,EAAgBmB,gBAChEA,GACAt1D,GAAGs1D,GAAgBzvD,UAI3Bw/C,EAAWrlD,GAAG+3D,GAAgBxwD,gBAAgB4sD,EAAgBO,MAI1DrP,IAAarlD,GAAGyE,cAChBrC,EAAI,0BAA2B,QAC/BpC,GAAGqlD,GAAUx/C,UAGZ7F,GAAG2V,kBAAkB4C,SAajBvY,GAAGm4D,GAAYlwD,aAtZN,sBAsZ2Co9C,IACzD6S,EAAal4D,GAAGqlD,GAAU99C,gBAAgB4sD,EAAgBkB,UAC1D6C,GAAcl4D,GAAGk4D,GAAYryD,WAb7BsyD,EAAW97C,gBA3YG,qBA6YVgpC,GAAYrlD,GAAGqlD,GAAUp9C,aA9YhB,qBAkZTjI,GAAGqlD,GAAUt/C,KACTf,QAAS,UAWrBwwD,EAAYx1D,GAAG+3D,GAAgBxwD,gBAAgB4sD,EAAgBqB,WAC1DhC,EAGIgC,IACLtB,EAAmBxuB,SAAS8vB,EAAUptD,aAtapB,gBAwalB8rD,EAAmBA,EAAmB,EAAIA,EAAmB,KAE7DT,EAAczzD,GAAGw1D,GAAWvtD,aAzaN,oBAkatButD,GAAax1D,GAAGw1D,GAAW3vD,SAS/B2tD,EAAiBA,GAAkBgC,EAEnCnC,EAAsBrzD,GAAG+3D,GAAgB/wD,WAAWmtD,EAAgBgB,mBAAmB9wD,OAAS,EAChGivD,EAAsBtzD,GAAG+3D,GAAgB/wD,WAAWmtD,EAAgBttC,OAAOxiB,OAAS,EAEpFyzD,EAAe93D,GAAG+3D,GAAgBxwD,gBAAgB4sD,EAAgBQ,MAE9C,MAAhBmD,EACA,KAAM,IAAI7xD,OAAM,0DAapB,OAVA+xD,GAAaF,EAAatwD,SAAS,GAAG5D,WAAU,GAChDk0D,EAAa1lD,UAAY,GAGrB2lD,EAAezwD,qBAAqB,UAAUjD,QAC9C0I,SAASC,cAAc,UAG3B5K,EAAI,8BAGA0vD,SAAUiG,EACVK,aAAcJ,IAItBK,EAAc,SAASj0D,EAAID,EAAO4tB,GAC9B,GAAIumC,GAAWvmC,EACXwmC,EAAWD,EAAS5wD,UAEpBvD,GAAQ,IACRo0D,EAAWv4D,GAAGs4D,GAAU9wD,WAAWrD,GAAOwD,aAI9C2wD,EAAS5yD,aAAatB,EAAIm0D,IAG9B3B,EAAiC,SAASH,GACtC,GAAI55C,GAAK45C,EAAmB55C,GACxB27C,EAAgB/B,EAAmB+B,cACnCC,EAAqBD,GAAiBA,EAAclC,cACpDd,EAAYa,EAAax5C,GACzBgB,GACI8F,qBAAsB8yC,EAAmB9yC,qBACzCF,QAASywC,EACTr4B,QAAQ,EACR7X,OAAO,EAGXhkB,IAAG2V,kBAAkB+C,cACjB88C,EACIx2D,EAAQ64C,OAAOmb,WAAah0D,EAAQ64C,OAAOmb,WAAae,GACxDwC,EAA+B15C,EAAI24C,GACnCgB,KAGAR,EAAkBR,GAAWr7C,KAAK,WAC9Bs7C,EAAkB54C,GAAM,GAAI7c,IAAG+O,QAE/B0mD,EAAkB54C,GAAI1C,KAAK,WACvB6R,WAAWwqC,EAA2Bx3D,EAAQ64C,OAAOya,qBAM/B,MAAtBmG,EACAC,EAAiB77C,EAAI47C,GAGrBrC,EAAmBv5C,EAAI27C,EAAe36C,KAOlD24C,IAGChB,IACLQ,EAAkBR,GAClBgB,MAIRG,EAAoC,SAASF,GACzC,GAAI55C,GAAK45C,EAAmB55C,GACxBkM,EAAe0tC,EAAmB1tC,aAClC4vC,EAAiBlC,EAAmBkC,eACpCnD,EAAYa,EAAax5C,GACzBgB,GACI8F,qBAAsB8yC,EAAmB9yC,qBACzCK,MAAOyvC,EACPhwC,QAASywC,EAGjB,IAAIsB,EACA,GAAIzsC,EAAc,CACd,KAAI/pB,EAAQ64C,OAAOmb,WAAah0D,EAAQ64C,OAAOmb,WAAae,GASxD,MAJI4E,IACA3C,EAAkBR,GAGfx2D,EAAQ68C,eAAe13B,SAAS4E,EAAcysC,EAAW33C,GAAMnE,KAClE,WACIy8C,EAAKX,GACLzB,IACA/nC,WAAWwqC,EAA2Bx3D,EAAQ64C,OAAOya,oBAGzD,WACIiE,EAA+B15C,EAAI24C,GACnCxpC,WAAWwqC,EAA2Bx3D,EAAQ64C,OAAOya,oBAjB7DiE,GAA+B15C,EAAI24C,GACnCgB,QAsBJD,GAA+B15C,EAAI24C,GACnCgB,KAKZoC,EAAsB,SAAS/7C,EAAIg8C,GAC/B,GAAIC,GAAMzB,EAAYx6C,GAElBk8C,EAA4B,MAANl8C,EAAas3C,EAAgBW,iBAAmBX,EAAgBr7C,WAEtFggD,KAAQ94D,GAAG84D,GAAKvyD,SAASwyD,KACzBD,EAAM94D,GAAG84D,GAAKvxD,gBAAgBwxD,IAG9BD,IACA94D,GAAG84D,GAAK/yD,KAAKkoC,MAAO4qB,EAAU,MAC9BC,EAAI9kD,aAAa,gBAAiB6kD,KAI1C1C,EAAO,SAAS/xD,GACZA,GAAMpE,GAAGoE,GAAI0C,YAAY9H,EAAQytB,QAAQ3nB,OAG7C4zD,EAAmB,SAASM,EAAmBC,GAC3C,GAAIC,GAAkB7C,EAAa2C,GAC/BG,EAAkB9C,EAAa4C,EAEnC72D,GAAIpC,GAAGwL,OAAO,qFAAsFwtD,EAAmBC,EAAmBA,IAG1IxD,EAAkBwD,GAAmBv/C,KAAK,WACtCq6C,IACA0B,EAAkBuD,GAAmB/pD,UACrC7M,EAAIpC,GAAGwL,OAAO,uEAAwEytD,EAAmBD,IACzGE,EAAgB1nB,IAAM2nB,EAAgB3nB,IACtC2kB,EAAK+C,IAET,WACIzD,EAAkBuD,GAAmB7pD,UAChCnQ,EAAQ2yD,aAAasB,iBACtBsD,EAA+ByC,EAAmBE,KAKlEl5D,IAAGsG,OAAOtH,EAAS6e,GACnBzb,EAAMpD,EAAQoD,IAITpC,GAAG2V,kBAAkB+C,gBACtB1Z,EAAQ64C,OAAOya,kBAAoB,EACnCtzD,EAAQ64C,OAAOmb,UAAY,GAG/B9uC,EAAYllB,EAAQ8zD,YACpBU,EAA4ClzD,SAA3BtB,EAAQ68C,eACzB0X,EAAcoE,IAEd/B,IAEA51D,GAAGsG,OAAOrE,MACN0vC,OAAQ,WACJvvC,EAAI,8BAEJ2xD,EAAsB,EAEtB7vC,EAAUjQ,YAAYs/C,EAAYzB,SAASluD,WAAU,IACrDkB,EAAKoyD,KACLj1D,KAAKm3D,oBACLrnC,EAAW/yB,EAAQ+zD,iBAAmB+D,EAAc5yC,EAAWiwC,EAAgBQ,MAE/EvyD,EAAI,gCAGRgxD,cAAe,SAAS/wD,GACpB,GAAIg3D,GAAer5D,GAAGiS,UAAU5P,EAChC6hB,GAAU9R,UAAY,GACtB8R,EAAUjQ,YAAYolD,IAG1B98C,MAAO,WACH2H,EAAU9R,UAAY,GACtBnQ,KAAK0vC,UAGTiX,WAAY,WACR72B,EAAS3f,UAAY,IAGzB89C,cAAe,WACX4D,GAAmB,GAGvBl2C,QAAS,SAASf,EAAI7b,EAAMs4D,EAAaC,EAAaC,GAClD,GAIIC,GAJAC,EAASnG,EAAY6E,aAAax0D,WAAU,GAC5C+1D,EAAa7C,EAAc4C,EAAQvF,EAAgBl2C,MACnDk6C,EAAarB,EAAc5yC,EAAWiwC,EAAgB90D,UACtD8iB,EAAgBq3C,EAAQ9F,EAAUC,QAAU5hC,CAG5CynC,KACA9F,EAAUG,IAAIh3C,GAAM68C,GAGxB15D,GAAG05D,GAAQ7yD,SArpBK,cAqpBwBgW,GACxCs7C,EAAW97C,gBAjpBO,qBAmpBds9C,IACA35D,GAAG25D,GAAY/xD,QAAQ5G,GACvB24D,EAAW3lD,aAAa,QAAShT,IAGrC04D,EAAO1lD,aA9pBI,aA8pBuB6I,GAE9By8C,EACAjB,EAAYqB,EAAQJ,EAAYn1D,MAAOge,GAGvCA,EAAclO,YAAYylD,GAG1BH,GACAG,EAAO30D,MAAMC,QAAU,OACvBhF,GAAG05D,GAAQ7yD,SAjqBI,uBAoqBf/B,EAAKuyD,EAAYx6C,IACjB/X,EAAKogB,EAAQrI,IACb/X,EAAKmyD,EAAUp6C,IACf/X,EAAKwyD,EAASz6C,IACd/X,EAAKsyD,EAASv6C,IACd/X,EAAKiyD,EAAYl6C,IAEbi3C,GACA7xD,KAAKyrD,WAAW7wC,GAGpB48C,EAAQpD,EAAax5C,GACjB48C,IAAUA,EAAMjoB,KAChBmkB,EAA6Bj8C,KAAK,SAASkgD,GACvCH,EAAMjoB,IAAMooB,EAAWpoB,IACnBooB,EAAW70D,MAAM00B,WAAamgC,EAAW70D,MAAM20B,UAC/C15B,GAAGy5D,GAAO1zD,KACN0zB,UAAWmgC,EAAW70D,MAAM00B,UAC5BC,SAAUkgC,EAAW70D,MAAM20B,WAInCy8B,EAAKsD,OAMrBpJ,eAAgB,SAASxzC,EAAI7b,EAAMs4D,EAAaC,GAC5Ct3D,KAAK2b,QAAQf,EAAI7b,EAAMs4D,EAAaC,GAAa,IAGrD5Q,cAAe,WACX52B,EAAS9d,YAAYy/C,EAAUC,SAC/BD,EAAUC,QAAU5mD,SAAS6mD,yBAC7BF,EAAUG,QAGd1J,WAAY,SAASttC,GACjB7c,GAAGikB,EAAQpH,IAAKhX,UAGpBikD,UAAW,SAAS1lD,GAChB,GAAIy1D,GAAcz1D,CAElB,IAAIy1D,EAAa,CAEb,KAAiD,MAA1CA,EAAYzxD,aA3tBZ,eA4tBHyxD,EAAcA,EAAYj0D,UAG9B,OAAO8/B,UAASm0B,EAAYzxD,aA/tBrB,iBAmuBf0xD,YAAa,WACT,MAAO/nC,IAGX66B,qBAAsB,SAAS/vC,GAC3B,GAAIrI,GAAWI,EAAYiI,EAE3BrI,IAAYxU,GAAGwU,GAAU3N,SAAS7H,EAAQytB,QAAQslC,WAGtDvI,eAAgB,SAAS3sC,EAAI7b,GACzB,GAAI+4D,GAAanlD,EAAYiI,EAEzBk9C,KACA/5D,GAAG+5D,GAAYnyD,QAAQ5G,GACvB+4D,EAAW/lD,aAAa,QAAShT,KAIzCwrD,aAAc,SAAS3vC,GACnB/X,EAAK8P,EAAYiI,KAGrB6vC,aAAc,SAAS7vC,GACnBs5C,EAAKvhD,EAAYiI,KAGrBm9C,WAAY,SAAS51D,GACjB,MAAOpE,IAAGoE,GAAImC,SAAS4tD,EAAgBl2C,OAG3CqG,UAAW,WACP,MAAOtlB,GAAQmnB,QAAU2wC,EAAc5yC,EAAWiwC,EAAgBhuC,SAGtEklC,mBAAoB,WAChBvmD,EAAKoyD,MAGT9L,mBAAoB,WAChB+K,EAAKe,MAGT/L,YAAa,WACT,MAAO2L,GAAc5yC,EAAWiwC,EAAgBO,OAGpD7I,uBAAwB,WACpB,MAAOwH,IAGXxG,UAAW,SAAShwC,GAChB/X,EAAKwyD,EAASz6C,KAGlBqxC,gBAAiB,WACb,MAAOoF,IAGXnF,UAAW,SAAStxC,GAChBs5C,EAAKmB,EAASz6C,KAGlBqsC,iBAAkB,SAASrsC,GACvB,MAAOoH,GAAQpH,IAGnB8vC,aAAc,SAAS9vC,GACnB,GAAIo9C,GAAO9C,EAAYt6C,EAEvBo9C,IAAQj6D,GAAGi6D,GAAMpzD,SAAS7H,EAAQytB,QAAQslC,WAG9C9I,gBAAiB,SAASpsC,GACtB,MAAO7c,IAAGikB,EAAQpH,IAAKtW,SAryBJ,sBAwyBvBkmD,aAAc,SAAS5vC,GACnB,GAAIo9C,GAAO9C,EAAYt6C,EAEvBo9C,IAAQj6D,GAAGi6D,GAAMnzD,YAAY9H,EAAQytB,QAAQslC,WAGjDmI,WAAY,SAAS91D,GACjB,MAAOpE,IAAGoE,GAAImC,SAAS4tD,EAAgBiB,cAAc,IAGzD9I,aAAc,SAASzvC,GACnB,MAAOi6C,GAAc7yC,EAAQpH,GAAKs3C,EAAgBgB,oBAGtDgF,YAAa,SAAS/1D,GAClB,MAAOpE,IAAGoE,GAAImC,SAAS4tD,EAAgBgB,mBAAmB,IAG9D1H,eAAgB,SAAS5wC,EAAI0Q,EAAQC,GACjC,GACIqrC,GADAC,EAAMzB,EAAYx6C,EAGlBi8C,IAAOtrC,EAAQ,IACfqrC,EAAUzyD,KAAKC,MAAMknB,EAASC,EAAQ,KAEtB,MAAZqrC,EACA/zD,EAAKg0D,GAGL3C,EAAK2C,GAGTF,EAAoB/7C,EAAIg8C,KAIhCxZ,oBAAqB,SAAS9xB,EAAQC,GAClCvrB,KAAKwrD,eAAe,KAAMlgC,EAAQC,IAGtCmgC,aAAc,SAAS9wC,GACnB,GAAIi8C,GAAMzB,EAAYx6C,EAEtBi8C,IAAOh0D,EAAKg0D,IAGhBM,kBAAmB,WACfn3D,KAAK0rD,gBAGTsB,cAAe,SAASpyC,GACpB+7C,EAAoB/7C,EAAI,GACxB5a,KAAKm3D,kBAAkBv8C,IAG3BuwC,mBAAoB,WAChBnrD,KAAKgtD,iBAGThB,WAAY,SAASpxC,GACjB,IAAKi3C,EAAkB,CACnB,GAAIzxC,GAASw0C,EAAUh6C,EAEvBwF,IAAUriB,GAAGqiB,GAAQvb,YAAY9H,EAAQytB,QAAQ3nB,QAIzD4oD,WAAY,SAAS7wC,GACjB/X,EAAK+xD,EAAUh6C,KAGnBu9C,SAAU,SAASh2D,GACf,MAAOpE,IAAGoE,GAAImC,SAAS4tD,EAAgB9xC,QAAQ,IAGnDqsC,WAAY,SAAS7xC,GACjBs5C,EAAKiB,EAASv6C,IACd/X,EAAKiyD,EAAYl6C,KAGrB4sC,aAAc,SAAS5sC,GACnB5a,KAAK6qD,cAAcjwC,EAAI7d,EAAQ6I,KAAKmjC,QACpC/oC,KAAKo4D,oBAAoBx9C,GACzB/X,EAAKyyD,EAAW16C,KAGpBowC,UAAW,SAASpwC,GAChB/X,EAAKsyD,EAASv6C,KAGlBy9C,QAAS,SAASl2D,GACd,MAAOpE,IAAGoE,GAAImC,SAAS4tD,EAAgBt7C,OAAO,IAGlD0hD,iBAAkB,SAASn2D,GACvB,MAAOpE,IAAGoE,GAAImC,SAAS4tD,EAAgBa,gBAAgB,IAG3DqF,oBAAqB,SAASx9C,GAC1Bs5C,EAAKY,EAAYl6C,IACjB/X,EAAKsyD,EAASv6C,KAGlB8sC,gBAAiB,SAAS9sC,GACtB5a,KAAK6qD,cAAcjwC,EAAI,IACvB5a,KAAKysD,WAAW7xC,GAChBs5C,EAAKoB,EAAW16C,KAGpB0xC,iBAAkB,SAAS1xC,GACvBs5C,EAAKc,EAAUp6C,KAGnB0yC,iBAAkB,SAAS1yC,GACvB/X,EAAKmyD,EAAUp6C,KAGnB29C,eAAgB,SAASp2D,GACrB,MAAOpE,IAAGoE,GAAImC,SAAS4tD,EAAgBc,cAAc,IAGzDwF,QAAS,SAASr2D,GACd,MAAOpE,IAAGoE,GAAImC,SAAS4tD,EAAgBttC,OAAO,IAGlDzH,WAAY,SAASvC,EAAIhV,GACrB,GAAImW,GAAOkH,EAAQrI,EAEfmB,KACAm4C,EAAKn4C,GACLhe,GAAGge,GAAMpW,QAAQC,KAIzBilD,cAAe,SAASjwC,EAAIhV,GACxB,GAAI6yD,GAAS5D,EAAc7yC,EAAQpH,GAAKs3C,EAAgBe,WAEpDwF,KAEY,MAAR7yD,EACA7H,GAAG06D,GAAQ1yD,YAGXhI,GAAG06D,GAAQ9yD,QAAQC,KAK/BslD,YAAa,SAAStwC,GAClB7c,GAAGikB,EAAQpH,IAAK/V,YA97BA,kBA+7BhBhC,EAAKyyD,EAAW16C,KAGpB4xC,YAAa,SAAS5xC,GAClB7c,GAAGikB,EAAQpH,IAAKhW,SAn8BA,kBAo8BhBsvD,EAAKoB,EAAW16C,KAGpB2zC,gBAAiB,SAAS3zC,EAAI27C,EAAe70C,GACpC1hB,KAAKgnD,gBAAgBpsC,KACtBo3C,EAAqBnyD,MAAM+a,GAAIA,EAAI8G,qBAAsBA,EAAsB60C,cAAeA,KAC7FxE,GAAgCwC,MAIzClG,gBAAiB,SAASzzC,EAAIkM,EAAc4vC,EAAgBh1C,GACnD1hB,KAAKgnD,gBAAgBpsC,KACtBo3C,EAAqBnyD,MAAM6hB,qBAAsBA,EAAsB+yC,QAAQ,EAAM75C,GAAIA,EAAIkM,aAAcA,EAAc4vC,eAAgBA,KACxI3E,GAAgCwC,MAIzCjE,UAAW,SAASnvD,GAChB,MAAOpD,IAAG2V,kBAAkB0C,iBAAmB2+C,EAAU5zD,IAG7DovD,WAAY,SAASpvD,EAAMf,EAASqwD,GAChC,GAAIiI,GAAS3D,EAAU5zD,GACnBw3D,EAAY9D,EAAc6D,EAAQxG,EAAgBI,eAClDsG,EAAUF,EAAOrzD,qBAAqB,SAAS,GAC/CwzD,EAAYhE,EAAc6D,EAAQxG,EAAgBE,oBAClD0G,EAAQjE,EAAc6D,EAAQxG,EAAgBK,gBAC9C1lD,EAAU,GAAI9O,IAAG+O,QAEjBisD,EAAe,WACXF,EAAUz1D,oBAAoB,QAAS41D,GACvCF,GAASA,EAAM11D,oBAAoB,QAAS61D,GAC5CpsD,EAAQK,WAGZ8rD,EAAqB,WACjBH,EAAUz1D,oBAAoB,QAAS41D,GACvCN,EAAOQ,SAGXD,EAAiB,WACbP,EAAOt1D,oBAAoB,QAAS21D,GACpCD,EAAM11D,oBAAoB,QAAS61D,GACnCP,EAAOQ,QAEPrsD,EAAQG,QAAQ4rD,GAAWA,EAAQpwD,OAc3C,OAXAkwD,GAAOz1D,iBAAiB,QAAS81D,GACjCF,EAAU51D,iBAAiB,QAAS+1D,GACpCF,GAASA,EAAM71D,iBAAiB,QAASg2D,GAErCL,IACAA,EAAQpwD,MAAQioD,GAEpBkI,EAAU7yD,YAAc1F,EAExBs4D,EAAOS,YAEAtsD,MChhCnB9O,GAAGq7D,eAAiB,SAASC,EAAGC,GAC5B,YAqBA,SAAS/N,GAAW9qD,GAChBwS,EAASjQ,OAAOvC,EAASmb,EAAK29C,UAAW,SAASlkC,GAE9CA,EAAQA,GAASpuB,OAAOouB,KAGxB,IAAI9nB,GAAS8nB,EAAM9nB,QAAU8nB,EAAMmkC,UAEnC59C,GAAK69C,UAAUlsD,EAAQ8nB,KA3B/B,GAAIpiB,GAAW,GAAIlV,IAAG+U,eAClB8I,GACI29C,UAAW,QACXG,SAAU,KACVD,UAAW,SAASlsD,EAAQ8nB,KAKpCt3B,IAAGsG,OAAOrE,MACNurD,WAAY,SAAS9qD,GACjB8qD,EAAW9qD,IAGfuS,QAAS,WACLC,EAASD,aAiBjBjV,GAAGsG,OAAOi1D,GACNK,kBAAmB,SAAS5wD,GACxB,MAAOA,GAAK6wD,UAGhBC,kBAAmB,WACf,MAAO5mD,MAIflV,GAAGsG,OAAOuX,EAAMy9C,GAEZz9C,EAAK89C,UACLnO,EAAW3vC,EAAK89C,WClDxB37D,GAAGqqD,wBAA0B,SAASiR,GAClC,YAqBA,SAASS,GAAavsD,EAAQ8nB,GAC1Bt3B,GAAGY,KAAKo7D,EAAgB,SAASC,EAAYvqC,GACzC,GACInO,GADA24C,EAA2BD,EAAWr8D,OAAO,GAAGC,cAAgBo8D,EAAWn8D,MAAM,EAGrF,IAAI+d,EAAKotC,WAAW,KAAOiR,GAA0B1sD,GAKjD,MAJA+T,GAAS1F,EAAKotC,WAAWnB,UAAUt6C,GACnCxP,GAAG8R,eAAewlB,GAClBzZ,EAAKzb,IAAIpC,GAAGwL,OAAO,+DAAgEqS,EAAK+tC,UAAUroC,GAASA,IAC3GmO,EAAQnO,IACD,IA7BnB,GAAI44C,MACAt+C,GACIotC,WAAY,KACZ7oD,IAAK,SAASC,EAASkpD,KACvBC,aAAc,SAASjoC,KACvBsK,SAAU,SAAStK,KACnBkoC,QAAS,SAASloC,KAClBmoC,QAAS,SAASnoC,KAClBooC,WAAY,SAASpoC,KACrBqoC,UAAW,SAASroC,MAExBy4C,GACI35C,OAAQ,SAASxF,GAAMgB,EAAKgQ,SAAShR,IACrCgK,MAAQ,SAAShK,GAAMgB,EAAK4tC,QAAQ5uC,IACpCo4C,aAAc,SAASp4C,GAAMgB,EAAK2tC,aAAa3uC,IAC/ChE,MAAO,SAASgE,GAAMgB,EAAK6tC,QAAQ7uC,IACnCm4C,eAAgB,SAASn4C,GAAMgB,EAAK8tC,WAAW9uC,IAkBvD7c,IAAGsG,OAAOuX,EAAMy9C,GAEhBz9C,EAAK29C,UAAY,QACjB39C,EAAK69C,UAAYK,EACjBl+C,EAAK89C,SAAW99C,EAAKotC,WAAW6O,cAEhC95D,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGq7D,eAAex9C,EAAMs+C,KC1ChDn8D,GAAG8rD,qBAAuB,SAASwP,GAC/B,YAiBA,SAASS,GAAavsD,EAAQ8nB,GAC1B,GAAIzZ,EAAKotC,WAAW+O,WAAWxqD,IAAWqO,EAAKotC,WAAWiP,WAAW1qD,GAAS,CAC1E,GAAI+T,GAAS1F,EAAKotC,WAAWnB,UAAUt6C,EAC1BqO,GAAKouC,kBAAkB1oC,KAGrBvjB,GAAGmd,OAAOwC,YACrB9B,EAAKzb,IAAIpC,GAAGwL,OAAO,4DAA6DqS,EAAK+tC,UAAUroC,GAASA,IACxGvjB,GAAG8R,eAAewlB,GAElB6kC,EAAqBC,mBAAmB74C,EAAQ/T,GAAQ,KAzBpE,GAAI2sD,MACAt+C,GACIotC,WAAY,KACZ7oD,IAAK,SAASC,EAASkpD,KACvB9+B,SACIxO,KAAM,iBACNm3C,aAAc,yBAElBnJ,kBAAmB,SAAS1oC,KAC5BqoC,UAAW,SAASroC,KAG5BvjB,IAAGsG,OAAOuX,EAAMy9C,GAkBhBz9C,EAAK29C,UAAY,QACjB39C,EAAK69C,UAAYK,EAEjB/7D,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGq8D,oBAAoBx+C,EAAMs+C,KCpCrDn8D,GAAGktD,4BAA8B,SAASoO,EAAGa,GACzC,YAaA,SAASG,GAAiB9sD,EAAQ8nB,GAC9B,GAAIzZ,EAAKotC,WAAWkP,YAAY3qD,GAAS,CACrC,GAAI+T,GAAS1F,EAAKotC,WAAWnB,UAAUt6C,EAC1BqO,GAAKouC,kBAAkB1oC,KAErBvjB,GAAGmd,OAAOwC,YACrB9B,EAAKzb,IAAIpC,GAAGwL,OAAO,kEAAmEqS,EAAK+tC,UAAUroC,GAASA,IAC9G44C,EAAqBC,mBAAmB74C,EAAQ/T,KAlB5D,GAAIqO,IACIotC,WAAY,KACZgB,kBAAmB,SAAS1oC,KAC5BnhB,IAAK,SAASC,EAASkpD,KAG1B4Q,KACDA,MAgBJt+C,EAAK29C,UAAY,UACjB39C,EAAK69C,UAAYY,EAEjBt8D,GAAGsG,OAAOuX,EAAMy9C,GAChBt7D,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGq8D,oBAAoBx+C,EAAMs+C,KCzBrDn8D,GAAG+rD,0BAA4B,SAASluC,GACpC,YAEAA,GAAK29C,UAAY,QACjB39C,EAAK89C,SAAW,KAEhB37D,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGktD,4BAA4BrvC,QCVvD7d,GAAGq8D,oBAAsB,SAASf,EAAGa,GACjC,YAWA,SAASI,GAAyBh5C,GAC9B,GAAIi5C,GAAkB3+C,EAAK+tC,UAAUroC,GACjC9O,EAAS+nD,EAAgB9nD,YAAY,IAMzC,OAJID,GAAS,IACT+nD,EAAkBA,EAAgB7nD,OAAO,EAAGF,IAGzC+nD,EAGX,QAASC,GAAqBl5C,GAC1B,GAAIm5C,GAAW7+C,EAAK+tC,UAAUroC,EAC9B,OAAOvjB,IAAGuU,aAAamoD,GAI3B,QAASC,GAAiBC,EAAoBr5C,GAC1C,GACIs5C,GADA19C,EAAUy9C,EAAmBnyD,KAGjBnK,UAAZ6e,GAAyBnf,GAAGoL,QAAQ+T,GAAS9a,OAAS,IACtDw4D,EAAgBJ,EAAqBl5C,GAEfjjB,SAAlBu8D,IACA19C,EAAUA,EAAU,IAAM09C,GAG9Bh/C,EAAKquC,UAAU3oC,EAAQpE,IAG3BtB,EAAKsuC,sBAAsB5oC,GAAQ,GAIvC,QAASu5C,GAAyBjC,EAASt3C,GACvC44C,EAAqBL,oBAAoB72D,OAAO41D,EAAS,OAAQ,WAC7D8B,EAAiB9B,EAASt3C,KAKlC,QAASw5C,GAA6BlC,EAASt3C,GAC3C44C,EAAqBL,oBAAoB72D,OAAO41D,EAAS,QAAS,SAASvjC,GAI1D,MAFFA,EAAM0lC,SAAW1lC,EAAM2lC,QAG9BN,EAAiB9B,EAASt3C,KAzDtC,GAAI1F,IACIotC,WAAY,KACZ7oD,IAAK,SAASC,EAASkpD,KACvBU,kBAAmB,SAAS1oC,KAC5BqoC,UAAW,SAASroC,KACpB2oC,UAAW,SAAS3oC,EAAQpE,KAC5BgtC,sBAAuB,SAAS5oC,EAAQ6oC,KAwDhDpsD,IAAGsG,OAAOuX,EAAMy9C,GAEhBz9C,EAAK89C,SAAW99C,EAAKotC,WAAW6O,cAEhC95D,GAAGsG,OAAOrE,KAAM,GAAIjC,IAAGq7D,eAAex9C,EAAMs+C,IAE5Cn8D,GAAGsG,OAAO61D,GACNC,mBAAoB,SAASv/C,EAAIrN,EAAQ0tD,GACrC,GAAIN,GAAqB/+C,EAAKotC,WAAWqB,aAAazvC,EAEtDgB,GAAKsuC,sBAAsBtvC,GAAI,GAE/B+/C,EAAmBnyD,MAAQ8xD,EAAyB1/C,GAEhDqgD,GACAN,EAAmBO,QAGvBL,EAAyBF,EAAoB//C,GAC7CkgD,EAA6BH,EAAoB//C,Q7CvF9B3T","file":"jquery.fine-uploader.min.js","sourcesContent":[null,"/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var $el,\n pluginOptions = [\"uploaderType\", \"endpointType\"];\n\n function init(options) {\n var xformedOpts = transformVariables(options || {}),\n newUploaderInstance = getNewUploaderInstance(xformedOpts);\n\n uploader(newUploaderInstance);\n addCallbacks(xformedOpts, newUploaderInstance);\n\n return $el;\n }\n\n function getNewUploaderInstance(params) {\n var uploaderType = pluginOption(\"uploaderType\"),\n namespace = pluginOption(\"endpointType\");\n\n // If the integrator has defined a specific type of uploader to load, use that, otherwise assume `qq.FineUploader`\n if (uploaderType) {\n // We can determine the correct constructor function to invoke by combining \"FineUploader\"\n // with the upper camel cased `uploaderType` value.\n uploaderType = uploaderType.charAt(0).toUpperCase() + uploaderType.slice(1).toLowerCase();\n\n if (namespace) {\n return new qq[namespace][\"FineUploader\" + uploaderType](params);\n }\n\n return new qq[\"FineUploader\" + uploaderType](params);\n }\n else {\n if (namespace) {\n return new qq[namespace].FineUploader(params);\n }\n\n return new qq.FineUploader(params);\n }\n }\n\n function dataStore(key, val) {\n var data = $el.data(\"fineuploader\");\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(\"fineuploader\", data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element\n // tied to this instance of the plug-in\n function uploader(instanceToStore) {\n return dataStore(\"uploader\", instanceToStore);\n }\n\n function pluginOption(option, optionVal) {\n return dataStore(option, optionVal);\n }\n\n // Implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and\n // return the result of executing the bound handler back to Fine Uploader\n function addCallbacks(transformedOpts, newUploaderInstance) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(newUploaderInstance._options.callbacks, function(prop, nonJqueryCallback) {\n var name, callbackEventTarget;\n\n name = /^on(\\w+)/.exec(prop)[1];\n name = name.substring(0, 1).toLowerCase() + name.substring(1);\n callbackEventTarget = $el;\n\n callbacks[prop] = function() {\n var originalArgs = Array.prototype.slice.call(arguments),\n transformedArgs = [],\n nonJqueryCallbackRetVal, jqueryEventCallbackRetVal;\n\n $.each(originalArgs, function(idx, arg) {\n transformedArgs.push(maybeWrapInJquery(arg));\n });\n\n nonJqueryCallbackRetVal = nonJqueryCallback.apply(this, originalArgs);\n\n try {\n jqueryEventCallbackRetVal = callbackEventTarget.triggerHandler(name, transformedArgs);\n }\n catch (error) {\n qq.log(\"Caught error in Fine Uploader jQuery event handler: \" + error.message, \"error\");\n }\n\n /*jshint -W116*/\n if (nonJqueryCallbackRetVal != null) {\n return nonJqueryCallbackRetVal;\n }\n return jqueryEventCallbackRetVal;\n };\n });\n\n newUploaderInstance._options.callbacks = callbacks;\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n if (source.uploaderType !== \"basic\") {\n xformed = { element: $el[0] };\n }\n else {\n xformed = {};\n }\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if ($.inArray(prop, pluginOptions) >= 0) {\n pluginOption(prop, val);\n }\n else if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n var arrayObjDest = {};\n\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else if ($.isPlainObject(arrayVal)) {\n transformVariables(arrayVal, arrayObjDest);\n arrayVals.push(arrayObjDest);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n !command.match(/^_/) && //enforce private methods convention\n uploader()[command] !== undefined;\n }\n\n // Assuming we have already verified that this is a valid command, call the associated function in the underlying\n // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller\n function delegateCommand(command) {\n var xformedArgs = [],\n origArgs = Array.prototype.slice.call(arguments, 1),\n retVal;\n\n transformVariables(origArgs, xformedArgs);\n\n retVal = uploader()[command].apply(uploader(), xformedArgs);\n\n return maybeWrapInJquery(retVal);\n }\n\n // If the value is an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n function maybeWrapInJquery(val) {\n var transformedVal = val;\n\n // If the command is returning an `HTMLElement` or `HTMLDocument`, wrap it in a `jQuery` object\n /*jshint -W116*/\n if (val != null && typeof val === \"object\" &&\n (val.nodeType === 1 || val.nodeType === 9) && val.cloneNode) {\n\n transformedVal = $(val);\n }\n\n return transformedVal;\n }\n\n $.fn.fineUploader = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (uploader() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist on jQuery.fineUploader\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals jQuery, qq*/\n(function($) {\n \"use strict\";\n var rootDataKey = \"fineUploaderDnd\",\n $el;\n\n function init(options) {\n if (!options) {\n options = {};\n }\n\n options.dropZoneElements = [$el];\n var xformedOpts = transformVariables(options);\n addCallbacks(xformedOpts);\n dnd(new qq.DragAndDrop(xformedOpts));\n\n return $el;\n }\n\n function dataStore(key, val) {\n var data = $el.data(rootDataKey);\n\n if (val) {\n if (data === undefined) {\n data = {};\n }\n data[key] = val;\n $el.data(rootDataKey, data);\n }\n else {\n if (data === undefined) {\n return null;\n }\n return data[key];\n }\n }\n\n function dnd(instanceToStore) {\n return dataStore(\"dndInstance\", instanceToStore);\n }\n\n function addCallbacks(transformedOpts) {\n var callbacks = transformedOpts.callbacks = {};\n\n $.each(new qq.DragAndDrop.callbacks(), function(prop, func) {\n var name = prop,\n $callbackEl;\n\n $callbackEl = $el;\n\n callbacks[prop] = function() {\n var args = Array.prototype.slice.call(arguments),\n jqueryHandlerResult = $callbackEl.triggerHandler(name, args);\n\n return jqueryHandlerResult;\n };\n });\n }\n\n //transform jQuery objects into HTMLElements, and pass along all other option properties\n function transformVariables(source, dest) {\n var xformed, arrayVals;\n\n if (dest === undefined) {\n xformed = {};\n }\n else {\n xformed = dest;\n }\n\n $.each(source, function(prop, val) {\n if (val instanceof $) {\n xformed[prop] = val[0];\n }\n else if ($.isPlainObject(val)) {\n xformed[prop] = {};\n transformVariables(val, xformed[prop]);\n }\n else if ($.isArray(val)) {\n arrayVals = [];\n $.each(val, function(idx, arrayVal) {\n if (arrayVal instanceof $) {\n $.merge(arrayVals, arrayVal);\n }\n else {\n arrayVals.push(arrayVal);\n }\n });\n xformed[prop] = arrayVals;\n }\n else {\n xformed[prop] = val;\n }\n });\n\n if (dest === undefined) {\n return xformed;\n }\n }\n\n function isValidCommand(command) {\n return $.type(command) === \"string\" &&\n command === \"dispose\" &&\n dnd()[command] !== undefined;\n }\n\n function delegateCommand(command) {\n var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1);\n transformVariables(origArgs, xformedArgs);\n return dnd()[command].apply(dnd(), xformedArgs);\n }\n\n $.fn.fineUploaderDnd = function(optionsOrCommand) {\n var self = this, selfArgs = arguments, retVals = [];\n\n this.each(function(index, el) {\n $el = $(el);\n\n if (dnd() && isValidCommand(optionsOrCommand)) {\n retVals.push(delegateCommand.apply(self, selfArgs));\n\n if (self.length === 1) {\n return false;\n }\n }\n else if (typeof optionsOrCommand === \"object\" || !optionsOrCommand) {\n init.apply(self, selfArgs);\n }\n else {\n $.error(\"Method \" + optionsOrCommand + \" does not exist in Fine Uploader's DnD module.\");\n }\n });\n\n if (retVals.length === 1) {\n return retVals[0];\n }\n else if (retVals.length > 1) {\n return retVals;\n }\n\n return this;\n };\n\n}(jQuery));\n","/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/* globals qq */\n/**\n * Fine Uploader top-level Error container. Inherits from `Error`.\n */\n(function() {\n \"use strict\";\n\n qq.Error = function(message) {\n this.message = \"[Fine Uploader \" + qq.version + \"] \" + message;\n };\n\n qq.Error.prototype = new Error();\n}());\n","/*global qq */\nqq.version = \"5.16.2\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n // adapted from https://stackoverflow.com/a/23278460/486979\n supportsFolderDrop = supportsFileDrop && (function() {\n var input = document.createElement(\"input\");\n\n input.type = \"file\";\n return !!(\"webkitdirectory\" in (input || document.querySelectorAll(\"input[type=file]\")[0]));\n }());\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/* globals qq */\n/**\n * Placeholder for a Blob that will be generated on-demand.\n *\n * @param referenceBlob Parent of the generated blob\n * @param onCreate Function to invoke when the blob must be created. Must be promissory.\n * @constructor\n */\nqq.BlobProxy = function(referenceBlob, onCreate) {\n \"use strict\";\n\n qq.extend(this, {\n referenceBlob: referenceBlob,\n\n create: function() {\n return onCreate(referenceBlob);\n }\n });\n};\n","/*globals qq*/\n\n/**\n * This module represents an upload or \"Select File(s)\" button. It's job is to embed an opaque ``\n * element as a child of a provided \"container\" element. This \"container\" element (`options.element`) is used to provide\n * a custom style for the `` element. The ability to change the style of the container element is also\n * provided here by adding CSS classes to the container on hover/focus.\n *\n * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be\n * available on all supported browsers.\n *\n * @param o Options to override the default values\n */\nqq.UploadButton = function(o) {\n \"use strict\";\n\n var self = this,\n\n disposeSupport = new qq.DisposeSupport(),\n\n options = {\n // Corresponds to the `accept` attribute on the associated ``\n acceptFiles: null,\n\n // \"Container\" element\n element: null,\n\n focusClass: \"qq-upload-button-focus\",\n\n // A true value allows folders to be selected, if supported by the UA\n folders: false,\n\n // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n hoverClass: \"qq-upload-button-hover\",\n\n ios8BrowserCrashWorkaround: false,\n\n // If true adds `multiple` attribute to ``\n multiple: false,\n\n // `name` attribute of ``\n name: \"qqfile\",\n\n // Called when the browser invokes the onchange handler on the ``\n onChange: function(input) {},\n\n title: null\n },\n input, buttonId;\n\n // Overrides any of the default option values with any option values passed in during construction.\n qq.extend(options, o);\n\n buttonId = qq.getUniqueId();\n\n // Embed an opaque `` element as a child of `options.element`.\n function createInput() {\n var input = document.createElement(\"input\");\n\n input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId);\n input.setAttribute(\"title\", options.title);\n\n self.setMultiple(options.multiple, input);\n\n if (options.folders && qq.supportedFeatures.folderSelection) {\n // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute\n input.setAttribute(\"webkitdirectory\", \"\");\n }\n\n if (options.acceptFiles) {\n input.setAttribute(\"accept\", options.acceptFiles);\n }\n\n input.setAttribute(\"type\", \"file\");\n input.setAttribute(\"name\", options.name);\n\n qq(input).css({\n position: \"absolute\",\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n right: 0,\n top: 0,\n fontFamily: \"Arial\",\n // It's especially important to make this an arbitrarily large value\n // to ensure the rendered input button in IE takes up the entire\n // space of the container element. Otherwise, the left side of the\n // button will require a double-click to invoke the file chooser.\n // In other browsers, this might cause other issues, so a large font-size\n // is only used in IE. There is a bug in IE8 where the opacity style is ignored\n // in some cases when the font-size is large. So, this workaround is not applied\n // to IE8.\n fontSize: qq.ie() && !qq.ie8() ? \"3500px\" : \"118px\",\n margin: 0,\n padding: 0,\n cursor: \"pointer\",\n opacity: 0\n });\n\n // Setting the file input's height to 100% in IE7 causes\n // most of the visible button to be unclickable.\n !qq.ie7() && qq(input).css({height: \"100%\"});\n\n options.element.appendChild(input);\n\n disposeSupport.attach(input, \"change\", function() {\n options.onChange(input);\n });\n\n // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers\n disposeSupport.attach(input, \"mouseover\", function() {\n qq(options.element).addClass(options.hoverClass);\n });\n disposeSupport.attach(input, \"mouseout\", function() {\n qq(options.element).removeClass(options.hoverClass);\n });\n\n disposeSupport.attach(input, \"focus\", function() {\n qq(options.element).addClass(options.focusClass);\n });\n disposeSupport.attach(input, \"blur\", function() {\n qq(options.element).removeClass(options.focusClass);\n });\n\n return input;\n }\n\n // Make button suitable container for input\n qq(options.element).css({\n position: \"relative\",\n overflow: \"hidden\",\n // Make sure browse button is in the right side in Internet Explorer\n direction: \"ltr\"\n });\n\n // Exposed API\n qq.extend(this, {\n getInput: function() {\n return input;\n },\n\n getButtonId: function() {\n return buttonId;\n },\n\n setMultiple: function(isMultiple, optInput) {\n var input = optInput || this.getInput();\n\n // Temporary workaround for bug in in iOS8 UIWebView that causes the browser to crash\n // before the file chooser appears if the file input doesn't contain a multiple attribute.\n // See #1283.\n if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) {\n input.setAttribute(\"multiple\", \"\");\n }\n\n else {\n if (isMultiple) {\n input.setAttribute(\"multiple\", \"\");\n }\n else {\n input.removeAttribute(\"multiple\");\n }\n }\n },\n\n setAcceptFiles: function(acceptFiles) {\n if (acceptFiles !== options.acceptFiles) {\n input.setAttribute(\"accept\", acceptFiles);\n }\n },\n\n reset: function() {\n if (input.parentNode) {\n qq(input).remove();\n }\n\n qq(options.element).removeClass(options.focusClass);\n input = null;\n input = createInput();\n }\n });\n\n input = createInput();\n};\n\nqq.UploadButton.BUTTON_ID_ATTR_NAME = \"qq-button-id\";\n","/*globals qq */\nqq.UploadData = function(uploaderProxy) {\n \"use strict\";\n\n var data = [],\n byUuid = {},\n byStatus = {},\n byProxyGroupId = {},\n byBatchId = {};\n\n function getDataByIds(idOrIds) {\n if (qq.isArray(idOrIds)) {\n var entries = [];\n\n qq.each(idOrIds, function(idx, id) {\n entries.push(data[id]);\n });\n\n return entries;\n }\n\n return data[idOrIds];\n }\n\n function getDataByUuids(uuids) {\n if (qq.isArray(uuids)) {\n var entries = [];\n\n qq.each(uuids, function(idx, uuid) {\n entries.push(data[byUuid[uuid]]);\n });\n\n return entries;\n }\n\n return data[byUuid[uuids]];\n }\n\n function getDataByStatus(status) {\n var statusResults = [],\n statuses = [].concat(status);\n\n qq.each(statuses, function(index, statusEnum) {\n var statusResultIndexes = byStatus[statusEnum];\n\n if (statusResultIndexes !== undefined) {\n qq.each(statusResultIndexes, function(i, dataIndex) {\n statusResults.push(data[dataIndex]);\n });\n }\n });\n\n return statusResults;\n }\n\n qq.extend(this, {\n /**\n * Adds a new file to the data cache for tracking purposes.\n *\n * @param spec Data that describes this file. Possible properties are:\n *\n * - uuid: Initial UUID for this file.\n * - name: Initial name of this file.\n * - size: Size of this file, omit if this cannot be determined\n * - status: Initial `qq.status` for this file. Omit for `qq.status.SUBMITTING`.\n * - batchId: ID of the batch this file belongs to\n * - proxyGroupId: ID of the proxy group associated with this file\n * - onBeforeStatusChange(fileId): callback that is executed before the status change is broadcast\n *\n * @returns {number} Internal ID for this file.\n */\n addFile: function(spec) {\n var status = spec.status || qq.status.SUBMITTING,\n id = data.push({\n name: spec.name,\n originalName: spec.name,\n uuid: spec.uuid,\n size: spec.size == null ? -1 : spec.size,\n status: status,\n file: spec.file\n }) - 1;\n\n if (spec.batchId) {\n data[id].batchId = spec.batchId;\n\n if (byBatchId[spec.batchId] === undefined) {\n byBatchId[spec.batchId] = [];\n }\n byBatchId[spec.batchId].push(id);\n }\n\n if (spec.proxyGroupId) {\n data[id].proxyGroupId = spec.proxyGroupId;\n\n if (byProxyGroupId[spec.proxyGroupId] === undefined) {\n byProxyGroupId[spec.proxyGroupId] = [];\n }\n byProxyGroupId[spec.proxyGroupId].push(id);\n }\n\n data[id].id = id;\n byUuid[spec.uuid] = id;\n\n if (byStatus[status] === undefined) {\n byStatus[status] = [];\n }\n byStatus[status].push(id);\n\n spec.onBeforeStatusChange && spec.onBeforeStatusChange(id);\n uploaderProxy.onStatusChange(id, null, status);\n\n return id;\n },\n\n retrieve: function(optionalFilter) {\n if (qq.isObject(optionalFilter) && data.length) {\n if (optionalFilter.id !== undefined) {\n return getDataByIds(optionalFilter.id);\n }\n\n else if (optionalFilter.uuid !== undefined) {\n return getDataByUuids(optionalFilter.uuid);\n }\n\n else if (optionalFilter.status) {\n return getDataByStatus(optionalFilter.status);\n }\n }\n else {\n return qq.extend([], data, true);\n }\n },\n\n removeFileRef: function(id) {\n var record = getDataByIds(id);\n\n if (record) {\n delete record.file;\n }\n },\n\n reset: function() {\n data = [];\n byUuid = {};\n byStatus = {};\n byBatchId = {};\n },\n\n setStatus: function(id, newStatus) {\n var oldStatus = data[id].status,\n byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id);\n\n byStatus[oldStatus].splice(byStatusOldStatusIndex, 1);\n\n data[id].status = newStatus;\n\n if (byStatus[newStatus] === undefined) {\n byStatus[newStatus] = [];\n }\n byStatus[newStatus].push(id);\n\n uploaderProxy.onStatusChange(id, oldStatus, newStatus);\n },\n\n uuidChanged: function(id, newUuid) {\n var oldUuid = data[id].uuid;\n\n data[id].uuid = newUuid;\n byUuid[newUuid] = id;\n delete byUuid[oldUuid];\n },\n\n updateName: function(id, newName) {\n data[id].name = newName;\n },\n\n updateSize: function(id, newSize) {\n data[id].size = newSize;\n },\n\n // Only applicable if this file has a parent that we may want to reference later.\n setParentId: function(targetId, parentId) {\n data[targetId].parentId = parentId;\n },\n\n getIdsInProxyGroup: function(id) {\n var proxyGroupId = data[id].proxyGroupId;\n\n if (proxyGroupId) {\n return byProxyGroupId[proxyGroupId];\n }\n return [];\n },\n\n getIdsInBatch: function(id) {\n var batchId = data[id].batchId;\n\n return byBatchId[batchId];\n }\n });\n};\n\nqq.status = {\n SUBMITTING: \"submitting\",\n SUBMITTED: \"submitted\",\n REJECTED: \"rejected\",\n QUEUED: \"queued\",\n CANCELED: \"canceled\",\n PAUSED: \"paused\",\n UPLOADING: \"uploading\",\n UPLOAD_FINALIZING: \"upload finalizing\",\n UPLOAD_RETRYING: \"retrying upload\",\n UPLOAD_SUCCESSFUL: \"upload successful\",\n UPLOAD_FAILED: \"upload failed\",\n DELETE_FAILED: \"delete failed\",\n DELETING: \"deleting\",\n DELETED: \"deleted\"\n};\n","/*globals qq*/\n/**\n * Defines the public API for FineUploaderBasic mode.\n */\n(function() {\n \"use strict\";\n\n qq.basePublicApi = {\n // DEPRECATED - TODO REMOVE IN NEXT MAJOR RELEASE (replaced by addFiles)\n addBlobs: function(blobDataOrArray, params, endpoint) {\n this.addFiles(blobDataOrArray, params, endpoint);\n },\n\n addInitialFiles: function(cannedFileList) {\n var self = this;\n\n qq.each(cannedFileList, function(index, cannedFile) {\n self._addCannedFile(cannedFile);\n });\n },\n\n addFiles: function(data, params, endpoint) {\n this._maybeHandleIos8SafariWorkaround();\n\n var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId,\n\n processBlob = qq.bind(function(blob) {\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName\n }, batchId, verifiedFiles);\n }, this),\n\n processBlobData = qq.bind(function(blobData) {\n this._handleNewFile(blobData, batchId, verifiedFiles);\n }, this),\n\n processCanvas = qq.bind(function(canvas) {\n var blob = qq.canvasToBlob(canvas);\n\n this._handleNewFile({\n blob: blob,\n name: this._options.blobs.defaultName + \".png\"\n }, batchId, verifiedFiles);\n }, this),\n\n processCanvasData = qq.bind(function(canvasData) {\n var normalizedQuality = canvasData.quality && canvasData.quality / 100,\n blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality);\n\n this._handleNewFile({\n blob: blob,\n name: canvasData.name\n }, batchId, verifiedFiles);\n }, this),\n\n processFileOrInput = qq.bind(function(fileOrInput) {\n if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) {\n var files = Array.prototype.slice.call(fileOrInput.files),\n self = this;\n\n qq.each(files, function(idx, file) {\n self._handleNewFile(file, batchId, verifiedFiles);\n });\n }\n else {\n this._handleNewFile(fileOrInput, batchId, verifiedFiles);\n }\n }, this),\n\n normalizeData = function() {\n if (qq.isFileList(data)) {\n data = Array.prototype.slice.call(data);\n }\n data = [].concat(data);\n },\n\n self = this,\n verifiedFiles = [];\n\n this._currentBatchId = batchId;\n\n if (data) {\n normalizeData();\n\n qq.each(data, function(idx, fileContainer) {\n if (qq.isFileOrInput(fileContainer)) {\n processFileOrInput(fileContainer);\n }\n else if (qq.isBlob(fileContainer)) {\n processBlob(fileContainer);\n }\n else if (qq.isObject(fileContainer)) {\n if (fileContainer.blob && fileContainer.name) {\n processBlobData(fileContainer);\n }\n else if (fileContainer.canvas && fileContainer.name) {\n processCanvasData(fileContainer);\n }\n }\n else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === \"canvas\") {\n processCanvas(fileContainer);\n }\n else {\n self.log(fileContainer + \" is not a valid file container! Ignoring!\", \"warn\");\n }\n });\n\n this.log(\"Received \" + verifiedFiles.length + \" files.\");\n this._prepareItemsForUpload(verifiedFiles, params, endpoint);\n }\n },\n\n cancel: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (uploadData && uploadData.status === qq.status.UPLOAD_FINALIZING) {\n this.log(qq.format(\"Ignoring cancel for file ID {} ({}). Finalizing upload.\", id, this.getName(id)), \"error\");\n }\n else {\n this._handler.cancel(id);\n }\n },\n\n cancelAll: function() {\n var storedIdsCopy = [],\n self = this;\n\n qq.extend(storedIdsCopy, this._storedIds);\n qq.each(storedIdsCopy, function(idx, storedFileId) {\n self.cancel(storedFileId);\n });\n\n this._handler.cancelAll();\n },\n\n clearStoredFiles: function() {\n this._storedIds = [];\n },\n\n continueUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n if (uploadData.status === qq.status.PAUSED) {\n this.log(qq.format(\"Paused file ID {} ({}) will be continued. Not paused.\", id, this.getName(id)));\n this._uploadFile(id);\n return true;\n }\n else {\n this.log(qq.format(\"Ignoring continue for file ID {} ({}). Not paused.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n deleteFile: function(id) {\n return this._onSubmitDelete(id);\n },\n\n // TODO document?\n doesExist: function(fileOrBlobId) {\n return this._handler.isValid(fileOrBlobId);\n },\n\n // Generate a variable size thumbnail on an img or canvas,\n // returning a promise that is fulfilled when the attempt completes.\n // Thumbnail can either be based off of a URL for an image returned\n // by the server in the upload response, or the associated `Blob`.\n drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) {\n var promiseToReturn = new qq.Promise(),\n fileOrUrl, options;\n\n if (this._imageGenerator) {\n fileOrUrl = this._thumbnailUrls[fileId];\n options = {\n customResizeFunction: customResizeFunction,\n maxSize: maxSize > 0 ? maxSize : null,\n scale: maxSize > 0\n };\n\n // If client-side preview generation is possible\n // and we are not specifically looking for the image URl returned by the server...\n if (!fromServer && qq.supportedFeatures.imagePreviews) {\n fileOrUrl = this.getFile(fileId);\n }\n\n /* jshint eqeqeq:false,eqnull:true */\n if (fileOrUrl == null) {\n promiseToReturn.failure({container: imgOrCanvas, error: \"File or URL not found.\"});\n }\n else {\n this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(\n function success(modifiedContainer) {\n promiseToReturn.success(modifiedContainer);\n },\n\n function failure(container, reason) {\n promiseToReturn.failure({container: container, error: reason || \"Problem generating thumbnail\"});\n }\n );\n }\n }\n else {\n promiseToReturn.failure({container: imgOrCanvas, error: \"Missing image generator module\"});\n }\n\n return promiseToReturn;\n },\n\n getButton: function(fileId) {\n return this._getButton(this._buttonIdsForFileIds[fileId]);\n },\n\n getEndpoint: function(fileId) {\n return this._endpointStore.get(fileId);\n },\n\n getFile: function(fileOrBlobId) {\n var file = this._handler.getFile(fileOrBlobId);\n var uploadDataRecord;\n\n if (!file) {\n uploadDataRecord = this._uploadData.retrieve({id: fileOrBlobId});\n\n if (uploadDataRecord) {\n file = uploadDataRecord.file;\n }\n }\n\n return file || null;\n },\n\n getInProgress: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED\n ]\n }).length;\n },\n\n getName: function(id) {\n return this._uploadData.retrieve({id: id}).name;\n },\n\n // Parent ID for a specific file, or null if this is the parent, or if it has no parent.\n getParentId: function(id) {\n var uploadDataEntry = this.getUploads({id: id}),\n parentId = null;\n\n if (uploadDataEntry) {\n if (uploadDataEntry.parentId !== undefined) {\n parentId = uploadDataEntry.parentId;\n }\n }\n\n return parentId;\n },\n\n getResumableFilesData: function() {\n return this._handler.getResumableFilesData();\n },\n\n getSize: function(id) {\n return this._uploadData.retrieve({id: id}).size;\n },\n\n getNetUploads: function() {\n return this._netUploaded;\n },\n\n getRemainingAllowedItems: function() {\n var allowedItems = this._currentItemLimit;\n\n if (allowedItems > 0) {\n return allowedItems - this._netUploadedOrQueued;\n }\n\n return null;\n },\n\n getUploads: function(optionalFilter) {\n return this._uploadData.retrieve(optionalFilter);\n },\n\n getUuid: function(id) {\n return this._uploadData.retrieve({id: id}).uuid;\n },\n\n isResumable: function(id) {\n return this._handler.hasResumeRecord(id);\n },\n\n log: function(str, level) {\n if (this._options.debug && (!level || level === \"info\")) {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str);\n }\n else if (level && level !== \"info\") {\n qq.log(\"[Fine Uploader \" + qq.version + \"] \" + str, level);\n\n }\n },\n\n pauseUpload: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) {\n return false;\n }\n\n // Pause only really makes sense if the file is uploading or retrying\n if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) {\n if (this._handler.pause(id)) {\n this._uploadData.setStatus(id, qq.status.PAUSED);\n return true;\n }\n else {\n this.log(qq.format(\"Unable to pause file ID {} ({}).\", id, this.getName(id)), \"error\");\n }\n }\n else {\n this.log(qq.format(\"Ignoring pause for file ID {} ({}). Not in progress.\", id, this.getName(id)), \"error\");\n }\n\n return false;\n },\n\n removeFileRef: function(id) {\n this._handler.expunge(id);\n this._uploadData.removeFileRef(id);\n },\n\n reset: function() {\n this.log(\"Resetting uploader...\");\n\n this._handler.reset();\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n\n this._paramsStore.reset();\n this._endpointStore.reset();\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData.reset();\n this._buttonIdsForFileIds = [];\n\n this._pasteHandler && this._pasteHandler.reset();\n this._options.session.refreshOnReset && this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._totalProgress && this._totalProgress.reset();\n\n this._customResumeDataStore.reset();\n },\n\n retry: function(id) {\n return this._manualRetry(id);\n },\n\n scaleImage: function(id, specs) {\n var self = this;\n\n return qq.Scaler.prototype.scaleImage(id, specs, {\n log: qq.bind(self.log, self),\n getFile: qq.bind(self.getFile, self),\n uploadData: self._uploadData\n });\n },\n\n setCustomHeaders: function(headers, id) {\n this._customHeadersStore.set(headers, id);\n },\n\n setCustomResumeData: function(id, data) {\n this._customResumeDataStore.set(data, id);\n },\n\n setDeleteFileCustomHeaders: function(headers, id) {\n this._deleteFileCustomHeadersStore.set(headers, id);\n },\n\n setDeleteFileEndpoint: function(endpoint, id) {\n this._deleteFileEndpointStore.set(endpoint, id);\n },\n\n setDeleteFileParams: function(params, id) {\n this._deleteFileParamsStore.set(params, id);\n },\n\n // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button\n setEndpoint: function(endpoint, id) {\n this._endpointStore.set(endpoint, id);\n },\n\n setForm: function(elementOrId) {\n this._updateFormSupportAndParams(elementOrId);\n },\n\n setItemLimit: function(newItemLimit) {\n this._currentItemLimit = newItemLimit;\n },\n\n setName: function(id, newName) {\n this._uploadData.updateName(id, newName);\n },\n\n setParams: function(params, id) {\n this._paramsStore.set(params, id);\n },\n\n setUuid: function(id, newUuid) {\n return this._uploadData.uuidChanged(id, newUuid);\n },\n\n /**\n * Expose the internal status of a file id to the public api for manual state changes\n * @public\n *\n * @param {Number} id,\n * @param {String} newStatus\n *\n * @todo Implement the remaining methods\n */\n setStatus: function(id, newStatus) {\n var fileRecord = this.getUploads({id: id});\n if (!fileRecord) {\n throw new qq.Error(id + \" is not a valid file ID.\");\n }\n\n switch (newStatus) {\n case qq.status.DELETED:\n this._onDeleteComplete(id, null, false);\n break;\n case qq.status.DELETE_FAILED:\n this._onDeleteComplete(id, null, true);\n break;\n default:\n var errorMessage = \"Method setStatus called on '\" + name + \"' not implemented yet for \" + newStatus;\n this.log(errorMessage);\n throw new qq.Error(errorMessage);\n }\n },\n\n uploadStoredFiles: function() {\n if (this._storedIds.length === 0) {\n this._itemError(\"noFilesError\");\n }\n else {\n this._uploadStoredFiles();\n }\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploaderBasic mode.\n */\n qq.basePrivateApi = {\n // Updates internal state with a file record (not backed by a live file). Returns the assigned ID.\n _addCannedFile: function(sessionData) {\n var self = this;\n\n return this._uploadData.addFile({\n uuid: sessionData.uuid,\n name: sessionData.name,\n size: sessionData.size,\n status: qq.status.UPLOAD_SUCCESSFUL,\n onBeforeStatusChange: function(id) {\n sessionData.deleteFileEndpoint && self.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id);\n sessionData.deleteFileParams && self.setDeleteFileParams(sessionData.deleteFileParams, id);\n\n if (sessionData.thumbnailUrl) {\n self._thumbnailUrls[id] = sessionData.thumbnailUrl;\n }\n\n self._netUploaded++;\n self._netUploadedOrQueued++;\n }\n });\n },\n\n _annotateWithButtonId: function(file, associatedInput) {\n if (qq.isFile(file)) {\n file.qqButtonId = this._getButtonId(associatedInput);\n }\n },\n\n _batchError: function(message) {\n this._options.callbacks.onError(null, null, message, undefined);\n },\n\n _createDeleteHandler: function() {\n var self = this;\n\n return new qq.DeleteFileAjaxRequester({\n method: this._options.deleteFile.method.toUpperCase(),\n maxConnections: this._options.maxConnections,\n uuidParamName: this._options.request.uuidName,\n customHeaders: this._deleteFileCustomHeadersStore,\n paramsStore: this._deleteFileParamsStore,\n endpointStore: this._deleteFileEndpointStore,\n cors: this._options.cors,\n log: qq.bind(self.log, self),\n onDelete: function(id) {\n self._onDelete(id);\n self._options.callbacks.onDelete(id);\n },\n onDeleteComplete: function(id, xhrOrXdr, isError) {\n self._onDeleteComplete(id, xhrOrXdr, isError);\n self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError);\n }\n\n });\n },\n\n _createPasteHandler: function() {\n var self = this;\n\n return new qq.PasteSupport({\n targetElement: this._options.paste.targetElement,\n callbacks: {\n log: qq.bind(self.log, self),\n pasteReceived: function(blob) {\n self._handleCheckedCallback({\n name: \"onPasteReceived\",\n callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob),\n onSuccess: qq.bind(self._handlePasteSuccess, self, blob),\n identifier: \"pasted image\"\n });\n }\n }\n });\n },\n\n _createStore: function(initialValue, _readOnlyValues_) {\n var store = {},\n catchall = initialValue,\n perIdReadOnlyValues = {},\n readOnlyValues = _readOnlyValues_,\n copy = function(orig) {\n if (qq.isObject(orig)) {\n return qq.extend({}, orig);\n }\n return orig;\n },\n getReadOnlyValues = function() {\n if (qq.isFunction(readOnlyValues)) {\n return readOnlyValues();\n }\n return readOnlyValues;\n },\n includeReadOnlyValues = function(id, existing) {\n if (readOnlyValues && qq.isObject(existing)) {\n qq.extend(existing, getReadOnlyValues());\n }\n\n if (perIdReadOnlyValues[id]) {\n qq.extend(existing, perIdReadOnlyValues[id]);\n }\n };\n\n return {\n set: function(val, id) {\n /*jshint eqeqeq: true, eqnull: true*/\n if (id == null) {\n store = {};\n catchall = copy(val);\n }\n else {\n store[id] = copy(val);\n }\n },\n\n get: function(id) {\n var values;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (id != null && store[id]) {\n values = store[id];\n }\n else {\n values = copy(catchall);\n }\n\n includeReadOnlyValues(id, values);\n\n return copy(values);\n },\n\n addReadOnly: function(id, values) {\n // Only applicable to Object stores\n if (qq.isObject(store)) {\n // If null ID, apply readonly values to all files\n if (id === null) {\n if (qq.isFunction(values)) {\n readOnlyValues = values;\n }\n else {\n readOnlyValues = readOnlyValues || {};\n qq.extend(readOnlyValues, values);\n }\n }\n else {\n perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};\n qq.extend(perIdReadOnlyValues[id], values);\n }\n }\n },\n\n remove: function(fileId) {\n return delete store[fileId];\n },\n\n reset: function() {\n store = {};\n perIdReadOnlyValues = {};\n catchall = initialValue;\n }\n };\n },\n\n _createUploadDataTracker: function() {\n var self = this;\n\n return new qq.UploadData({\n getName: function(id) {\n return self.getName(id);\n },\n getUuid: function(id) {\n return self.getUuid(id);\n },\n getSize: function(id) {\n return self.getSize(id);\n },\n onStatusChange: function(id, oldStatus, newStatus) {\n self._onUploadStatusChange(id, oldStatus, newStatus);\n self._options.callbacks.onStatusChange(id, oldStatus, newStatus);\n self._maybeAllComplete(id, newStatus);\n\n if (self._totalProgress) {\n setTimeout(function() {\n self._totalProgress.onStatusChange(id, oldStatus, newStatus);\n }, 0);\n }\n }\n });\n },\n\n /**\n * Generate a tracked upload button.\n *\n * @param spec Object containing a required `element` property\n * along with optional `multiple`, `accept`, and `folders`.\n * @returns {qq.UploadButton}\n * @private\n */\n _createUploadButton: function(spec) {\n var self = this,\n acceptFiles = spec.accept || this._options.validation.acceptFiles,\n allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions,\n button;\n\n function allowMultiple() {\n if (qq.supportedFeatures.ajaxUploading) {\n // Workaround for bug in iOS7+ (see #1039)\n if (self._options.workarounds.iosEmptyVideos &&\n qq.ios() &&\n !qq.ios6() &&\n self._isAllowedExtension(allowedExtensions, \".mov\")) {\n\n return false;\n }\n\n if (spec.multiple === undefined) {\n return self._options.multiple;\n }\n\n return spec.multiple;\n }\n\n return false;\n }\n\n button = new qq.UploadButton({\n acceptFiles: acceptFiles,\n element: spec.element,\n focusClass: this._options.classes.buttonFocus,\n folders: spec.folders,\n hoverClass: this._options.classes.buttonHover,\n ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash,\n multiple: allowMultiple(),\n name: this._options.request.inputName,\n onChange: function(input) {\n self._onInputChange(input);\n },\n title: spec.title == null ? this._options.text.fileInputTitle : spec.title\n });\n\n this._disposeSupport.addDisposer(function() {\n button.dispose();\n });\n\n self._buttons.push(button);\n\n return button;\n },\n\n _createUploadHandler: function(additionalOptions, namespace) {\n var self = this,\n lastOnProgress = {},\n options = {\n debug: this._options.debug,\n maxConnections: this._options.maxConnections,\n cors: this._options.cors,\n paramsStore: this._paramsStore,\n endpointStore: this._endpointStore,\n chunking: this._options.chunking,\n resume: this._options.resume,\n blobs: this._options.blobs,\n log: qq.bind(self.log, self),\n preventRetryParam: this._options.retry.preventRetryResponseProperty,\n onProgress: function(id, name, loaded, total) {\n if (loaded < 0 || total < 0) {\n return;\n }\n\n if (lastOnProgress[id]) {\n if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n }\n else {\n self._onProgress(id, name, loaded, total);\n self._options.callbacks.onProgress(id, name, loaded, total);\n }\n\n lastOnProgress[id] = {loaded: loaded, total: total};\n\n },\n onComplete: function(id, name, result, xhr) {\n delete lastOnProgress[id];\n\n var status = self.getUploads({id: id}).status,\n retVal;\n\n // This is to deal with some observed cases where the XHR readyStateChange handler is\n // invoked by the browser multiple times for the same XHR instance with the same state\n // readyState value. Higher level: don't invoke complete-related code if we've already\n // done this.\n if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) {\n return;\n }\n\n retVal = self._onComplete(id, name, result, xhr);\n\n // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback\n // until the promise has been fulfilled.\n if (retVal instanceof qq.Promise) {\n retVal.done(function() {\n self._options.callbacks.onComplete(id, name, result, xhr);\n });\n }\n else {\n self._options.callbacks.onComplete(id, name, result, xhr);\n }\n },\n onCancel: function(id, name, cancelFinalizationEffort) {\n var promise = new qq.Promise();\n\n self._handleCheckedCallback({\n name: \"onCancel\",\n callback: qq.bind(self._options.callbacks.onCancel, self, id, name),\n onFailure: promise.failure,\n onSuccess: function() {\n cancelFinalizationEffort.then(function() {\n self._onCancel(id, name);\n });\n\n promise.success();\n },\n identifier: id\n });\n\n return promise;\n },\n onUploadPrep: qq.bind(this._onUploadPrep, this),\n onUpload: function(id, name) {\n self._onUpload(id, name);\n var onUploadResult = self._options.callbacks.onUpload(id, name);\n\n if (qq.isGenericPromise(onUploadResult)) {\n self.log(qq.format(\"onUpload for {} returned a Promise - waiting for resolution.\", id));\n return onUploadResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunk: function(id, name, chunkData) {\n self._onUploadChunk(id, chunkData);\n var onUploadChunkResult = self._options.callbacks.onUploadChunk(id, name, chunkData);\n\n if (qq.isGenericPromise(onUploadChunkResult)) {\n self.log(qq.format(\"onUploadChunk for {}.{} returned a Promise - waiting for resolution.\", id, chunkData.partIndex));\n return onUploadChunkResult;\n }\n\n return new qq.Promise().success();\n },\n onUploadChunkSuccess: function(id, chunkData, result, xhr) {\n self._onUploadChunkSuccess(id, chunkData);\n self._options.callbacks.onUploadChunkSuccess.apply(self, arguments);\n },\n onResume: function(id, name, chunkData, customResumeData) {\n return self._options.callbacks.onResume(id, name, chunkData, customResumeData);\n },\n onAutoRetry: function(id, name, responseJSON, xhr) {\n return self._onAutoRetry.apply(self, arguments);\n },\n onUuidChanged: function(id, newUuid) {\n self.log(\"Server requested UUID change from '\" + self.getUuid(id) + \"' to '\" + newUuid + \"'\");\n self.setUuid(id, newUuid);\n },\n getName: qq.bind(self.getName, self),\n getUuid: qq.bind(self.getUuid, self),\n getSize: qq.bind(self.getSize, self),\n setSize: qq.bind(self._setSize, self),\n getDataByUuid: function(uuid) {\n return self.getUploads({uuid: uuid});\n },\n isQueued: function(id) {\n var status = self.getUploads({id: id}).status;\n return status === qq.status.QUEUED ||\n status === qq.status.SUBMITTED ||\n status === qq.status.UPLOAD_RETRYING ||\n status === qq.status.PAUSED;\n },\n getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup,\n getIdsInBatch: self._uploadData.getIdsInBatch,\n isInProgress: function(id) {\n return self.getUploads({id: id}).status === qq.status.UPLOADING;\n },\n getCustomResumeData: qq.bind(self._getCustomResumeData, self),\n setStatus: function(id, status) {\n self._uploadData.setStatus(id, status);\n }\n };\n\n qq.each(this._options.request, function(prop, val) {\n options[prop] = val;\n });\n\n options.customHeaders = this._customHeadersStore;\n\n if (additionalOptions) {\n qq.each(additionalOptions, function(key, val) {\n options[key] = val;\n });\n }\n\n return new qq.UploadHandlerController(options, namespace);\n },\n\n _fileOrBlobRejected: function(id) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.REJECTED);\n },\n\n _formatSize: function(bytes) {\n if (bytes === 0) {\n return bytes + this._options.text.sizeSymbols[0];\n }\n var i = -1;\n do {\n bytes = bytes / 1000;\n i++;\n } while (bytes > 999);\n\n return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i];\n },\n\n // Creates an internal object that tracks various properties of each extra button,\n // and then actually creates the extra button.\n _generateExtraButtonSpecs: function() {\n var self = this;\n\n this._extraButtonSpecs = {};\n\n qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) {\n var multiple = extraButtonOptionEntry.multiple,\n validation = qq.extend({}, self._options.validation, true),\n extraButtonSpec = qq.extend({}, extraButtonOptionEntry);\n\n if (multiple === undefined) {\n multiple = self._options.multiple;\n }\n\n if (extraButtonSpec.validation) {\n qq.extend(validation, extraButtonOptionEntry.validation, true);\n }\n\n qq.extend(extraButtonSpec, {\n multiple: multiple,\n validation: validation\n }, true);\n\n self._initExtraButton(extraButtonSpec);\n });\n },\n\n _getButton: function(buttonId) {\n var extraButtonsSpec = this._extraButtonSpecs[buttonId];\n\n if (extraButtonsSpec) {\n return extraButtonsSpec.element;\n }\n else if (buttonId === this._defaultButtonId) {\n return this._options.button;\n }\n },\n\n /**\n * Gets the internally used tracking ID for a button.\n *\n * @param buttonOrFileInputOrFile `File`, ``, or a button container element\n * @returns {*} The button's ID, or undefined if no ID is recoverable\n * @private\n */\n _getButtonId: function(buttonOrFileInputOrFile) {\n var inputs, fileInput,\n fileBlobOrInput = buttonOrFileInputOrFile;\n\n // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later)\n if (fileBlobOrInput instanceof qq.BlobProxy) {\n fileBlobOrInput = fileBlobOrInput.referenceBlob;\n }\n\n // If the item is a `Blob` it will never be associated with a button or drop zone.\n if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) {\n if (qq.isFile(fileBlobOrInput)) {\n return fileBlobOrInput.qqButtonId;\n }\n else if (fileBlobOrInput.tagName.toLowerCase() === \"input\" &&\n fileBlobOrInput.type.toLowerCase() === \"file\") {\n\n return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n\n inputs = fileBlobOrInput.getElementsByTagName(\"input\");\n\n qq.each(inputs, function(idx, input) {\n if (input.getAttribute(\"type\") === \"file\") {\n fileInput = input;\n return false;\n }\n });\n\n if (fileInput) {\n return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);\n }\n }\n },\n\n _getCustomResumeData: function(fileId) {\n return this._customResumeDataStore.get(fileId);\n },\n\n _getNotFinished: function() {\n return this._uploadData.retrieve({\n status: [\n qq.status.UPLOADING,\n qq.status.UPLOAD_RETRYING,\n qq.status.QUEUED,\n qq.status.SUBMITTING,\n qq.status.SUBMITTED,\n qq.status.PAUSED\n ]\n }).length;\n },\n\n // Get the validation options for this button. Could be the default validation option\n // or a specific one assigned to this particular button.\n _getValidationBase: function(buttonId) {\n var extraButtonSpec = this._extraButtonSpecs[buttonId];\n\n return extraButtonSpec ? extraButtonSpec.validation : this._options.validation;\n },\n\n _getValidationDescriptor: function(fileWrapper) {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return {\n name: qq.getFilename(fileWrapper.file.referenceBlob),\n size: fileWrapper.file.referenceBlob.size\n };\n }\n\n return {\n name: this.getUploads({id: fileWrapper.id}).name,\n size: this.getUploads({id: fileWrapper.id}).size\n };\n },\n\n _getValidationDescriptors: function(fileWrappers) {\n var self = this,\n fileDescriptors = [];\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n fileDescriptors.push(self._getValidationDescriptor(fileWrapper));\n });\n\n return fileDescriptors;\n },\n\n // Allows camera access on either the default or an extra button for iOS devices.\n _handleCameraAccess: function() {\n if (this._options.camera.ios && qq.ios()) {\n var acceptIosCamera = \"image/*;capture=camera\",\n button = this._options.camera.button,\n buttonId = button ? this._getButtonId(button) : this._defaultButtonId,\n optionRoot = this._options;\n\n // If we are not targeting the default button, it is an \"extra\" button\n if (buttonId && buttonId !== this._defaultButtonId) {\n optionRoot = this._extraButtonSpecs[buttonId];\n }\n\n // Camera access won't work in iOS if the `multiple` attribute is present on the file input\n optionRoot.multiple = false;\n\n // update the options\n if (optionRoot.validation.acceptFiles === null) {\n optionRoot.validation.acceptFiles = acceptIosCamera;\n }\n else {\n optionRoot.validation.acceptFiles += \",\" + acceptIosCamera;\n }\n\n // update the already-created button\n qq.each(this._buttons, function(idx, button) {\n if (button.getButtonId() === buttonId) {\n button.setMultiple(optionRoot.multiple);\n button.setAcceptFiles(optionRoot.acceptFiles);\n\n return false;\n }\n });\n }\n },\n\n _handleCheckedCallback: function(details) {\n var self = this,\n callbackRetVal = details.callback();\n\n if (qq.isGenericPromise(callbackRetVal)) {\n this.log(details.name + \" - waiting for \" + details.name + \" promise to be fulfilled for \" + details.identifier);\n return callbackRetVal.then(\n function(successParam) {\n self.log(details.name + \" promise success for \" + details.identifier);\n details.onSuccess(successParam);\n },\n function() {\n if (details.onFailure) {\n self.log(details.name + \" promise failure for \" + details.identifier);\n details.onFailure();\n }\n else {\n self.log(details.name + \" promise failure for \" + details.identifier);\n }\n });\n }\n\n if (callbackRetVal !== false) {\n details.onSuccess(callbackRetVal);\n }\n else {\n if (details.onFailure) {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Invoking failure callback.\");\n details.onFailure();\n }\n else {\n this.log(details.name + \" - return value was 'false' for \" + details.identifier + \". Will not proceed.\");\n }\n }\n\n return callbackRetVal;\n },\n\n // Updates internal state when a new file has been received, and adds it along with its ID to a passed array.\n _handleNewFile: function(file, batchId, newFileWrapperList) {\n var self = this,\n uuid = qq.getUniqueId(),\n size = -1,\n name = qq.getFilename(file),\n actualFile = file.blob || file,\n handler = this._customNewFileHandler ?\n this._customNewFileHandler :\n qq.bind(self._handleNewFileGeneric, self);\n\n if (!qq.isInput(actualFile) && actualFile.size >= 0) {\n size = actualFile.size;\n }\n\n handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, {\n uploadData: self._uploadData,\n paramsStore: self._paramsStore,\n addFileToHandler: function(id, file) {\n self._handler.add(id, file);\n self._netUploadedOrQueued++;\n self._trackButton(id);\n }\n });\n },\n\n _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) {\n var id = this._uploadData.addFile({\n uuid: uuid,\n name: name,\n size: size,\n batchId: batchId,\n file: file\n });\n\n this._handler.add(id, file);\n\n this._trackButton(id);\n\n this._netUploadedOrQueued++;\n\n fileList.push({id: id, file: file});\n },\n\n _handlePasteSuccess: function(blob, extSuppliedName) {\n var extension = blob.type.split(\"/\")[1],\n name = extSuppliedName;\n\n /*jshint eqeqeq: true, eqnull: true*/\n if (name == null) {\n name = this._options.paste.defaultName;\n }\n\n name += \".\" + extension;\n\n this.addFiles({\n name: name,\n blob: blob\n });\n },\n\n _handleDeleteSuccess: function(id) {\n if (this.getUploads({id: id}).status !== qq.status.DELETED) {\n var name = this.getName(id);\n\n this._netUploadedOrQueued--;\n this._netUploaded--;\n this._handler.expunge(id);\n this._uploadData.setStatus(id, qq.status.DELETED);\n this.log(\"Delete request for '\" + name + \"' has succeeded.\");\n }\n },\n\n _handleDeleteFailed: function(id, xhrOrXdr) {\n var name = this.getName(id);\n\n this._uploadData.setStatus(id, qq.status.DELETE_FAILED);\n this.log(\"Delete request for '\" + name + \"' has failed.\", \"error\");\n\n // Check first if xhrOrXdr is actually passed or valid\n // For error reporting, we only have access to the response status if this is not\n // an `XDomainRequest`.\n if (!xhrOrXdr || xhrOrXdr.withCredentials === undefined) {\n this._options.callbacks.onError(id, name, \"Delete request failed\", xhrOrXdr);\n }\n else {\n this._options.callbacks.onError(id, name, \"Delete request failed with response code \" + xhrOrXdr.status, xhrOrXdr);\n }\n },\n\n // Creates an extra button element\n _initExtraButton: function(spec) {\n var button = this._createUploadButton({\n accept: spec.validation.acceptFiles,\n allowedExtensions: spec.validation.allowedExtensions,\n element: spec.element,\n folders: spec.folders,\n multiple: spec.multiple,\n title: spec.fileInputTitle\n });\n\n this._extraButtonSpecs[button.getButtonId()] = spec;\n },\n\n _initFormSupportAndParams: function() {\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore = this._createStore(\n this._options.request.params, this._formSupport.getFormInputsAsObject\n );\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this._options.request.endpoint = this._formSupport.newEndpoint;\n }\n }\n else {\n this._paramsStore = this._createStore(this._options.request.params);\n }\n },\n\n _isDeletePossible: function() {\n if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) {\n return false;\n }\n\n if (this._options.cors.expected) {\n if (qq.supportedFeatures.deleteFileCorsXhr) {\n return true;\n }\n\n if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) {\n return true;\n }\n\n return false;\n }\n\n return true;\n },\n\n _isAllowedExtension: function(allowed, fileName) {\n var valid = false;\n\n if (!allowed.length) {\n return true;\n }\n\n qq.each(allowed, function(idx, allowedExt) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExt)) {\n /*jshint eqeqeq: true, eqnull: true*/\n var extRegex = new RegExp(\"\\\\.\" + allowedExt + \"$\", \"i\");\n\n if (fileName.match(extRegex) != null) {\n valid = true;\n return false;\n }\n }\n });\n\n return valid;\n },\n\n /**\n * Constructs and returns a message that describes an item/file error. Also calls `onError` callback.\n *\n * @param code REQUIRED - a code that corresponds to a stock message describing this type of error\n * @param maybeNameOrNames names of the items that have failed, if applicable\n * @param item `File`, `Blob`, or ``\n * @private\n */\n _itemError: function(code, maybeNameOrNames, item) {\n var message = this._options.messages[code],\n allowedExtensions = [],\n names = [].concat(maybeNameOrNames),\n name = names[0],\n buttonId = this._getButtonId(item),\n validationBase = this._getValidationBase(buttonId),\n extensionsForMessage, placeholderMatch;\n\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) {\n /**\n * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the\n * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details.\n */\n if (qq.isString(allowedExtension)) {\n allowedExtensions.push(allowedExtension);\n }\n });\n\n extensionsForMessage = allowedExtensions.join(\", \").toLowerCase();\n\n r(\"{file}\", this._options.formatFileName(name));\n r(\"{extensions}\", extensionsForMessage);\n r(\"{sizeLimit}\", this._formatSize(validationBase.sizeLimit));\n r(\"{minSizeLimit}\", this._formatSize(validationBase.minSizeLimit));\n\n placeholderMatch = message.match(/(\\{\\w+\\})/g);\n if (placeholderMatch !== null) {\n qq.each(placeholderMatch, function(idx, placeholder) {\n r(placeholder, names[idx]);\n });\n }\n\n this._options.callbacks.onError(null, name, message, undefined);\n\n return message;\n },\n\n /**\n * Conditionally orders a manual retry of a failed upload.\n *\n * @param id File ID of the failed upload\n * @param callback Optional callback to invoke if a retry is prudent.\n * In lieu of asking the upload handler to retry.\n * @returns {boolean} true if a manual retry will occur\n * @private\n */\n _manualRetry: function(id, callback) {\n if (this._onBeforeManualRetry(id)) {\n this._netUploadedOrQueued++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n\n if (callback) {\n callback(id);\n }\n else {\n this._handler.retry(id);\n }\n\n return true;\n }\n },\n\n _maybeAllComplete: function(id, status) {\n var self = this,\n notFinished = this._getNotFinished();\n\n if (status === qq.status.UPLOAD_SUCCESSFUL) {\n this._succeededSinceLastAllComplete.push(id);\n }\n else if (status === qq.status.UPLOAD_FAILED) {\n this._failedSinceLastAllComplete.push(id);\n }\n\n if (notFinished === 0 &&\n (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) {\n // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete\n setTimeout(function() {\n self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete);\n }, 0);\n }\n },\n\n _maybeHandleIos8SafariWorkaround: function() {\n var self = this;\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n setTimeout(function() {\n window.alert(self._options.messages.unsupportedBrowserIos8Safari);\n }, 0);\n throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari);\n }\n },\n\n _maybeParseAndSendUploadError: function(id, name, response, xhr) {\n // Assuming no one will actually set the response code to something other than 200\n // and still set 'success' to true...\n if (!response.success) {\n if (xhr && xhr.status !== 200 && !response.error) {\n this._options.callbacks.onError(id, name, \"XHR returned response code \" + xhr.status, xhr);\n }\n else {\n var errorReason = response.error ? response.error : this._options.text.defaultResponseError;\n this._options.callbacks.onError(id, name, errorReason, xhr);\n }\n }\n },\n\n _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) {\n var self = this;\n\n if (items.length > index) {\n if (validItem || !this._options.validation.stopOnFirstInvalidFile) {\n //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks\n setTimeout(function() {\n var validationDescriptor = self._getValidationDescriptor(items[index]),\n buttonId = self._getButtonId(items[index].file),\n button = self._getButton(buttonId);\n\n self._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button),\n onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint),\n onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint),\n identifier: \"Item '\" + validationDescriptor.name + \"', size: \" + validationDescriptor.size\n });\n }, 0);\n }\n else if (!validItem) {\n for (; index < items.length; index++) {\n self._fileOrBlobRejected(items[index].id);\n }\n }\n }\n },\n\n _onAllComplete: function(successful, failed) {\n this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries);\n\n this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed));\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n },\n\n /**\n * Attempt to automatically retry a failed upload.\n *\n * @param id The file ID of the failed upload\n * @param name The name of the file associated with the failed upload\n * @param responseJSON Response from the server, parsed into a javascript object\n * @param xhr Ajax transport used to send the failed request\n * @param callback Optional callback to be invoked if a retry is prudent.\n * Invoked in lieu of asking the upload handler to retry.\n * @returns {boolean} true if an auto-retry will occur\n * @private\n */\n _onAutoRetry: function(id, name, responseJSON, xhr, callback) {\n var self = this;\n\n self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];\n\n if (self._shouldAutoRetry(id)) {\n var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1000;\n\n self._maybeParseAndSendUploadError.apply(self, arguments);\n self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]);\n self._onBeforeAutoRetry(id, name);\n\n self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING);\n self._retryTimeouts[id] = setTimeout(function() {\n self.log(\"Starting retry for \" + name + \"...\");\n\n if (callback) {\n callback(id);\n }\n else {\n self._handler.retry(id);\n }\n }, retryWaitPeriod);\n\n return true;\n }\n },\n\n _onBeforeAutoRetry: function(id, name) {\n this.log(\"Waiting \" + this._options.retry.autoAttemptDelay + \" seconds before retrying \" + name + \"...\");\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n var itemLimit = this._currentItemLimit,\n fileName;\n\n if (this._preventRetries[id]) {\n this.log(\"Retries are forbidden for id \" + id, \"warn\");\n return false;\n }\n else if (this._handler.isValid(id)) {\n fileName = this.getName(id);\n\n if (this._options.callbacks.onManualRetry(id, fileName) === false) {\n return false;\n }\n\n if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) {\n this._itemError(\"retryFailTooManyItems\");\n return false;\n }\n\n this.log(\"Retrying upload for '\" + fileName + \"' (id: \" + id + \")...\");\n return true;\n }\n else {\n this.log(\"'\" + id + \"' is not a valid file ID\", \"error\");\n return false;\n }\n },\n\n _onCancel: function(id, name) {\n this._netUploadedOrQueued--;\n\n clearTimeout(this._retryTimeouts[id]);\n\n var storedItemIndex = qq.indexOf(this._storedIds, id);\n if (!this._options.autoUpload && storedItemIndex >= 0) {\n this._storedIds.splice(storedItemIndex, 1);\n }\n\n this._uploadData.setStatus(id, qq.status.CANCELED);\n },\n\n _onComplete: function(id, name, result, xhr) {\n if (!result.success) {\n this._netUploadedOrQueued--;\n this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED);\n\n if (result[this._options.retry.preventRetryResponseProperty] === true) {\n this._preventRetries[id] = true;\n }\n }\n else {\n if (result.thumbnailUrl) {\n this._thumbnailUrls[id] = result.thumbnailUrl;\n }\n\n this._netUploaded++;\n this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL);\n }\n\n this._maybeParseAndSendUploadError(id, name, result, xhr);\n\n return result.success ? true : false;\n },\n\n _onDelete: function(id) {\n this._uploadData.setStatus(id, qq.status.DELETING);\n },\n\n _onDeleteComplete: function(id, xhrOrXdr, isError) {\n var name = this.getName(id);\n\n if (isError) {\n this._handleDeleteFailed(id, xhrOrXdr);\n }\n else {\n this._handleDeleteSuccess(id);\n }\n },\n\n _onInputChange: function(input) {\n var fileIndex;\n\n if (qq.supportedFeatures.ajaxUploading) {\n for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) {\n this._annotateWithButtonId(input.files[fileIndex], input);\n }\n\n this.addFiles(input.files);\n }\n // Android 2.3.x will fire `onchange` even if no file has been selected\n else if (input.value.length > 0) {\n this.addFiles(input);\n }\n\n qq.each(this._buttons, function(idx, button) {\n button.reset();\n });\n },\n\n _onProgress: function(id, name, loaded, total) {\n this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total);\n },\n\n _onSubmit: function(id, name) {\n //nothing to do yet in core uploader\n },\n\n _onSubmitCallbackSuccess: function(id, name) {\n this._onSubmit.apply(this, arguments);\n this._uploadData.setStatus(id, qq.status.SUBMITTED);\n this._onSubmitted.apply(this, arguments);\n\n if (this._options.autoUpload) {\n this._options.callbacks.onSubmitted.apply(this, arguments);\n this._uploadFile(id);\n }\n else {\n this._storeForLater(id);\n this._options.callbacks.onSubmitted.apply(this, arguments);\n }\n },\n\n _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) {\n var uuid = this.getUuid(id),\n adjustedOnSuccessCallback;\n\n if (onSuccessCallback) {\n adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams);\n }\n\n if (this._isDeletePossible()) {\n this._handleCheckedCallback({\n name: \"onSubmitDelete\",\n callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id),\n onSuccess: adjustedOnSuccessCallback ||\n qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams),\n identifier: id\n });\n return true;\n }\n else {\n this.log(\"Delete request ignored for ID \" + id + \", delete feature is disabled or request not possible \" +\n \"due to CORS on a user agent that does not support pre-flighting.\", \"warn\");\n return false;\n }\n },\n\n _onSubmitted: function(id) {\n //nothing to do in the base uploader\n },\n\n _onTotalProgress: function(loaded, total) {\n this._options.callbacks.onTotalProgress(loaded, total);\n },\n\n _onUploadPrep: function(id) {\n // nothing to do in the core uploader for now\n },\n\n _onUpload: function(id, name) {\n this._uploadData.setStatus(id, qq.status.UPLOADING);\n },\n\n _onUploadChunk: function(id, chunkData) {\n //nothing to do in the base uploader\n },\n\n _onUploadChunkSuccess: function(id, chunkData) {\n if (!this._preventRetries[id] && this._options.retry.enableAuto) {\n this._autoRetries[id] = 0;\n }\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n // Make sure a \"queued\" retry attempt is canceled if the upload has been paused\n if (newStatus === qq.status.PAUSED) {\n clearTimeout(this._retryTimeouts[id]);\n }\n },\n\n _onValidateBatchCallbackFailure: function(fileWrappers) {\n var self = this;\n\n qq.each(fileWrappers, function(idx, fileWrapper) {\n self._fileOrBlobRejected(fileWrapper.id);\n });\n },\n\n _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) {\n var errorMessage,\n itemLimit = this._currentItemLimit,\n proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued;\n\n if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) {\n if (items.length > 0) {\n this._handleCheckedCallback({\n name: \"onValidate\",\n callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button),\n onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint),\n onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint),\n identifier: \"Item '\" + items[0].file.name + \"', size: \" + items[0].file.size\n });\n }\n else {\n this._itemError(\"noFilesError\");\n }\n }\n else {\n this._onValidateBatchCallbackFailure(items);\n errorMessage = this._options.messages.tooManyItemsError\n .replace(/\\{netItems\\}/g, proposedNetFilesUploadedOrQueued)\n .replace(/\\{itemLimit\\}/g, itemLimit);\n this._batchError(errorMessage);\n }\n },\n\n _onValidateCallbackFailure: function(items, index, params, endpoint) {\n var nextIndex = index + 1;\n\n this._fileOrBlobRejected(items[index].id, items[index].file.name);\n\n this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n },\n\n _onValidateCallbackSuccess: function(items, index, params, endpoint) {\n var self = this,\n nextIndex = index + 1,\n validationDescriptor = this._getValidationDescriptor(items[index]);\n\n this._validateFileOrBlobData(items[index], validationDescriptor)\n .then(\n function() {\n self._upload(items[index].id, params, endpoint);\n self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint);\n },\n function() {\n self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint);\n }\n );\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n if (items.length === 0) {\n this._itemError(\"noFilesError\");\n return;\n }\n\n var validationDescriptors = this._getValidationDescriptors(items),\n buttonId = this._getButtonId(items[0].file),\n button = this._getButton(buttonId);\n\n this._handleCheckedCallback({\n name: \"onValidateBatch\",\n callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button),\n onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button),\n onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items),\n identifier: \"batch validation\"\n });\n },\n\n _preventLeaveInProgress: function() {\n var self = this;\n\n this._disposeSupport.attach(window, \"beforeunload\", function(e) {\n if (self.getInProgress()) {\n e = e || window.event;\n // for ie, ff\n e.returnValue = self._options.messages.onLeave;\n // for webkit\n return self._options.messages.onLeave;\n }\n });\n },\n\n // Attempts to refresh session data only if the `qq.Session` module exists\n // and a session endpoint has been specified. The `onSessionRequestComplete`\n // callback will be invoked once the refresh is complete.\n _refreshSessionData: function() {\n var self = this,\n options = this._options.session;\n\n /* jshint eqnull:true */\n if (qq.Session && this._options.session.endpoint != null) {\n if (!this._session) {\n qq.extend(options, {cors: this._options.cors});\n\n options.log = qq.bind(this.log, this);\n options.addFileRecord = qq.bind(this._addCannedFile, this);\n\n this._session = new qq.Session(options);\n }\n\n setTimeout(function() {\n self._session.refresh().then(function(response, xhrOrXdr) {\n self._sessionRequestComplete();\n self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);\n\n }, function(response, xhrOrXdr) {\n\n self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);\n });\n }, 0);\n }\n },\n\n _sessionRequestComplete: function() {},\n\n _setSize: function(id, newSize) {\n this._uploadData.updateSize(id, newSize);\n this._totalProgress && this._totalProgress.onNewSize(id);\n },\n\n _shouldAutoRetry: function(id) {\n var uploadData = this._uploadData.retrieve({id: id});\n\n /*jshint laxbreak: true */\n if (!this._preventRetries[id]\n && this._options.retry.enableAuto\n && uploadData.status !== qq.status.PAUSED) {\n\n if (this._autoRetries[id] === undefined) {\n this._autoRetries[id] = 0;\n }\n\n if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) {\n this._autoRetries[id] += 1;\n return true;\n }\n }\n\n return false;\n },\n\n _storeForLater: function(id) {\n this._storedIds.push(id);\n },\n\n // Maps a file with the button that was used to select it.\n _trackButton: function(id) {\n var buttonId;\n\n if (qq.supportedFeatures.ajaxUploading) {\n buttonId = this._handler.getFile(id).qqButtonId;\n }\n else {\n buttonId = this._getButtonId(this._handler.getInput(id));\n }\n\n if (buttonId) {\n this._buttonIdsForFileIds[id] = buttonId;\n }\n },\n\n _updateFormSupportAndParams: function(formElementOrId) {\n this._options.form.element = formElementOrId;\n\n this._formSupport = qq.FormSupport && new qq.FormSupport(\n this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)\n );\n\n if (this._formSupport && this._formSupport.attachedToForm) {\n this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);\n\n this._options.autoUpload = this._formSupport.newAutoUpload;\n if (this._formSupport.newEndpoint) {\n this.setEndpoint(this._formSupport.newEndpoint);\n }\n }\n },\n\n _upload: function(id, params, endpoint) {\n var name = this.getName(id);\n\n if (params) {\n this.setParams(params, id);\n }\n\n if (endpoint) {\n this.setEndpoint(endpoint, id);\n }\n\n this._handleCheckedCallback({\n name: \"onSubmit\",\n callback: qq.bind(this._options.callbacks.onSubmit, this, id, name),\n onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name),\n onFailure: qq.bind(this._fileOrBlobRejected, this, id, name),\n identifier: id\n });\n },\n\n _uploadFile: function(id) {\n if (!this._handler.upload(id)) {\n this._uploadData.setStatus(id, qq.status.QUEUED);\n }\n },\n\n _uploadStoredFiles: function() {\n var idToUpload, stillSubmitting,\n self = this;\n\n while (this._storedIds.length) {\n idToUpload = this._storedIds.shift();\n this._uploadFile(idToUpload);\n }\n\n // If we are still waiting for some files to clear validation, attempt to upload these again in a bit\n stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;\n if (stillSubmitting) {\n qq.log(\"Still waiting for \" + stillSubmitting + \" files to clear submit queue. Will re-parse stored IDs array shortly.\");\n setTimeout(function() {\n self._uploadStoredFiles();\n }, 1000);\n }\n },\n\n /**\n * Performs some internal validation checks on an item, defined in the `validation` option.\n *\n * @param fileWrapper Wrapper containing a `file` along with an `id`\n * @param validationDescriptor Normalized information about the item (`size`, `name`).\n * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file\n * @private\n */\n _validateFileOrBlobData: function(fileWrapper, validationDescriptor) {\n var self = this,\n file = (function() {\n if (fileWrapper.file instanceof qq.BlobProxy) {\n return fileWrapper.file.referenceBlob;\n }\n return fileWrapper.file;\n }()),\n name = validationDescriptor.name,\n size = validationDescriptor.size,\n buttonId = this._getButtonId(fileWrapper.file),\n validationBase = this._getValidationBase(buttonId),\n validityChecker = new qq.Promise();\n\n validityChecker.then(\n function() {},\n function() {\n self._fileOrBlobRejected(fileWrapper.id, name);\n });\n\n if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) {\n this._itemError(\"typeError\", name, file);\n return validityChecker.failure();\n }\n\n if (!this._options.validation.allowEmpty && size === 0) {\n this._itemError(\"emptyError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) {\n this._itemError(\"sizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (size > 0 && size < validationBase.minSizeLimit) {\n this._itemError(\"minSizeError\", name, file);\n return validityChecker.failure();\n }\n\n if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) {\n new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(\n validityChecker.success,\n function(errorCode) {\n self._itemError(errorCode + \"ImageError\", name, file);\n validityChecker.failure();\n }\n );\n }\n else {\n validityChecker.success();\n }\n\n return validityChecker;\n },\n\n _wrapCallbacks: function() {\n var self, safeCallback, prop;\n\n self = this;\n\n safeCallback = function(name, callback, args) {\n var errorMsg;\n\n try {\n return callback.apply(self, args);\n }\n catch (exception) {\n errorMsg = exception.message || exception.toString();\n self.log(\"Caught exception in '\" + name + \"' callback - \" + errorMsg, \"error\");\n }\n };\n\n /* jshint forin: false, loopfunc: true */\n for (prop in this._options.callbacks) {\n (function() {\n var callbackName, callbackFunc;\n callbackName = prop;\n callbackFunc = self._options.callbacks[callbackName];\n self._options.callbacks[callbackName] = function() {\n return safeCallback(callbackName, callbackFunc, arguments);\n };\n }());\n }\n }\n };\n}());\n","/*globals qq*/\n(function() {\n \"use strict\";\n\n qq.FineUploaderBasic = function(o) {\n var self = this;\n\n // These options define FineUploaderBasic mode.\n this._options = {\n debug: false,\n button: null,\n multiple: true,\n maxConnections: 3,\n disableCancelForFormUploads: false,\n autoUpload: true,\n warnBeforeUnload: true,\n\n request: {\n customHeaders: {},\n endpoint: \"/server/upload\",\n filenameParam: \"qqfilename\",\n forceMultipart: true,\n inputName: \"qqfile\",\n method: \"POST\",\n omitDefaultParams: false,\n params: {},\n paramsInBody: true,\n requireSuccessJson: true,\n totalFileSizeName: \"qqtotalfilesize\",\n uuidName: \"qquuid\"\n },\n\n validation: {\n allowedExtensions: [],\n sizeLimit: 0,\n minSizeLimit: 0,\n itemLimit: 0,\n stopOnFirstInvalidFile: true,\n acceptFiles: null,\n image: {\n maxHeight: 0,\n maxWidth: 0,\n minHeight: 0,\n minWidth: 0\n },\n allowEmpty: false\n },\n\n callbacks: {\n onSubmit: function(id, name) {},\n onSubmitted: function(id, name) {},\n onComplete: function(id, name, responseJSON, maybeXhr) {},\n onAllComplete: function(successful, failed) {},\n onCancel: function(id, name) {},\n onUpload: function(id, name) {},\n onUploadChunk: function(id, name, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onProgress: function(id, name, loaded, total) {},\n onTotalProgress: function(loaded, total) {},\n onError: function(id, name, reason, maybeXhrOrXdr) {},\n onAutoRetry: function(id, name, attemptNumber) {},\n onManualRetry: function(id, name) {},\n onValidateBatch: function(fileOrBlobData) {},\n onValidate: function(fileOrBlobData) {},\n onSubmitDelete: function(id) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {},\n onPasteReceived: function(blob) {},\n onStatusChange: function(id, oldStatus, newStatus) {},\n onSessionRequestComplete: function(response, success, xhrOrXdr) {}\n },\n\n messages: {\n typeError: \"{file} has an invalid extension. Valid extension(s): {extensions}.\",\n sizeError: \"{file} is too large, maximum file size is {sizeLimit}.\",\n minSizeError: \"{file} is too small, minimum file size is {minSizeLimit}.\",\n emptyError: \"{file} is empty, please select files again without it.\",\n noFilesError: \"No files to upload.\",\n tooManyItemsError: \"Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.\",\n maxHeightImageError: \"Image is too tall.\",\n maxWidthImageError: \"Image is too wide.\",\n minHeightImageError: \"Image is not tall enough.\",\n minWidthImageError: \"Image is not wide enough.\",\n retryFailTooManyItems: \"Retry failed - you have reached your file limit.\",\n onLeave: \"The files are being uploaded, if you leave now the upload will be canceled.\",\n unsupportedBrowserIos8Safari: \"Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues.\"\n },\n\n retry: {\n enableAuto: false,\n maxAutoAttempts: 3,\n autoAttemptDelay: 5,\n preventRetryResponseProperty: \"preventRetry\"\n },\n\n classes: {\n buttonHover: \"qq-upload-button-hover\",\n buttonFocus: \"qq-upload-button-focus\"\n },\n\n chunking: {\n enabled: false,\n concurrent: {\n enabled: false\n },\n mandatory: false,\n paramNames: {\n partIndex: \"qqpartindex\",\n partByteOffset: \"qqpartbyteoffset\",\n chunkSize: \"qqchunksize\",\n totalFileSize: \"qqtotalfilesize\",\n totalParts: \"qqtotalparts\"\n },\n partSize: function(id) {\n return 2000000;\n },\n // only relevant for traditional endpoints, only required when concurrent.enabled === true\n success: {\n endpoint: null,\n\n headers: function(id) {\n return null;\n },\n\n jsonPayload: false,\n\n method: \"POST\",\n\n params: function(id) {\n return null;\n },\n\n resetOnStatus: []\n }\n },\n\n resume: {\n enabled: false,\n recordsExpireIn: 7, //days\n paramNames: {\n resuming: \"qqresume\"\n },\n customKeys: function(fileId) {\n return [];\n }\n },\n\n formatFileName: function(fileOrBlobName) {\n return fileOrBlobName;\n },\n\n text: {\n defaultResponseError: \"Upload failure reason unknown\",\n fileInputTitle: \"file input\",\n sizeSymbols: [\"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"]\n },\n\n deleteFile: {\n enabled: false,\n method: \"DELETE\",\n endpoint: \"/server/upload\",\n customHeaders: {},\n params: {}\n },\n\n cors: {\n expected: false,\n sendCredentials: false,\n allowXdr: false\n },\n\n blobs: {\n defaultName: \"misc_data\"\n },\n\n paste: {\n targetElement: null,\n defaultName: \"pasted_image\"\n },\n\n camera: {\n ios: false,\n\n // if ios is true: button is null means target the default button, otherwise target the button specified\n button: null\n },\n\n // This refers to additional upload buttons to be handled by Fine Uploader.\n // Each element is an object, containing `element` as the only required\n // property. The `element` must be a container that will ultimately\n // contain an invisible `` created by Fine Uploader.\n // Optional properties of each object include `multiple`, `validation`,\n // and `folders`.\n extraButtons: [],\n\n // Depends on the session module. Used to query the server for an initial file list\n // during initialization and optionally after a `reset`.\n session: {\n endpoint: null,\n params: {},\n customHeaders: {},\n refreshOnReset: true\n },\n\n // Send parameters associated with an existing form along with the files\n form: {\n // Element ID, HTMLElement, or null\n element: \"qq-form\",\n\n // Overrides the base `autoUpload`, unless `element` is null.\n autoUpload: false,\n\n // true = upload files on form submission (and squelch submit event)\n interceptSubmit: true\n },\n\n // scale images client side, upload a new file for each scaled version\n scaling: {\n customResizer: null,\n\n // send the original file as well\n sendOriginal: true,\n\n // fox orientation for scaled images\n orient: true,\n\n // If null, scaled image type will match reference image type. This value will be referred to\n // for any size record that does not specific a type.\n defaultType: null,\n\n defaultQuality: 80,\n\n failureText: \"Failed to scale\",\n\n includeExif: false,\n\n // metadata about each requested scaled version\n sizes: []\n },\n\n workarounds: {\n iosEmptyVideos: true,\n ios8SafariUploads: true,\n ios8BrowserCrash: false\n }\n };\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._buttons = [];\n this._extraButtonSpecs = {};\n this._buttonIdsForFileIds = [];\n\n this._wrapCallbacks();\n this._disposeSupport = new qq.DisposeSupport();\n\n this._storedIds = [];\n this._autoRetries = [];\n this._retryTimeouts = [];\n this._preventRetries = [];\n this._thumbnailUrls = [];\n\n this._netUploadedOrQueued = 0;\n this._netUploaded = 0;\n this._uploadData = this._createUploadDataTracker();\n\n this._initFormSupportAndParams();\n\n this._customHeadersStore = this._createStore(this._options.request.customHeaders);\n this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders);\n\n this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params);\n\n this._endpointStore = this._createStore(this._options.request.endpoint);\n this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint);\n\n this._handler = this._createUploadHandler();\n\n this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler();\n\n if (this._options.button) {\n this._defaultButtonId = this._createUploadButton({\n element: this._options.button,\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._generateExtraButtonSpecs();\n\n this._handleCameraAccess();\n\n if (this._options.paste.targetElement) {\n if (qq.PasteSupport) {\n this._pasteHandler = this._createPasteHandler();\n }\n else {\n this.log(\"Paste support module not found\", \"error\");\n }\n }\n\n this._options.warnBeforeUnload && this._preventLeaveInProgress();\n\n this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));\n this._refreshSessionData();\n\n this._succeededSinceLastAllComplete = [];\n this._failedSinceLastAllComplete = [];\n\n this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {};\n if (this._scaler.enabled) {\n this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler);\n }\n\n if (qq.TotalProgress && qq.supportedFeatures.progressBar) {\n this._totalProgress = new qq.TotalProgress(\n qq.bind(this._onTotalProgress, this),\n\n function(id) {\n var entry = self._uploadData.retrieve({id: id});\n return (entry && entry.size) || 0;\n }\n );\n }\n\n this._currentItemLimit = this._options.validation.itemLimit;\n\n this._customResumeDataStore = this._createStore();\n };\n\n // Define the private & public API methods.\n qq.FineUploaderBasic.prototype = qq.basePublicApi;\n qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi);\n}());\n","/*globals qq, XDomainRequest*/\n/** Generic class for sending non-upload ajax requests and handling the associated responses **/\nqq.AjaxRequester = function(o) {\n \"use strict\";\n\n var log, shouldParamsBeInQueryString,\n queue = [],\n requestData = {},\n options = {\n acceptHeader: null,\n validMethods: [\"PATCH\", \"POST\", \"PUT\"],\n method: \"POST\",\n contentType: \"application/x-www-form-urlencoded\",\n maxConnections: 3,\n customHeaders: {},\n endpointStore: {},\n paramsStore: {},\n mandatedParams: {},\n allowXRequestedWithAndCacheControl: true,\n successfulResponseCodes: {\n DELETE: [200, 202, 204],\n PATCH: [200, 201, 202, 203, 204],\n POST: [200, 201, 202, 203, 204],\n PUT: [200, 201, 202, 203, 204],\n GET: [200]\n },\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onSend: function(id) {},\n onComplete: function(id, xhrOrXdr, isError) {},\n onProgress: null\n };\n\n qq.extend(options, o);\n log = options.log;\n\n if (qq.indexOf(options.validMethods, options.method) < 0) {\n throw new Error(\"'\" + options.method + \"' is not a supported method for this type of request!\");\n }\n\n // [Simple methods](http://www.w3.org/TR/cors/#simple-method)\n // are defined by the W3C in the CORS spec as a list of methods that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function isSimpleMethod() {\n return qq.indexOf([\"GET\", \"POST\", \"HEAD\"], options.method) >= 0;\n }\n\n // [Simple headers](http://www.w3.org/TR/cors/#simple-header)\n // are defined by the W3C in the CORS spec as a list of headers that, in part,\n // make a CORS request eligible to be exempt from preflighting.\n function containsNonSimpleHeaders(headers) {\n var containsNonSimple = false;\n\n qq.each(containsNonSimple, function(idx, header) {\n if (qq.indexOf([\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"], header) < 0) {\n containsNonSimple = true;\n return false;\n }\n });\n\n return containsNonSimple;\n }\n\n function isXdr(xhr) {\n //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS.\n return options.cors.expected && xhr.withCredentials === undefined;\n }\n\n // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance.\n function getCorsAjaxTransport() {\n var xhrOrXdr;\n\n if (window.XMLHttpRequest || window.ActiveXObject) {\n xhrOrXdr = qq.createXhrInstance();\n\n if (xhrOrXdr.withCredentials === undefined) {\n xhrOrXdr = new XDomainRequest();\n // Workaround for XDR bug in IE9 - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment\n xhrOrXdr.onload = function() {};\n xhrOrXdr.onerror = function() {};\n xhrOrXdr.ontimeout = function() {};\n xhrOrXdr.onprogress = function() {};\n }\n }\n\n return xhrOrXdr;\n }\n\n // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`.\n function getXhrOrXdr(id, suppliedXhr) {\n var xhrOrXdr = requestData[id] && requestData[id].xhr;\n\n if (!xhrOrXdr) {\n if (suppliedXhr) {\n xhrOrXdr = suppliedXhr;\n }\n else {\n if (options.cors.expected) {\n xhrOrXdr = getCorsAjaxTransport();\n }\n else {\n xhrOrXdr = qq.createXhrInstance();\n }\n }\n\n requestData[id].xhr = xhrOrXdr;\n }\n\n return xhrOrXdr;\n }\n\n // Removes element from queue, sends next request\n function dequeue(id) {\n var i = qq.indexOf(queue, id),\n max = options.maxConnections,\n nextId;\n\n delete requestData[id];\n queue.splice(i, 1);\n\n if (queue.length >= max && i < max) {\n nextId = queue[max - 1];\n sendRequest(nextId);\n }\n }\n\n function onComplete(id, xdrError) {\n var xhr = getXhrOrXdr(id),\n method = options.method,\n isError = xdrError === true;\n\n dequeue(id);\n\n if (isError) {\n log(method + \" request for \" + id + \" has failed\", \"error\");\n }\n else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) {\n isError = true;\n log(method + \" request for \" + id + \" has failed - response code \" + xhr.status, \"error\");\n }\n\n options.onComplete(id, xhr, isError);\n }\n\n function getParams(id) {\n var onDemandParams = requestData[id].additionalParams,\n mandatedParams = options.mandatedParams,\n params;\n\n if (options.paramsStore.get) {\n params = options.paramsStore.get(id);\n }\n\n if (onDemandParams) {\n qq.each(onDemandParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n if (mandatedParams) {\n qq.each(mandatedParams, function(name, val) {\n params = params || {};\n params[name] = val;\n });\n }\n\n return params;\n }\n\n function sendRequest(id, optXhr) {\n var xhr = getXhrOrXdr(id, optXhr),\n method = options.method,\n params = getParams(id),\n payload = requestData[id].payload,\n url;\n\n options.onSend(id);\n\n url = createUrl(id, params, requestData[id].additionalQueryParams);\n\n // XDR and XHR status detection APIs differ a bit.\n if (isXdr(xhr)) {\n xhr.onload = getXdrLoadHandler(id);\n xhr.onerror = getXdrErrorHandler(id);\n }\n else {\n xhr.onreadystatechange = getXhrReadyStateChangeHandler(id);\n }\n\n registerForUploadProgress(id);\n\n // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`.\n xhr.open(method, url, true);\n\n // Instruct the transport to send cookies along with the CORS request,\n // unless we are using `XDomainRequest`, which is not capable of this.\n if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) {\n xhr.withCredentials = true;\n }\n\n setHeaders(id);\n\n log(\"Sending \" + method + \" request for \" + id);\n\n if (payload) {\n xhr.send(payload);\n }\n else if (shouldParamsBeInQueryString || !params) {\n xhr.send();\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/x-www-form-urlencoded\") >= 0) {\n xhr.send(qq.obj2url(params, \"\"));\n }\n else if (params && options.contentType && options.contentType.toLowerCase().indexOf(\"application/json\") >= 0) {\n xhr.send(JSON.stringify(params));\n }\n else {\n xhr.send(params);\n }\n\n return xhr;\n }\n\n function createUrl(id, params, additionalQueryParams) {\n var endpoint = options.endpointStore.get(id),\n addToPath = requestData[id].addToPath;\n\n /*jshint -W116,-W041 */\n if (addToPath != undefined) {\n endpoint += \"/\" + addToPath;\n }\n\n if (shouldParamsBeInQueryString && params) {\n endpoint = qq.obj2url(params, endpoint);\n }\n\n if (additionalQueryParams) {\n endpoint = qq.obj2url(additionalQueryParams, endpoint);\n }\n\n return endpoint;\n }\n\n // Invoked by the UA to indicate a number of possible states that describe\n // a live `XMLHttpRequest` transport.\n function getXhrReadyStateChangeHandler(id) {\n return function() {\n if (getXhrOrXdr(id).readyState === 4) {\n onComplete(id);\n }\n };\n }\n\n function registerForUploadProgress(id) {\n var onProgress = options.onProgress;\n\n if (onProgress) {\n getXhrOrXdr(id).upload.onprogress = function(e) {\n if (e.lengthComputable) {\n onProgress(id, e.loaded, e.total);\n }\n };\n }\n }\n\n // This will be called by IE to indicate **success** for an associated\n // `XDomainRequest` transported request.\n function getXdrLoadHandler(id) {\n return function() {\n onComplete(id);\n };\n }\n\n // This will be called by IE to indicate **failure** for an associated\n // `XDomainRequest` transported request.\n function getXdrErrorHandler(id) {\n return function() {\n onComplete(id, true);\n };\n }\n\n function setHeaders(id) {\n var xhr = getXhrOrXdr(id),\n customHeaders = options.customHeaders,\n onDemandHeaders = requestData[id].additionalHeaders || {},\n method = options.method,\n allHeaders = {};\n\n // If XDomainRequest is being used, we can't set headers, so just ignore this block.\n if (!isXdr(xhr)) {\n options.acceptHeader && xhr.setRequestHeader(\"Accept\", options.acceptHeader);\n\n // Only attempt to add X-Requested-With & Cache-Control if permitted\n if (options.allowXRequestedWithAndCacheControl) {\n // Do not add X-Requested-With & Cache-Control if this is a cross-origin request\n // OR the cross-origin request contains a non-simple method or header.\n // This is done to ensure a preflight is not triggered exclusively based on the\n // addition of these 2 non-simple headers.\n if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) {\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n }\n }\n\n if (options.contentType && (method === \"POST\" || method === \"PUT\")) {\n xhr.setRequestHeader(\"Content-Type\", options.contentType);\n }\n\n qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders);\n qq.extend(allHeaders, onDemandHeaders);\n\n qq.each(allHeaders, function(name, val) {\n xhr.setRequestHeader(name, val);\n });\n }\n }\n\n function isResponseSuccessful(responseCode) {\n return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0;\n }\n\n function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) {\n requestData[id] = {\n addToPath: addToPath,\n additionalParams: additionalParams,\n additionalQueryParams: additionalQueryParams,\n additionalHeaders: additionalHeaders,\n payload: payload\n };\n\n var len = queue.push(id);\n\n // if too many active connections, wait...\n if (len <= options.maxConnections) {\n return sendRequest(id, optXhr);\n }\n }\n\n shouldParamsBeInQueryString = options.method === \"GET\" || options.method === \"DELETE\";\n\n qq.extend(this, {\n // Start the process of sending the request. The ID refers to the file associated with the request.\n initTransport: function(id) {\n var path, params, headers, payload, cacheBuster, additionalQueryParams;\n\n return {\n // Optionally specify the end of the endpoint path for the request.\n withPath: function(appendToPath) {\n path = appendToPath;\n return this;\n },\n\n // Optionally specify additional parameters to send along with the request.\n // These will be added to the query string for GET/DELETE requests or the payload\n // for POST/PUT requests. The Content-Type of the request will be used to determine\n // how these parameters should be formatted as well.\n withParams: function(additionalParams) {\n params = additionalParams;\n return this;\n },\n\n withQueryParams: function(_additionalQueryParams_) {\n additionalQueryParams = _additionalQueryParams_;\n return this;\n },\n\n // Optionally specify additional headers to send along with the request.\n withHeaders: function(additionalHeaders) {\n headers = additionalHeaders;\n return this;\n },\n\n // Optionally specify a payload/body for the request.\n withPayload: function(thePayload) {\n payload = thePayload;\n return this;\n },\n\n // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE)\n withCacheBuster: function() {\n cacheBuster = true;\n return this;\n },\n\n // Send the constructed request.\n send: function(optXhr) {\n if (cacheBuster && qq.indexOf([\"GET\", \"DELETE\"], options.method) >= 0) {\n params.qqtimestamp = new Date().getTime();\n }\n\n return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload);\n }\n };\n },\n\n canceled: function(id) {\n dequeue(id);\n }\n });\n};\n","/* globals qq */\n/**\n * Common upload handler functions.\n *\n * @constructor\n */\nqq.UploadHandler = function(spec) {\n \"use strict\";\n\n var proxy = spec.proxy,\n fileState = {},\n onCancel = proxy.onCancel,\n getName = proxy.getName;\n\n qq.extend(this, {\n add: function(id, fileItem) {\n fileState[id] = fileItem;\n fileState[id].temp = {};\n },\n\n cancel: function(id) {\n var self = this,\n cancelFinalizationEffort = new qq.Promise(),\n onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort);\n\n onCancelRetVal.then(function() {\n if (self.isValid(id)) {\n fileState[id].canceled = true;\n self.expunge(id);\n }\n cancelFinalizationEffort.success();\n });\n },\n\n expunge: function(id) {\n delete fileState[id];\n },\n\n getThirdPartyFileId: function(id) {\n return fileState[id].key;\n },\n\n isValid: function(id) {\n return fileState[id] !== undefined;\n },\n\n reset: function() {\n fileState = {};\n },\n\n _getFileState: function(id) {\n return fileState[id];\n },\n\n _setThirdPartyFileId: function(id, thirdPartyFileId) {\n fileState[id].key = thirdPartyFileId;\n },\n\n _wasCanceled: function(id) {\n return !!fileState[id].canceled;\n }\n });\n};\n","/*globals qq*/\n/**\n * Base upload handler module. Controls more specific handlers.\n *\n * @param o Options. Passed along to the specific handler submodule as well.\n * @param namespace [optional] Namespace for the specific handler.\n */\nqq.UploadHandlerController = function(o, namespace) {\n \"use strict\";\n\n var controller = this,\n chunkingPossible = false,\n concurrentChunkingPossible = false,\n chunking, preventRetryResponse, log, handler,\n\n options = {\n paramsStore: {},\n maxConnections: 3, // maximum number of concurrent uploads\n chunking: {\n enabled: false,\n multiple: {\n enabled: false\n }\n },\n log: function(str, level) {},\n onProgress: function(id, fileName, loaded, total) {},\n onComplete: function(id, fileName, response, xhr) {},\n onCancel: function(id, fileName) {},\n onUploadPrep: function(id) {}, // Called if non-trivial operations will be performed before onUpload\n onUpload: function(id, fileName) {},\n onUploadChunk: function(id, fileName, chunkData) {},\n onUploadChunkSuccess: function(id, chunkData, response, xhr) {},\n onAutoRetry: function(id, fileName, response, xhr) {},\n onResume: function(id, fileName, chunkData, customResumeData) {},\n onUuidChanged: function(id, newUuid) {},\n getName: function(id) {},\n setSize: function(id, newSize) {},\n isQueued: function(id) {},\n getIdsInProxyGroup: function(id) {},\n getIdsInBatch: function(id) {},\n isInProgress: function(id) {}\n },\n\n chunked = {\n // Called when each chunk has uploaded successfully\n done: function(id, chunkIdx, response, xhr) {\n var chunkData = handler._getChunkData(id, chunkIdx);\n\n handler._getFileState(id).attemptingResume = false;\n\n delete handler._getFileState(id).temp.chunkProgress[chunkIdx];\n handler._getFileState(id).loaded += chunkData.size;\n\n options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr);\n },\n\n // Called when all chunks have been successfully uploaded and we want to ask the handler to perform any\n // logic associated with closing out the file, such as combining the chunks.\n finalize: function(id) {\n var size = options.getSize(id),\n name = options.getName(id);\n\n log(\"All chunks have been uploaded for \" + id + \" - finalizing....\");\n handler.finalizeChunks(id).then(\n function(response, xhr) {\n log(\"Finalize successful for \" + id);\n\n var normaizedResponse = upload.normalizeResponse(response, true);\n\n options.onProgress(id, name, size, size);\n handler._maybeDeletePersistedChunkData(id);\n upload.cleanup(id, normaizedResponse, xhr);\n },\n function(response, xhr) {\n var normalizedResponse = upload.normalizeResponse(response, false);\n\n log(\"Problem finalizing chunks for file ID \" + id + \" - \" + normalizedResponse.error, \"error\");\n\n if (\n normalizedResponse.reset ||\n (xhr && options.chunking.success.resetOnStatus.indexOf(xhr.status) >= 0)\n ) {\n chunked.reset(id);\n }\n\n if (!options.onAutoRetry(id, name, normalizedResponse, xhr)) {\n upload.cleanup(id, normalizedResponse, xhr);\n }\n }\n );\n },\n\n handleFailure: function(chunkIdx, id, response, xhr) {\n var name = options.getName(id);\n\n log(\"Chunked upload request failed for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var responseToReport = upload.normalizeResponse(response, false),\n inProgressIdx;\n\n if (responseToReport.reset) {\n chunked.reset(id);\n }\n else {\n var inProgressChunksArray = handler._getFileState(id).chunking.inProgress;\n\n inProgressIdx = inProgressChunksArray ? qq.indexOf(inProgressChunksArray, chunkIdx) : -1;\n if (inProgressIdx >= 0) {\n handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1);\n handler._getFileState(id).chunking.remaining.unshift(chunkIdx);\n }\n }\n\n // We may have aborted all other in-progress chunks for this file due to a failure.\n // If so, ignore the failures associated with those aborts.\n if (!handler._getFileState(id).temp.ignoreFailure) {\n // If this chunk has failed, we want to ignore all other failures of currently in-progress\n // chunks since they will be explicitly aborted\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = true;\n\n log(qq.format(\"Going to attempt to abort these chunks: {}. These are currently in-progress: {}.\", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress)));\n qq.each(handler._getXhrs(id), function(ckid, ckXhr) {\n log(qq.format(\"Attempting to abort file {}.{}. XHR readyState {}. \", id, ckid, ckXhr.readyState));\n ckXhr.abort();\n // Flag the transport, in case we are waiting for some other async operation\n // to complete before attempting to upload the chunk\n ckXhr._cancelled = true;\n });\n\n // We must indicate that all aborted chunks are no longer in progress\n handler.moveInProgressToRemaining(id);\n\n // Free up any connections used by these chunks, but don't allow any\n // other files to take up the connections (until we have exhausted all auto-retries)\n connectionManager.free(id, true);\n }\n\n if (!options.onAutoRetry(id, name, responseToReport, xhr)) {\n // If one chunk fails, abort all of the others to avoid odd race conditions that occur\n // if a chunk succeeds immediately after one fails before we have determined if the upload\n // is a failure or not.\n upload.cleanup(id, responseToReport, xhr);\n }\n }\n },\n\n hasMoreParts: function(id) {\n return !!handler._getFileState(id).chunking.remaining.length;\n },\n\n nextPart: function(id) {\n var nextIdx = handler._getFileState(id).chunking.remaining.shift();\n\n if (nextIdx >= handler._getTotalChunks(id)) {\n nextIdx = null;\n }\n\n return nextIdx;\n },\n\n reset: function(id) {\n log(\"Server or callback has ordered chunking effort to be restarted on next attempt for item ID \" + id, \"error\");\n\n handler._maybeDeletePersistedChunkData(id);\n handler.reevaluateChunking(id);\n handler._getFileState(id).loaded = 0;\n handler._getFileState(id).attemptingResume = false;\n },\n\n sendNext: function(id) {\n var size = options.getSize(id),\n name = options.getName(id),\n chunkIdx = chunked.nextPart(id),\n chunkData = handler._getChunkData(id, chunkIdx),\n fileState = handler._getFileState(id),\n resuming = fileState.attemptingResume,\n inProgressChunks = fileState.chunking.inProgress || [];\n\n if (fileState.loaded == null) {\n fileState.loaded = 0;\n }\n\n // Don't follow-through with the resume attempt if the integrator returns false from onResume\n if (resuming && options.onResume(id, name, chunkData, fileState.customResumeData) === false) {\n chunked.reset(id);\n chunkIdx = chunked.nextPart(id);\n chunkData = handler._getChunkData(id, chunkIdx);\n resuming = false;\n }\n\n // If all chunks have already uploaded successfully, we must be re-attempting the finalize step.\n if (chunkIdx == null && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n\n // Send the next chunk\n else {\n inProgressChunks.push(chunkIdx);\n handler._getFileState(id).chunking.inProgress = inProgressChunks;\n\n if (concurrentChunkingPossible) {\n connectionManager.open(id, chunkIdx);\n }\n\n if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) {\n chunked.sendNext(id);\n }\n\n if (chunkData.blob.size === 0) {\n log(qq.format(\"Chunk {} for file {} will not be uploaded, zero sized chunk.\", chunkIdx, id), \"error\");\n chunked.handleFailure(chunkIdx, id, \"File is no longer available\", null);\n }\n\n var onUploadChunkPromise = options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData));\n\n onUploadChunkPromise.then(\n function(requestOverrides) {\n if (!options.isInProgress(id)) {\n log(qq.format(\"Not sending chunked upload request for item {}.{} - no longer in progress.\", id, chunkIdx));\n }\n else {\n log(qq.format(\"Sending chunked upload request for item {}.{}, bytes {}-{} of {}.\", id, chunkIdx, chunkData.start + 1, chunkData.end, size));\n\n var uploadChunkData = {\n chunkIdx: chunkIdx,\n id: id,\n overrides: requestOverrides,\n resuming: resuming\n };\n\n handler.uploadChunk(uploadChunkData).then(\n // upload chunk success\n function success(response, xhr) {\n log(\"Chunked upload request succeeded for \" + id + \", chunk \" + chunkIdx);\n\n handler.clearCachedChunk(id, chunkIdx);\n\n var inProgressChunks = handler._getFileState(id).chunking.inProgress || [],\n responseToReport = upload.normalizeResponse(response, true),\n inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx);\n\n log(qq.format(\"Chunk {} for file {} uploaded successfully.\", chunkIdx, id));\n\n chunked.done(id, chunkIdx, responseToReport, xhr);\n\n if (inProgressChunkIdx >= 0) {\n inProgressChunks.splice(inProgressChunkIdx, 1);\n }\n\n handler._maybePersistChunkedState(id);\n\n if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) {\n chunked.finalize(id);\n }\n else if (chunked.hasMoreParts(id)) {\n chunked.sendNext(id);\n }\n else {\n log(qq.format(\"File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}\", id, JSON.stringify(inProgressChunks)));\n }\n },\n\n // upload chunk failure\n function failure(response, xhr) {\n chunked.handleFailure(chunkIdx, id, response, xhr);\n }\n )\n .done(function () {\n handler.clearXhr(id, chunkIdx);\n });\n }\n },\n\n function(error) {\n chunked.handleFailure(chunkIdx, id, error, null);\n }\n );\n }\n }\n },\n\n connectionManager = {\n _open: [],\n _openChunks: {},\n _waiting: [],\n\n available: function() {\n var max = options.maxConnections,\n openChunkEntriesCount = 0,\n openChunksCount = 0;\n\n qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) {\n openChunkEntriesCount++;\n openChunksCount += openChunkIndexes.length;\n });\n\n return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount);\n },\n\n /**\n * Removes element from queue, starts upload of next\n */\n free: function(id, dontAllowNext) {\n var allowNext = !dontAllowNext,\n waitingIndex = qq.indexOf(connectionManager._waiting, id),\n connectionsIndex = qq.indexOf(connectionManager._open, id),\n nextId;\n\n delete connectionManager._openChunks[id];\n\n if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) {\n log(\"Generated blob upload has ended for \" + id + \", disposing generated blob.\");\n delete handler._getFileState(id).file;\n }\n\n // If this file was not consuming a connection, it was just waiting, so remove it from the waiting array\n if (waitingIndex >= 0) {\n connectionManager._waiting.splice(waitingIndex, 1);\n }\n // If this file was consuming a connection, allow the next file to be uploaded\n else if (allowNext && connectionsIndex >= 0) {\n connectionManager._open.splice(connectionsIndex, 1);\n\n nextId = connectionManager._waiting.shift();\n if (nextId >= 0) {\n connectionManager._open.push(nextId);\n upload.start(nextId);\n }\n }\n },\n\n getWaitingOrConnected: function() {\n var waitingOrConnected = [];\n\n // Chunked files may have multiple connections open per chunk (if concurrent chunking is enabled)\n // We need to grab the file ID of any file that has at least one chunk consuming a connection.\n qq.each(connectionManager._openChunks, function(fileId, chunks) {\n if (chunks && chunks.length) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // For non-chunked files, only one connection will be consumed per file.\n // This is where we aggregate those file IDs.\n qq.each(connectionManager._open, function(idx, fileId) {\n if (!connectionManager._openChunks[fileId]) {\n waitingOrConnected.push(parseInt(fileId));\n }\n });\n\n // There may be files waiting for a connection.\n waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting);\n\n return waitingOrConnected;\n },\n\n isUsingConnection: function(id) {\n return qq.indexOf(connectionManager._open, id) >= 0;\n },\n\n open: function(id, chunkIdx) {\n if (chunkIdx == null) {\n connectionManager._waiting.push(id);\n }\n\n if (connectionManager.available()) {\n if (chunkIdx == null) {\n connectionManager._waiting.pop();\n connectionManager._open.push(id);\n }\n else {\n (function() {\n var openChunksEntry = connectionManager._openChunks[id] || [];\n openChunksEntry.push(chunkIdx);\n connectionManager._openChunks[id] = openChunksEntry;\n }());\n }\n\n return true;\n }\n\n return false;\n },\n\n reset: function() {\n connectionManager._waiting = [];\n connectionManager._open = [];\n }\n },\n\n simple = {\n send: function(id, name) {\n var fileState = handler._getFileState(id);\n\n if (!fileState) {\n log(\"Ignoring send request as this upload may have been cancelled, File ID \" + id, \"warn\");\n return;\n }\n\n fileState.loaded = 0;\n\n log(\"Sending simple upload request for \" + id);\n handler.uploadFile(id).then(\n function(response, optXhr) {\n log(\"Simple upload request succeeded for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, true),\n size = options.getSize(id);\n\n options.onProgress(id, name, size, size);\n upload.maybeNewUuid(id, responseToReport);\n upload.cleanup(id, responseToReport, optXhr);\n },\n\n function(response, optXhr) {\n log(\"Simple upload request failed for \" + id);\n\n var responseToReport = upload.normalizeResponse(response, false);\n\n if (!options.onAutoRetry(id, name, responseToReport, optXhr)) {\n upload.cleanup(id, responseToReport, optXhr);\n }\n }\n );\n }\n },\n\n upload = {\n cancel: function(id) {\n log(\"Cancelling \" + id);\n options.paramsStore.remove(id);\n connectionManager.free(id);\n },\n\n cleanup: function(id, response, optXhr) {\n var name = options.getName(id);\n\n options.onComplete(id, name, response, optXhr);\n\n if (handler._getFileState(id)) {\n handler._clearXhrs && handler._clearXhrs(id);\n }\n\n connectionManager.free(id);\n },\n\n // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined\n // if none of these are available for the ID\n getProxyOrBlob: function(id) {\n return (handler.getProxy && handler.getProxy(id)) ||\n (handler.getFile && handler.getFile(id));\n },\n\n initHandler: function() {\n var handlerType = namespace ? qq[namespace] : qq.traditional,\n handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? \"Xhr\" : \"Form\";\n\n handler = new handlerType[handlerModuleSubtype + \"UploadHandler\"](\n options,\n {\n getCustomResumeData: options.getCustomResumeData,\n getDataByUuid: options.getDataByUuid,\n getName: options.getName,\n getSize: options.getSize,\n getUuid: options.getUuid,\n log: log,\n onCancel: options.onCancel,\n onProgress: options.onProgress,\n onUuidChanged: options.onUuidChanged,\n onFinalizing: function(id) {\n options.setStatus(id, qq.status.UPLOAD_FINALIZING);\n }\n }\n );\n\n if (handler._removeExpiredChunkingRecords) {\n handler._removeExpiredChunkingRecords();\n }\n },\n\n isDeferredEligibleForUpload: function(id) {\n return options.isQueued(id);\n },\n\n // For Blobs that are part of a group of generated images, along with a reference image,\n // this will ensure the blobs in the group are uploaded in the order they were triggered,\n // even if some async processing must be completed on one or more Blobs first.\n maybeDefer: function(id, blob) {\n // If we don't have a file/blob yet & no file/blob exists for this item, request it,\n // and then submit the upload to the specific handler once the blob is available.\n // ASSUMPTION: This condition will only ever be true if XHR uploading is supported.\n if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) {\n\n // Blob creation may take some time, so the caller may want to update the\n // UI to indicate that an operation is in progress, even before the actual\n // upload begins and an onUpload callback is invoked.\n options.onUploadPrep(id);\n\n log(\"Attempting to generate a blob on-demand for \" + id);\n blob.create().then(function(generatedBlob) {\n log(\"Generated an on-demand blob for \" + id);\n\n // Update record associated with this file by providing the generated Blob\n handler.updateBlob(id, generatedBlob);\n\n // Propagate the size for this generated Blob\n options.setSize(id, generatedBlob.size);\n\n // Order handler to recalculate chunking possibility, if applicable\n handler.reevaluateChunking(id);\n\n upload.maybeSendDeferredFiles(id);\n },\n\n // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message.\n function(errorMessage) {\n var errorResponse = {};\n\n if (errorMessage) {\n errorResponse.error = errorMessage;\n }\n\n log(qq.format(\"Failed to generate blob for ID {}. Error message: {}.\", id, errorMessage), \"error\");\n\n options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null);\n upload.maybeSendDeferredFiles(id);\n connectionManager.free(id);\n });\n }\n else {\n return upload.maybeSendDeferredFiles(id);\n }\n\n return false;\n },\n\n // Upload any grouped blobs, in the proper order, that are ready to be uploaded\n maybeSendDeferredFiles: function(id) {\n var idsInGroup = options.getIdsInProxyGroup(id),\n uploadedThisId = false;\n\n if (idsInGroup && idsInGroup.length) {\n log(\"Maybe ready to upload proxy group file \" + id);\n\n qq.each(idsInGroup, function(idx, idInGroup) {\n if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) {\n uploadedThisId = idInGroup === id;\n upload.now(idInGroup);\n }\n else if (upload.isDeferredEligibleForUpload(idInGroup)) {\n return false;\n }\n });\n }\n else {\n uploadedThisId = true;\n upload.now(id);\n }\n\n return uploadedThisId;\n },\n\n maybeNewUuid: function(id, response) {\n if (response.newUuid !== undefined) {\n options.onUuidChanged(id, response.newUuid);\n }\n },\n\n // The response coming from handler implementations may be in various formats.\n // Instead of hoping a promise nested 5 levels deep will always return an object\n // as its first param, let's just normalize the response here.\n normalizeResponse: function(originalResponse, successful) {\n var response = originalResponse;\n\n // The passed \"response\" param may not be a response at all.\n // It could be a string, detailing the error, for example.\n if (!qq.isObject(originalResponse)) {\n response = {};\n\n if (qq.isString(originalResponse) && !successful) {\n response.error = originalResponse;\n }\n }\n\n response.success = successful;\n\n return response;\n },\n\n now: function(id) {\n var name = options.getName(id);\n\n if (!controller.isValid(id)) {\n throw new qq.Error(id + \" is not a valid file ID to upload!\");\n }\n\n options.onUpload(id, name).then(\n function(response) {\n if (response && response.pause) {\n options.setStatus(id, qq.status.PAUSED);\n handler.pause(id);\n connectionManager.free(id);\n }\n else {\n if (chunkingPossible && handler._shouldChunkThisFile(id)) {\n chunked.sendNext(id);\n }\n else {\n simple.send(id, name);\n }\n }\n },\n\n function(error) {\n error = error || {};\n\n log(id + \" upload start aborted due to rejected onUpload Promise - details: \" + error, \"error\");\n\n if (!options.onAutoRetry(id, name, error.responseJSON || {})) {\n var response = upload.normalizeResponse(error.responseJSON, false);\n upload.cleanup(id, response);\n }\n }\n );\n },\n\n start: function(id) {\n var blobToUpload = upload.getProxyOrBlob(id);\n\n if (blobToUpload) {\n return upload.maybeDefer(id, blobToUpload);\n }\n else {\n upload.now(id);\n return true;\n }\n }\n };\n\n qq.extend(this, {\n /**\n * Adds file or file input to the queue\n **/\n add: function(id, file) {\n handler.add.apply(this, arguments);\n },\n\n /**\n * Sends the file identified by id\n */\n upload: function(id) {\n if (connectionManager.open(id)) {\n return upload.start(id);\n }\n return false;\n },\n\n retry: function(id) {\n // On retry, if concurrent chunking has been enabled, we may have aborted all other in-progress chunks\n // for a file when encountering a failed chunk upload. We then signaled the controller to ignore\n // all failures associated with these aborts. We are now retrying, so we don't want to ignore\n // any more failures at this point.\n if (concurrentChunkingPossible) {\n handler._getFileState(id).temp.ignoreFailure = false;\n }\n\n // If we are attempting to retry a file that is already consuming a connection, this is likely an auto-retry.\n // Just go ahead and ask the handler to upload again.\n if (connectionManager.isUsingConnection(id)) {\n return upload.start(id);\n }\n\n // If we are attempting to retry a file that is not currently consuming a connection,\n // this is likely a manual retry attempt. We will need to ensure a connection is available\n // before the retry commences.\n else {\n return controller.upload(id);\n }\n },\n\n /**\n * Cancels file upload by id\n */\n cancel: function(id) {\n var cancelRetVal = handler.cancel(id);\n\n if (qq.isGenericPromise(cancelRetVal)) {\n cancelRetVal.then(function() {\n upload.cancel(id);\n });\n }\n else if (cancelRetVal !== false) {\n upload.cancel(id);\n }\n },\n\n /**\n * Cancels all queued or in-progress uploads\n */\n cancelAll: function() {\n var waitingOrConnected = connectionManager.getWaitingOrConnected(),\n i;\n\n // ensure files are cancelled in reverse order which they were added\n // to avoid a flash of time where a queued file begins to upload before it is canceled\n if (waitingOrConnected.length) {\n for (i = waitingOrConnected.length - 1; i >= 0; i--) {\n controller.cancel(waitingOrConnected[i]);\n }\n }\n\n connectionManager.reset();\n },\n\n // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy.\n // Undefined if no file record is available.\n getFile: function(id) {\n if (handler.getProxy && handler.getProxy(id)) {\n return handler.getProxy(id).referenceBlob;\n }\n\n return handler.getFile && handler.getFile(id);\n },\n\n // Returns true if the Blob associated with the ID is related to a proxy s\n isProxied: function(id) {\n return !!(handler.getProxy && handler.getProxy(id));\n },\n\n getInput: function(id) {\n if (handler.getInput) {\n return handler.getInput(id);\n }\n },\n\n reset: function() {\n log(\"Resetting upload handler\");\n controller.cancelAll();\n connectionManager.reset();\n handler.reset();\n },\n\n expunge: function(id) {\n if (controller.isValid(id)) {\n return handler.expunge(id);\n }\n },\n\n /**\n * Determine if the file exists.\n */\n isValid: function(id) {\n return handler.isValid(id);\n },\n\n hasResumeRecord: function(id) {\n var key = handler.isValid(id) &&\n handler._getLocalStorageId &&\n handler._getLocalStorageId(id);\n\n if (key) {\n return !!localStorage.getItem(key);\n }\n\n return false;\n },\n\n getResumableFilesData: function() {\n if (handler.getResumableFilesData) {\n return handler.getResumableFilesData();\n }\n return [];\n },\n\n /**\n * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is\n * available (such as the \"key\" for Amazon S3), this will return that value. Otherwise, the return value\n * will be undefined.\n *\n * @param id Internal file ID\n * @returns {*} Some identifier used by a 3rd-party service involved in the upload process\n */\n getThirdPartyFileId: function(id) {\n if (controller.isValid(id)) {\n return handler.getThirdPartyFileId(id);\n }\n },\n\n /**\n * Attempts to pause the associated upload if the specific handler supports this and the file is \"valid\".\n * @param id ID of the upload/file to pause\n * @returns {boolean} true if the upload was paused\n */\n pause: function(id) {\n if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) {\n connectionManager.free(id);\n handler.moveInProgressToRemaining(id);\n return true;\n }\n return false;\n },\n\n isAttemptingResume: function(id) {\n return !!handler.isAttemptingResume && handler.isAttemptingResume(id);\n },\n\n // True if the file is eligible for pause/resume.\n isResumable: function(id) {\n return !!handler.isResumable && handler.isResumable(id);\n }\n });\n\n qq.extend(options, o);\n log = options.log;\n chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking;\n concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled;\n\n preventRetryResponse = (function() {\n var response = {};\n\n response[options.preventRetryParam] = true;\n\n return response;\n }());\n\n upload.initHandler();\n};\n","/*globals qq */\n/*jshint -W117 */\nqq.WindowReceiveMessage = function(o) {\n \"use strict\";\n\n var options = {\n log: function(message, level) {}\n },\n callbackWrapperDetachers = {};\n\n qq.extend(options, o);\n\n qq.extend(this, {\n receiveMessage: function(id, callback) {\n var onMessageCallbackWrapper = function(event) {\n callback(event.data);\n };\n\n if (window.postMessage) {\n callbackWrapperDetachers[id] = qq(window).attach(\"message\", onMessageCallbackWrapper);\n }\n else {\n log(\"iframe message passing not supported in this browser!\", \"error\");\n }\n },\n\n stopReceivingMessages: function(id) {\n if (window.postMessage) {\n var detacher = callbackWrapperDetachers[id];\n if (detacher) {\n detacher();\n }\n }\n }\n });\n};\n","/* globals qq */\n/**\n * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden\n * in some cases by specific form upload handlers.\n *\n * @constructor\n */\nqq.FormUploadHandler = function(spec) {\n \"use strict\";\n\n var options = spec.options,\n handler = this,\n proxy = spec.proxy,\n formHandlerInstanceId = qq.getUniqueId(),\n onloadCallbacks = {},\n detachLoadEvents = {},\n postMessageCallbackTimers = {},\n isCors = options.isCors,\n inputName = options.inputName,\n getUuid = proxy.getUuid,\n log = proxy.log,\n corsMessageReceiver = new qq.WindowReceiveMessage({log: log});\n\n /**\n * Remove any trace of the file from the handler.\n *\n * @param id ID of the associated file\n */\n function expungeFile(id) {\n delete detachLoadEvents[id];\n\n // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe.\n // In that case, terminate the timer waiting for a message from the loaded iframe\n // and stop listening for any more messages coming from this iframe.\n if (isCors) {\n clearTimeout(postMessageCallbackTimers[id]);\n delete postMessageCallbackTimers[id];\n corsMessageReceiver.stopReceivingMessages(id);\n }\n\n var iframe = document.getElementById(handler._getIframeName(id));\n if (iframe) {\n // To cancel request set src to something else. We use src=\"javascript:false;\"\n // because it doesn't trigger ie6 prompt on https\n /* jshint scripturl:true */\n iframe.setAttribute(\"src\", \"javascript:false;\");\n\n qq(iframe).remove();\n }\n }\n\n /**\n * @param iframeName `document`-unique Name of the associated iframe\n * @returns {*} ID of the associated file\n */\n function getFileIdForIframeName(iframeName) {\n return iframeName.split(\"_\")[0];\n }\n\n /**\n * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe\n * to the current `document`. Note that the iframe is hidden from view.\n *\n * @param name Name of the iframe.\n * @returns {HTMLIFrameElement} The created iframe\n */\n function initIframeForUpload(name) {\n var iframe = qq.toElement(\"\");\n\n iframe.setAttribute(\"id\", name);\n\n iframe.style.display = \"none\";\n document.body.appendChild(iframe);\n\n return iframe;\n }\n\n /**\n * If we are in CORS mode, we must listen for messages (containing the server response) from the associated\n * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions.\n *\n * @param iframe Listen for messages on this iframe.\n * @param callback Invoke this callback with the message from the iframe.\n */\n function registerPostMessageCallback(iframe, callback) {\n var iframeName = iframe.id,\n fileId = getFileIdForIframeName(iframeName),\n uuid = getUuid(fileId);\n\n onloadCallbacks[uuid] = callback;\n\n // When the iframe has loaded (after the server responds to an upload request)\n // declare the attempt a failure if we don't receive a valid message shortly after the response comes in.\n detachLoadEvents[fileId] = qq(iframe).attach(\"load\", function() {\n if (handler.getInput(fileId)) {\n log(\"Received iframe load event for CORS upload request (iframe name \" + iframeName + \")\");\n\n postMessageCallbackTimers[iframeName] = setTimeout(function() {\n var errorMessage = \"No valid message received from loaded iframe for iframe name \" + iframeName;\n log(errorMessage, \"error\");\n callback({\n error: errorMessage\n });\n }, 1000);\n }\n });\n\n // Listen for messages coming from this iframe. When a message has been received, cancel the timer\n // that declares the upload a failure if a message is not received within a reasonable amount of time.\n corsMessageReceiver.receiveMessage(iframeName, function(message) {\n log(\"Received the following window message: '\" + message + \"'\");\n var fileId = getFileIdForIframeName(iframeName),\n response = handler._parseJsonResponse(message),\n uuid = response.uuid,\n onloadCallback;\n\n if (uuid && onloadCallbacks[uuid]) {\n log(\"Handling response for iframe name \" + iframeName);\n clearTimeout(postMessageCallbackTimers[iframeName]);\n delete postMessageCallbackTimers[iframeName];\n\n handler._detachLoadEvent(iframeName);\n\n onloadCallback = onloadCallbacks[uuid];\n\n delete onloadCallbacks[uuid];\n corsMessageReceiver.stopReceivingMessages(iframeName);\n onloadCallback(response);\n }\n else if (!uuid) {\n log(\"'\" + message + \"' does not contain a UUID - ignoring.\");\n }\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, fileInput) {\n super_.add(id, {input: fileInput});\n\n fileInput.setAttribute(\"name\", inputName);\n\n // remove file input from DOM\n if (fileInput.parentNode) {\n qq(fileInput).remove();\n }\n },\n\n expunge: function(id) {\n expungeFile(id);\n super_.expunge(id);\n },\n\n isValid: function(id) {\n return super_.isValid(id) &&\n handler._getFileState(id).input !== undefined;\n }\n };\n });\n\n qq.extend(this, {\n getInput: function(id) {\n return handler._getFileState(id).input;\n },\n\n /**\n * This function either delegates to a more specific message handler if CORS is involved,\n * or simply registers a callback when the iframe has been loaded that invokes the passed callback\n * after determining if the content of the iframe is accessible.\n *\n * @param iframe Associated iframe\n * @param callback Callback to invoke after we have determined if the iframe content is accessible.\n */\n _attachLoadEvent: function(iframe, callback) {\n /*jslint eqeq: true*/\n var responseDescriptor;\n\n if (isCors) {\n registerPostMessageCallback(iframe, callback);\n }\n else {\n detachLoadEvents[iframe.id] = qq(iframe).attach(\"load\", function() {\n log(\"Received response for \" + iframe.id);\n\n // when we remove iframe from dom\n // the request stops, but in IE load\n // event fires\n if (!iframe.parentNode) {\n return;\n }\n\n try {\n // fixing Opera 10.53\n if (iframe.contentDocument &&\n iframe.contentDocument.body &&\n iframe.contentDocument.body.innerHTML == \"false\") {\n // In Opera event is fired second time\n // when body.innerHTML changed from false\n // to server response approx. after 1 sec\n // when we upload file with iframe\n return;\n }\n }\n catch (error) {\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n log(\"Error when attempting to access iframe during handling of upload response (\" + error.message + \")\", \"error\");\n responseDescriptor = {success: false};\n }\n\n callback(responseDescriptor);\n });\n }\n },\n\n /**\n * Creates an iframe with a specific document-unique name.\n *\n * @param id ID of the associated file\n * @returns {HTMLIFrameElement}\n */\n _createIframe: function(id) {\n var iframeName = handler._getIframeName(id);\n\n return initIframeForUpload(iframeName);\n },\n\n /**\n * Called when we are no longer interested in being notified when an iframe has loaded.\n *\n * @param id Associated file ID\n */\n _detachLoadEvent: function(id) {\n if (detachLoadEvents[id] !== undefined) {\n detachLoadEvents[id]();\n delete detachLoadEvents[id];\n }\n },\n\n /**\n * @param fileId ID of the associated file\n * @returns {string} The `document`-unique name of the iframe\n */\n _getIframeName: function(fileId) {\n return fileId + \"_\" + formHandlerInstanceId;\n },\n\n /**\n * Generates a form element and appends it to the `document`. When the form is submitted, a specific iframe is targeted.\n * The name of the iframe is passed in as a property of the spec parameter, and must be unique in the `document`. Note\n * that the form is hidden from view.\n *\n * @param spec An object containing various properties to be used when constructing the form. Required properties are\n * currently: `method`, `endpoint`, `params`, `paramsInBody`, and `targetName`.\n * @returns {HTMLFormElement} The created form\n */\n _initFormForUpload: function(spec) {\n var method = spec.method,\n endpoint = spec.endpoint,\n params = spec.params,\n paramsInBody = spec.paramsInBody,\n targetName = spec.targetName,\n form = qq.toElement(\"\"),\n url = endpoint;\n\n if (paramsInBody) {\n qq.obj2Inputs(params, form);\n }\n else {\n url = qq.obj2url(params, endpoint);\n }\n\n form.setAttribute(\"action\", url);\n form.setAttribute(\"target\", targetName);\n form.style.display = \"none\";\n document.body.appendChild(form);\n\n return form;\n },\n\n /**\n * @param innerHtmlOrMessage JSON message\n * @returns {*} The parsed response, or an empty object if the response could not be parsed\n */\n _parseJsonResponse: function(innerHtmlOrMessage) {\n var response = {};\n\n try {\n response = qq.parseJson(innerHtmlOrMessage);\n }\n catch (error) {\n log(\"Error when attempting to parse iframe upload response (\" + error.message + \")\", \"error\");\n }\n\n return response;\n }\n });\n};\n","/* globals qq */\n/**\n * Common API exposed to creators of XHR handlers. This is reused and possibly overriding in some cases by specific\n * XHR upload handlers.\n *\n * @constructor\n */\nqq.XhrUploadHandler = function(spec) {\n \"use strict\";\n\n var handler = this,\n namespace = spec.options.namespace,\n proxy = spec.proxy,\n chunking = spec.options.chunking,\n getChunkSize = function(id) {\n var fileState = handler._getFileState(id);\n\n if (fileState.chunkSize) {\n return fileState.chunkSize;\n }\n\n else {\n var chunkSize = chunking.partSize;\n\n if (qq.isFunction(chunkSize)) {\n chunkSize = chunkSize(id, getSize(id));\n }\n\n fileState.chunkSize = chunkSize;\n return chunkSize;\n }\n },\n resume = spec.options.resume,\n chunkFiles = chunking && spec.options.chunking.enabled && qq.supportedFeatures.chunking,\n resumeEnabled = resume && spec.options.resume.enabled && chunkFiles && qq.supportedFeatures.resume,\n getName = proxy.getName,\n getSize = proxy.getSize,\n getUuid = proxy.getUuid,\n getEndpoint = proxy.getEndpoint,\n getDataByUuid = proxy.getDataByUuid,\n onUuidChanged = proxy.onUuidChanged,\n onProgress = proxy.onProgress,\n log = proxy.log,\n getCustomResumeData = proxy.getCustomResumeData;\n\n function abort(id) {\n qq.each(handler._getXhrs(id), function(xhrId, xhr) {\n var ajaxRequester = handler._getAjaxRequester(id, xhrId);\n\n xhr.onreadystatechange = null;\n xhr.upload.onprogress = null;\n xhr.abort();\n ajaxRequester && ajaxRequester.canceled && ajaxRequester.canceled(id);\n });\n }\n\n qq.extend(this, new qq.UploadHandler(spec));\n\n qq.override(this, function(super_) {\n return {\n /**\n * Adds File or Blob to the queue\n **/\n add: function(id, blobOrProxy) {\n if (qq.isFile(blobOrProxy) || qq.isBlob(blobOrProxy)) {\n super_.add(id, {file: blobOrProxy});\n }\n else if (blobOrProxy instanceof qq.BlobProxy) {\n super_.add(id, {proxy: blobOrProxy});\n }\n else {\n throw new Error(\"Passed obj is not a File, Blob, or proxy\");\n }\n\n handler._initTempState(id);\n resumeEnabled && handler._maybePrepareForResume(id);\n },\n\n expunge: function(id) {\n abort(id);\n handler._maybeDeletePersistedChunkData(id);\n handler._clearXhrs(id);\n super_.expunge(id);\n }\n };\n });\n\n qq.extend(this, {\n // Clear the cached chunk `Blob` after we are done with it, just in case the `Blob` bytes are stored in memory.\n clearCachedChunk: function(id, chunkIdx) {\n var fileState = handler._getFileState(id);\n\n if (fileState) {\n delete fileState.temp.cachedChunks[chunkIdx];\n }\n },\n\n clearXhr: function(id, chunkIdx) {\n var tempState = handler._getFileState(id).temp;\n\n if (tempState.xhrs) {\n delete tempState.xhrs[chunkIdx];\n }\n if (tempState.ajaxRequesters) {\n delete tempState.ajaxRequesters[chunkIdx];\n }\n },\n\n // Called when all chunks have been successfully uploaded. Expected promissory return type.\n // This defines the default behavior if nothing further is required when all chunks have been uploaded.\n finalizeChunks: function(id, responseParser) {\n var lastChunkIdx = handler._getTotalChunks(id) - 1,\n xhr = handler._getXhr(id, lastChunkIdx);\n\n if (responseParser) {\n return new qq.Promise().success(responseParser(xhr), xhr);\n }\n\n return new qq.Promise().success({}, xhr);\n },\n\n getFile: function(id) {\n return handler.isValid(id) && handler._getFileState(id).file;\n },\n\n getProxy: function(id) {\n return handler.isValid(id) && handler._getFileState(id).proxy;\n },\n\n /**\n * @returns {Array} Array of objects containing properties useful to integrators\n * when it is important to determine which files are potentially resumable.\n */\n getResumableFilesData: function() {\n var resumableFilesData = [];\n\n handler._iterateResumeRecords(function(key, uploadData) {\n handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);\n\n var data = {\n name: uploadData.name,\n remaining: uploadData.chunking.remaining,\n size: uploadData.size,\n uuid: uploadData.uuid\n };\n\n if (uploadData.key) {\n data.key = uploadData.key;\n }\n\n if (uploadData.customResumeData) {\n data.customResumeData = uploadData.customResumeData;\n }\n\n resumableFilesData.push(data);\n });\n\n return resumableFilesData;\n },\n\n isAttemptingResume: function(id) {\n return handler._getFileState(id).attemptingResume;\n },\n\n isResumable: function(id) {\n return !!chunking && handler.isValid(id) &&\n !handler._getFileState(id).notResumable;\n },\n\n moveInProgressToRemaining: function(id, optInProgress, optRemaining) {\n var fileState = handler._getFileState(id) || {},\n chunkingState = fileState.chunking || {},\n inProgress = optInProgress || chunkingState.inProgress,\n remaining = optRemaining || chunkingState.remaining;\n\n if (inProgress) {\n log(qq.format(\"Moving these chunks from in-progress {}, to remaining.\", JSON.stringify(inProgress)));\n inProgress.reverse();\n qq.each(inProgress, function(idx, chunkIdx) {\n remaining.unshift(chunkIdx);\n });\n inProgress.length = 0;\n }\n },\n\n pause: function(id) {\n if (handler.isValid(id)) {\n log(qq.format(\"Aborting XHR upload for {} '{}' due to pause instruction.\", id, getName(id)));\n handler._getFileState(id).paused = true;\n abort(id);\n return true;\n }\n },\n\n reevaluateChunking: function(id) {\n if (chunking && handler.isValid(id)) {\n var state = handler._getFileState(id),\n totalChunks,\n i;\n\n delete state.chunking;\n\n state.chunking = {};\n totalChunks = handler._getTotalChunks(id);\n if (totalChunks > 1 || chunking.mandatory) {\n state.chunking.enabled = true;\n state.chunking.parts = totalChunks;\n state.chunking.remaining = [];\n\n for (i = 0; i < totalChunks; i++) {\n state.chunking.remaining.push(i);\n }\n\n handler._initTempState(id);\n }\n else {\n state.chunking.enabled = false;\n }\n }\n },\n\n updateBlob: function(id, newBlob) {\n if (handler.isValid(id)) {\n handler._getFileState(id).file = newBlob;\n }\n },\n\n _clearXhrs: function(id) {\n var tempState = handler._getFileState(id).temp;\n\n qq.each(tempState.ajaxRequesters, function(chunkId) {\n delete tempState.ajaxRequesters[chunkId];\n });\n\n qq.each(tempState.xhrs, function(chunkId) {\n delete tempState.xhrs[chunkId];\n });\n },\n\n /**\n * Creates an XHR instance for this file and stores it in the fileState.\n *\n * @param id File ID\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @returns {XMLHttpRequest}\n */\n _createXhr: function(id, optChunkIdx) {\n return handler._registerXhr(id, optChunkIdx, qq.createXhrInstance());\n },\n\n _getAjaxRequester: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.ajaxRequesters[chunkIdx];\n },\n\n _getChunkData: function(id, chunkIndex) {\n var chunkSize = getChunkSize(id),\n fileSize = getSize(id),\n fileOrBlob = handler.getFile(id),\n startBytes = chunkSize * chunkIndex,\n endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize,\n totalChunks = handler._getTotalChunks(id),\n cachedChunks = this._getFileState(id).temp.cachedChunks,\n\n // To work around a Webkit GC bug, we must keep each chunk `Blob` in scope until we are done with it.\n // See https://github.com/FineUploader/fine-uploader/issues/937#issuecomment-41418760\n blob = cachedChunks[chunkIndex] || qq.sliceBlob(fileOrBlob, startBytes, endBytes);\n\n cachedChunks[chunkIndex] = blob;\n\n return {\n part: chunkIndex,\n start: startBytes,\n end: endBytes,\n count: totalChunks,\n blob: blob,\n size: endBytes - startBytes\n };\n },\n\n _getChunkDataForCallback: function(chunkData) {\n return {\n partIndex: chunkData.part,\n startByte: chunkData.start + 1,\n endByte: chunkData.end,\n totalParts: chunkData.count\n };\n },\n\n /**\n * @param id File ID\n * @returns {string} Identifier for this item that may appear in the browser's local storage\n */\n _getLocalStorageId: function(id) {\n var formatVersion = \"5.0\",\n name = getName(id),\n size = getSize(id),\n chunkSize = getChunkSize(id),\n endpoint = getEndpoint(id),\n customKeys = resume.customKeys(id),\n localStorageId = qq.format(\"qq{}resume{}-{}-{}-{}-{}\", namespace, formatVersion, name, size, chunkSize, endpoint);\n\n customKeys.forEach(function(key) {\n localStorageId += \"-\" + key;\n });\n\n return localStorageId;\n },\n\n _getMimeType: function(id) {\n return handler.getFile(id).type;\n },\n\n _getPersistableData: function(id) {\n return handler._getFileState(id).chunking;\n },\n\n /**\n * @param id ID of the associated file\n * @returns {number} Number of parts this file can be divided into, or undefined if chunking is not supported in this UA\n */\n _getTotalChunks: function(id) {\n if (chunking) {\n var fileSize = getSize(id),\n chunkSize = getChunkSize(id);\n\n return Math.ceil(fileSize / chunkSize);\n }\n },\n\n _getXhr: function(id, optChunkIdx) {\n var chunkIdx = optChunkIdx == null ? -1 : optChunkIdx;\n return handler._getFileState(id).temp.xhrs[chunkIdx];\n },\n\n _getXhrs: function(id) {\n return handler._getFileState(id).temp.xhrs;\n },\n\n // Iterates through all XHR handler-created resume records (in local storage),\n // invoking the passed callback and passing in the key and value of each local storage record.\n _iterateResumeRecords: function(callback) {\n if (resumeEnabled) {\n qq.each(localStorage, function(key, item) {\n if (key.indexOf(qq.format(\"qq{}resume\", namespace)) === 0) {\n var uploadData = JSON.parse(item);\n callback(key, uploadData);\n }\n });\n }\n },\n\n _initTempState: function(id) {\n handler._getFileState(id).temp = {\n ajaxRequesters: {},\n chunkProgress: {},\n xhrs: {},\n cachedChunks: {}\n };\n },\n\n _markNotResumable: function(id) {\n handler._getFileState(id).notResumable = true;\n },\n\n // Removes a chunked upload record from local storage, if possible.\n // Returns true if the item was removed, false otherwise.\n _maybeDeletePersistedChunkData: function(id) {\n var localStorageId;\n\n if (resumeEnabled && handler.isResumable(id)) {\n localStorageId = handler._getLocalStorageId(id);\n\n if (localStorageId && localStorage.getItem(localStorageId)) {\n localStorage.removeItem(localStorageId);\n return true;\n }\n }\n\n return false;\n },\n\n // If this is a resumable upload, grab the relevant data from storage and items in memory that track this upload\n // so we can pick up from where we left off.\n _maybePrepareForResume: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // Resume is enabled and possible and this is the first time we've tried to upload this file in this session,\n // so prepare for a resume attempt.\n if (resumeEnabled && state.key === undefined) {\n localStorageId = handler._getLocalStorageId(id);\n persistedData = localStorage.getItem(localStorageId);\n\n // If we found this item in local storage, maybe we should resume it.\n if (persistedData) {\n persistedData = JSON.parse(persistedData);\n\n // If we found a resume record but we have already handled this file in this session,\n // don't try to resume it & ensure we don't persist future check data\n if (getDataByUuid(persistedData.uuid)) {\n handler._markNotResumable(id);\n }\n else {\n log(qq.format(\"Identified file with ID {} and name of {} as resumable.\", id, getName(id)));\n\n onUuidChanged(id, persistedData.uuid);\n\n state.key = persistedData.key;\n state.chunking = persistedData.chunking;\n state.loaded = persistedData.loaded;\n state.customResumeData = persistedData.customResumeData;\n state.attemptingResume = true;\n\n handler.moveInProgressToRemaining(id);\n }\n }\n }\n },\n\n // Persist any data needed to resume this upload in a new session.\n _maybePersistChunkedState: function(id) {\n var state = handler._getFileState(id),\n localStorageId, persistedData;\n\n // If local storage isn't supported by the browser, or if resume isn't enabled or possible, give up\n if (resumeEnabled && handler.isResumable(id)) {\n var customResumeData = getCustomResumeData(id);\n\n localStorageId = handler._getLocalStorageId(id);\n\n persistedData = {\n name: getName(id),\n size: getSize(id),\n uuid: getUuid(id),\n key: state.key,\n chunking: state.chunking,\n loaded: state.loaded,\n lastUpdated: Date.now(),\n };\n\n if (customResumeData) {\n persistedData.customResumeData = customResumeData;\n }\n\n try {\n localStorage.setItem(localStorageId, JSON.stringify(persistedData));\n }\n catch (error) {\n log(qq.format(\"Unable to save resume data for '{}' due to error: '{}'.\", id, error.toString()), \"warn\");\n }\n }\n },\n\n _registerProgressHandler: function(id, chunkIdx, chunkSize) {\n var xhr = handler._getXhr(id, chunkIdx),\n name = getName(id),\n progressCalculator = {\n simple: function(loaded, total) {\n var fileSize = getSize(id);\n\n if (loaded === total) {\n onProgress(id, name, fileSize, fileSize);\n }\n else {\n onProgress(id, name, (loaded >= fileSize ? fileSize - 1 : loaded), fileSize);\n }\n },\n\n chunked: function(loaded, total) {\n var chunkProgress = handler._getFileState(id).temp.chunkProgress,\n totalSuccessfullyLoadedForFile = handler._getFileState(id).loaded,\n loadedForRequest = loaded,\n totalForRequest = total,\n totalFileSize = getSize(id),\n estActualChunkLoaded = loadedForRequest - (totalForRequest - chunkSize),\n totalLoadedForFile = totalSuccessfullyLoadedForFile;\n\n chunkProgress[chunkIdx] = estActualChunkLoaded;\n\n qq.each(chunkProgress, function(chunkIdx, chunkLoaded) {\n totalLoadedForFile += chunkLoaded;\n });\n\n onProgress(id, name, totalLoadedForFile, totalFileSize);\n }\n };\n\n xhr.upload.onprogress = function(e) {\n if (e.lengthComputable) {\n /* jshint eqnull: true */\n var type = chunkSize == null ? \"simple\" : \"chunked\";\n progressCalculator[type](e.loaded, e.total);\n }\n };\n },\n\n /**\n * Registers an XHR transport instance created elsewhere.\n *\n * @param id ID of the associated file\n * @param optChunkIdx The chunk index associated with this XHR, if applicable\n * @param xhr XMLHttpRequest object instance\n * @param optAjaxRequester `qq.AjaxRequester` associated with this request, if applicable.\n * @returns {XMLHttpRequest}\n */\n _registerXhr: function(id, optChunkIdx, xhr, optAjaxRequester) {\n var xhrsId = optChunkIdx == null ? -1 : optChunkIdx,\n tempState = handler._getFileState(id).temp;\n\n tempState.xhrs = tempState.xhrs || {};\n tempState.ajaxRequesters = tempState.ajaxRequesters || {};\n\n tempState.xhrs[xhrsId] = xhr;\n\n if (optAjaxRequester) {\n tempState.ajaxRequesters[xhrsId] = optAjaxRequester;\n }\n\n return xhr;\n },\n\n // Deletes any local storage records that are \"expired\".\n _removeExpiredChunkingRecords: function() {\n var expirationDays = resume.recordsExpireIn;\n\n handler._iterateResumeRecords(function(key, uploadData) {\n var expirationDate = new Date(uploadData.lastUpdated);\n\n // transform updated date into expiration date\n expirationDate.setDate(expirationDate.getDate() + expirationDays);\n\n if (expirationDate.getTime() <= Date.now()) {\n log(\"Removing expired resume record with key \" + key);\n localStorage.removeItem(key);\n }\n });\n },\n\n /**\n * Determine if the associated file should be chunked.\n *\n * @param id ID of the associated file\n * @returns {*} true if chunking is enabled, possible, and the file can be split into more than 1 part\n */\n _shouldChunkThisFile: function(id) {\n var state = handler._getFileState(id);\n\n // file may no longer be available if it was recently cancelled\n if (state) {\n if (!state.chunking) {\n handler.reevaluateChunking(id);\n }\n\n return state.chunking.enabled;\n }\n }\n });\n};\n","/*globals qq, XMLHttpRequest*/\nqq.DeleteFileAjaxRequester = function(o) {\n \"use strict\";\n\n var requester,\n options = {\n method: \"DELETE\",\n uuidParamName: \"qquuid\",\n endpointStore: {},\n maxConnections: 3,\n customHeaders: function(id) {return {};},\n paramsStore: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n log: function(str, level) {},\n onDelete: function(id) {},\n onDeleteComplete: function(id, xhrOrXdr, isError) {}\n };\n\n qq.extend(options, o);\n\n function getMandatedParams() {\n if (options.method.toUpperCase() === \"POST\") {\n return {\n _method: \"DELETE\"\n };\n }\n\n return {};\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"POST\", \"DELETE\"],\n method: options.method,\n endpointStore: options.endpointStore,\n paramsStore: options.paramsStore,\n mandatedParams: getMandatedParams(),\n maxConnections: options.maxConnections,\n customHeaders: function(id) {\n return options.customHeaders.get(id);\n },\n log: options.log,\n onSend: options.onDelete,\n onComplete: options.onDeleteComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n sendDelete: function(id, uuid, additionalMandatedParams) {\n var additionalOptions = additionalMandatedParams || {};\n\n options.log(\"Submitting delete file request for \" + id);\n\n if (options.method === \"DELETE\") {\n requester.initTransport(id)\n .withPath(uuid)\n .withParams(additionalOptions)\n .send();\n }\n else {\n additionalOptions[options.uuidParamName] = uuid;\n requester.initTransport(id)\n .withParams(additionalOptions)\n .send();\n }\n }\n });\n};\n","/*global qq, define */\n/*jshint strict:false,bitwise:false,nonew:false,asi:true,-W064,-W116,-W089 */\n/**\n * Mega pixel image rendering library for iOS6+\n *\n * Fixes iOS6+'s image file rendering issue for large size image (over mega-pixel),\n * which causes unexpected subsampling when drawing it in canvas.\n * By using this library, you can safely render the image with proper stretching.\n *\n * Copyright (c) 2012 Shinichi Tomita \n * Released under the MIT license\n *\n * Heavily modified by Widen for Fine Uploader\n */\n(function() {\n\n /**\n * Detect subsampling in loaded image.\n * In iOS, larger images than 2M pixels may be subsampled in rendering.\n */\n function detectSubsampling(img) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n canvas = document.createElement(\"canvas\"),\n ctx;\n\n if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image\n canvas.width = canvas.height = 1;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, -iw + 1, 0);\n // subsampled image becomes half smaller in rendering size.\n // check alpha channel value to confirm image is covering edge pixel or not.\n // if alpha value is 0 image is not covering, hence subsampled.\n return ctx.getImageData(0, 0, 1, 1).data[3] === 0;\n } else {\n return false;\n }\n }\n\n /**\n * Detecting vertical squash in loaded image.\n * Fixes a bug which squash image vertically while drawing into canvas for some images.\n */\n function detectVerticalSquash(img, iw, ih) {\n var canvas = document.createElement(\"canvas\"),\n sy = 0,\n ey = ih,\n py = ih,\n ctx, data, alpha, ratio;\n\n canvas.width = 1;\n canvas.height = ih;\n ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n data = ctx.getImageData(0, 0, 1, ih).data;\n\n // search image edge pixel position in case it is squashed vertically.\n while (py > sy) {\n alpha = data[(py - 1) * 4 + 3];\n if (alpha === 0) {\n ey = py;\n } else {\n sy = py;\n }\n py = (ey + sy) >> 1;\n }\n\n ratio = (py / ih);\n return (ratio === 0) ? 1 : ratio;\n }\n\n /**\n * Rendering image element (with resizing) and get its data URL\n */\n function renderImageToDataURL(img, blob, options, doSquash) {\n var canvas = document.createElement(\"canvas\"),\n mime = options.mime || \"image/jpeg\",\n promise = new qq.Promise();\n\n renderImageToCanvas(img, blob, canvas, options, doSquash)\n .then(function() {\n promise.success(\n canvas.toDataURL(mime, options.quality || 0.8)\n );\n });\n\n return promise;\n }\n\n function maybeCalculateDownsampledDimensions(spec) {\n var maxPixels = 5241000; //iOS specific value\n\n if (!qq.ios()) {\n throw new qq.Error(\"Downsampled dimensions can only be reliably calculated for iOS!\");\n }\n\n if (spec.origHeight * spec.origWidth > maxPixels) {\n return {\n newHeight: Math.round(Math.sqrt(maxPixels * (spec.origHeight / spec.origWidth))),\n newWidth: Math.round(Math.sqrt(maxPixels * (spec.origWidth / spec.origHeight)))\n };\n }\n }\n\n /**\n * Rendering image element (with resizing) into the canvas element\n */\n function renderImageToCanvas(img, blob, canvas, options, doSquash) {\n var iw = img.naturalWidth,\n ih = img.naturalHeight,\n width = options.width,\n height = options.height,\n ctx = canvas.getContext(\"2d\"),\n promise = new qq.Promise(),\n modifiedDimensions;\n\n ctx.save();\n\n if (options.resize) {\n return renderImageToCanvasWithCustomResizer({\n blob: blob,\n canvas: canvas,\n image: img,\n imageHeight: ih,\n imageWidth: iw,\n orientation: options.orientation,\n resize: options.resize,\n targetHeight: height,\n targetWidth: width\n });\n }\n\n if (!qq.supportedFeatures.unlimitedScaledImageSize) {\n modifiedDimensions = maybeCalculateDownsampledDimensions({\n origWidth: width,\n origHeight: height\n });\n\n if (modifiedDimensions) {\n qq.log(qq.format(\"Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h\",\n width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),\n \"warn\");\n\n width = modifiedDimensions.newWidth;\n height = modifiedDimensions.newHeight;\n }\n }\n\n transformCoordinate(canvas, width, height, options.orientation);\n\n // Fine Uploader specific: Save some CPU cycles if not using iOS\n // Assumption: This logic is only needed to overcome iOS image sampling issues\n if (qq.ios()) {\n (function() {\n if (detectSubsampling(img)) {\n iw /= 2;\n ih /= 2;\n }\n\n var d = 1024, // size of tiling canvas\n tmpCanvas = document.createElement(\"canvas\"),\n vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,\n dw = Math.ceil(d * width / iw),\n dh = Math.ceil(d * height / ih / vertSquashRatio),\n sy = 0,\n dy = 0,\n tmpCtx, sx, dx;\n\n tmpCanvas.width = tmpCanvas.height = d;\n tmpCtx = tmpCanvas.getContext(\"2d\");\n\n while (sy < ih) {\n sx = 0;\n dx = 0;\n while (sx < iw) {\n tmpCtx.clearRect(0, 0, d, d);\n tmpCtx.drawImage(img, -sx, -sy);\n ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);\n sx += d;\n dx += dw;\n }\n sy += d;\n dy += dh;\n }\n ctx.restore();\n tmpCanvas = tmpCtx = null;\n }());\n }\n else {\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n canvas.qqImageRendered && canvas.qqImageRendered();\n promise.success();\n\n return promise;\n }\n\n function renderImageToCanvasWithCustomResizer(resizeInfo) {\n var blob = resizeInfo.blob,\n image = resizeInfo.image,\n imageHeight = resizeInfo.imageHeight,\n imageWidth = resizeInfo.imageWidth,\n orientation = resizeInfo.orientation,\n promise = new qq.Promise(),\n resize = resizeInfo.resize,\n sourceCanvas = document.createElement(\"canvas\"),\n sourceCanvasContext = sourceCanvas.getContext(\"2d\"),\n targetCanvas = resizeInfo.canvas,\n targetHeight = resizeInfo.targetHeight,\n targetWidth = resizeInfo.targetWidth;\n\n transformCoordinate(sourceCanvas, imageWidth, imageHeight, orientation);\n\n targetCanvas.height = targetHeight;\n targetCanvas.width = targetWidth;\n\n sourceCanvasContext.drawImage(image, 0, 0);\n\n resize({\n blob: blob,\n height: targetHeight,\n image: image,\n sourceCanvas: sourceCanvas,\n targetCanvas: targetCanvas,\n width: targetWidth\n })\n .then(\n function success() {\n targetCanvas.qqImageRendered && targetCanvas.qqImageRendered();\n promise.success();\n },\n promise.failure\n );\n\n return promise;\n }\n\n /**\n * Transform canvas coordination according to specified frame size and orientation\n * Orientation value is from EXIF tag\n */\n function transformCoordinate(canvas, width, height, orientation) {\n switch (orientation) {\n case 5:\n case 6:\n case 7:\n case 8:\n canvas.width = height;\n canvas.height = width;\n break;\n default:\n canvas.width = width;\n canvas.height = height;\n }\n var ctx = canvas.getContext(\"2d\");\n switch (orientation) {\n case 2:\n // horizontal flip\n ctx.translate(width, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n // 180 rotate left\n ctx.translate(width, height);\n ctx.rotate(Math.PI);\n break;\n case 4:\n // vertical flip\n ctx.translate(0, height);\n ctx.scale(1, -1);\n break;\n case 5:\n // vertical flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.scale(1, -1);\n break;\n case 6:\n // 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -height);\n break;\n case 7:\n // horizontal flip + 90 rotate right\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(width, -height);\n ctx.scale(-1, 1);\n break;\n case 8:\n // 90 rotate left\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-width, 0);\n break;\n default:\n break;\n }\n }\n\n /**\n * MegaPixImage class\n */\n function MegaPixImage(srcImage, errorCallback) {\n var self = this;\n\n if (window.Blob && srcImage instanceof Blob) {\n (function() {\n var img = new Image(),\n URL = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;\n if (!URL) { throw Error(\"No createObjectURL function found to create blob url\"); }\n img.src = URL.createObjectURL(srcImage);\n self.blob = srcImage;\n srcImage = img;\n }());\n }\n if (!srcImage.naturalWidth && !srcImage.naturalHeight) {\n srcImage.onload = function() {\n var listeners = self.imageLoadListeners;\n if (listeners) {\n self.imageLoadListeners = null;\n // IE11 doesn't reliably report actual image dimensions immediately after onload for small files,\n // so let's push this to the end of the UI thread queue.\n setTimeout(function() {\n for (var i = 0, len = listeners.length; i < len; i++) {\n listeners[i]();\n }\n }, 0);\n }\n };\n srcImage.onerror = errorCallback;\n this.imageLoadListeners = [];\n }\n this.srcImage = srcImage;\n }\n\n /**\n * Rendering megapix image into specified target element\n */\n MegaPixImage.prototype.render = function(target, options) {\n options = options || {};\n\n var self = this,\n imgWidth = this.srcImage.naturalWidth,\n imgHeight = this.srcImage.naturalHeight,\n width = options.width,\n height = options.height,\n maxWidth = options.maxWidth,\n maxHeight = options.maxHeight,\n doSquash = !this.blob || this.blob.type === \"image/jpeg\",\n tagName = target.tagName.toLowerCase(),\n opt;\n\n if (this.imageLoadListeners) {\n this.imageLoadListeners.push(function() { self.render(target, options); });\n return;\n }\n\n if (width && !height) {\n height = (imgHeight * width / imgWidth) << 0;\n } else if (height && !width) {\n width = (imgWidth * height / imgHeight) << 0;\n } else {\n width = imgWidth;\n height = imgHeight;\n }\n if (maxWidth && width > maxWidth) {\n width = maxWidth;\n height = (imgHeight * width / imgWidth) << 0;\n }\n if (maxHeight && height > maxHeight) {\n height = maxHeight;\n width = (imgWidth * height / imgHeight) << 0;\n }\n\n opt = { width: width, height: height },\n qq.each(options, function(optionsKey, optionsValue) {\n opt[optionsKey] = optionsValue;\n });\n\n if (tagName === \"img\") {\n (function() {\n var oldTargetSrc = target.src;\n renderImageToDataURL(self.srcImage, self.blob, opt, doSquash)\n .then(function(dataUri) {\n target.src = dataUri;\n oldTargetSrc === target.src && target.onload();\n });\n }());\n } else if (tagName === \"canvas\") {\n renderImageToCanvas(this.srcImage, this.blob, target, opt, doSquash);\n }\n if (typeof this.onrender === \"function\") {\n this.onrender(target);\n }\n };\n\n qq.MegaPixImage = MegaPixImage;\n})();\n","/*globals qq */\n/**\n * Draws a thumbnail of a Blob/File/URL onto an or .\n *\n * @constructor\n */\nqq.ImageGenerator = function(log) {\n \"use strict\";\n\n function isImg(el) {\n return el.tagName.toLowerCase() === \"img\";\n }\n\n function isCanvas(el) {\n return el.tagName.toLowerCase() === \"canvas\";\n }\n\n function isImgCorsSupported() {\n return new Image().crossOrigin !== undefined;\n }\n\n function isCanvasSupported() {\n var canvas = document.createElement(\"canvas\");\n\n return canvas.getContext && canvas.getContext(\"2d\");\n }\n\n // This is only meant to determine the MIME type of a renderable image file.\n // It is used to ensure images drawn from a URL that have transparent backgrounds\n // are rendered correctly, among other things.\n function determineMimeOfFileName(nameWithPath) {\n /*jshint -W015 */\n var pathSegments = nameWithPath.split(\"/\"),\n name = pathSegments[pathSegments.length - 1].split(\"?\")[0],\n extension = qq.getExtension(name);\n\n extension = extension && extension.toLowerCase();\n\n switch (extension) {\n case \"jpeg\":\n case \"jpg\":\n return \"image/jpeg\";\n case \"png\":\n return \"image/png\";\n case \"bmp\":\n return \"image/bmp\";\n case \"gif\":\n return \"image/gif\";\n case \"tiff\":\n case \"tif\":\n return \"image/tiff\";\n }\n }\n\n // This will likely not work correctly in IE8 and older.\n // It's only used as part of a formula to determine\n // if a canvas can be used to scale a server-hosted thumbnail.\n // If canvas isn't supported by the UA (IE8 and older)\n // this method should not even be called.\n function isCrossOrigin(url) {\n var targetAnchor = document.createElement(\"a\"),\n targetProtocol, targetHostname, targetPort;\n\n targetAnchor.href = url;\n\n targetProtocol = targetAnchor.protocol;\n targetPort = targetAnchor.port;\n targetHostname = targetAnchor.hostname;\n\n if (targetProtocol.toLowerCase() !== window.location.protocol.toLowerCase()) {\n return true;\n }\n\n if (targetHostname.toLowerCase() !== window.location.hostname.toLowerCase()) {\n return true;\n }\n\n // IE doesn't take ports into consideration when determining if two endpoints are same origin.\n if (targetPort !== window.location.port && !qq.ie()) {\n return true;\n }\n\n return false;\n }\n\n function registerImgLoadListeners(img, promise) {\n img.onload = function() {\n img.onload = null;\n img.onerror = null;\n promise.success(img);\n };\n\n img.onerror = function() {\n img.onload = null;\n img.onerror = null;\n log(\"Problem drawing thumbnail!\", \"error\");\n promise.failure(img, \"Problem drawing thumbnail!\");\n };\n }\n\n function registerCanvasDrawImageListener(canvas, promise) {\n // The image is drawn on the canvas by a third-party library,\n // and we want to know when this is completed. Since the library\n // may invoke drawImage many times in a loop, we need to be called\n // back when the image is fully rendered. So, we are expecting the\n // code that draws this image to follow a convention that involves a\n // function attached to the canvas instance be invoked when it is done.\n canvas.qqImageRendered = function() {\n promise.success(canvas);\n };\n }\n\n // Fulfills a `qq.Promise` when an image has been drawn onto the target,\n // whether that is a or an . The attempt is considered a\n // failure if the target is not an or a , or if the drawing\n // attempt was not successful.\n function registerThumbnailRenderedListener(imgOrCanvas, promise) {\n var registered = isImg(imgOrCanvas) || isCanvas(imgOrCanvas);\n\n if (isImg(imgOrCanvas)) {\n registerImgLoadListeners(imgOrCanvas, promise);\n }\n else if (isCanvas(imgOrCanvas)) {\n registerCanvasDrawImageListener(imgOrCanvas, promise);\n }\n else {\n promise.failure(imgOrCanvas);\n log(qq.format(\"Element container of type {} is not supported!\", imgOrCanvas.tagName), \"error\");\n }\n\n return registered;\n }\n\n // Draw a preview iff the current UA can natively display it.\n // Also rotate the image if necessary.\n function draw(fileOrBlob, container, options) {\n var drawPreview = new qq.Promise(),\n identifier = new qq.Identify(fileOrBlob, log),\n maxSize = options.maxSize,\n // jshint eqnull:true\n orient = options.orient == null ? true : options.orient,\n megapixErrorHandler = function() {\n container.onerror = null;\n container.onload = null;\n log(\"Could not render preview, file may be too large!\", \"error\");\n drawPreview.failure(container, \"Browser cannot render image!\");\n };\n\n identifier.isPreviewable().then(\n function(mime) {\n // If options explicitly specify that Orientation is not desired,\n // replace the orient task with a dummy promise that \"succeeds\" immediately.\n var dummyExif = {\n parse: function() {\n return new qq.Promise().success();\n }\n },\n exif = orient ? new qq.Exif(fileOrBlob, log) : dummyExif,\n mpImg = new qq.MegaPixImage(fileOrBlob, megapixErrorHandler);\n\n if (registerThumbnailRenderedListener(container, drawPreview)) {\n exif.parse().then(\n function(exif) {\n var orientation = exif && exif.Orientation;\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n orientation: orientation,\n mime: mime,\n resize: options.customResizeFunction\n });\n },\n\n function(failureMsg) {\n log(qq.format(\"EXIF data could not be parsed ({}). Assuming orientation = 1.\", failureMsg));\n\n mpImg.render(container, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: mime,\n resize: options.customResizeFunction\n });\n }\n );\n }\n },\n\n function() {\n log(\"Not previewable\");\n drawPreview.failure(container, \"Not previewable\");\n }\n );\n\n return drawPreview;\n }\n\n function drawOnCanvasOrImgFromUrl(url, canvasOrImg, draw, maxSize, customResizeFunction) {\n var tempImg = new Image(),\n tempImgRender = new qq.Promise();\n\n registerThumbnailRenderedListener(tempImg, tempImgRender);\n\n if (isCrossOrigin(url)) {\n tempImg.crossOrigin = \"anonymous\";\n }\n\n tempImg.src = url;\n\n tempImgRender.then(\n function rendered() {\n registerThumbnailRenderedListener(canvasOrImg, draw);\n\n var mpImg = new qq.MegaPixImage(tempImg);\n mpImg.render(canvasOrImg, {\n maxWidth: maxSize,\n maxHeight: maxSize,\n mime: determineMimeOfFileName(url),\n resize: customResizeFunction\n });\n },\n\n draw.failure\n );\n }\n\n function drawOnImgFromUrlWithCssScaling(url, img, draw, maxSize) {\n registerThumbnailRenderedListener(img, draw);\n // NOTE: The fact that maxWidth/height is set on the thumbnail for scaled images\n // that must drop back to CSS is known and exploited by the templating module.\n // In this module, we pre-render \"waiting\" thumbs for all files immediately after they\n // are submitted, and we must be sure to pass any style associated with the \"waiting\" preview.\n qq(img).css({\n maxWidth: maxSize + \"px\",\n maxHeight: maxSize + \"px\"\n });\n\n img.src = url;\n }\n\n // Draw a (server-hosted) thumbnail given a URL.\n // This will optionally scale the thumbnail as well.\n // It attempts to use to scale, but will fall back\n // to max-width and max-height style properties if the UA\n // doesn't support canvas or if the images is cross-domain and\n // the UA doesn't support the crossorigin attribute on img tags,\n // which is required to scale a cross-origin image using &\n // then export it back to an .\n function drawFromUrl(url, container, options) {\n var draw = new qq.Promise(),\n scale = options.scale,\n maxSize = scale ? options.maxSize : null;\n\n // container is an img, scaling needed\n if (scale && isImg(container)) {\n // Iff canvas is available in this UA, try to use it for scaling.\n // Otherwise, fall back to CSS scaling\n if (isCanvasSupported()) {\n // Attempt to use for image scaling,\n // but we must fall back to scaling via CSS/styles\n // if this is a cross-origin image and the UA doesn't support CORS.\n if (isCrossOrigin(url) && !isImgCorsSupported()) {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n else {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n }\n else {\n drawOnImgFromUrlWithCssScaling(url, container, draw, maxSize);\n }\n }\n // container is a canvas, scaling optional\n else if (isCanvas(container)) {\n drawOnCanvasOrImgFromUrl(url, container, draw, maxSize);\n }\n // container is an img & no scaling: just set the src attr to the passed url\n else if (registerThumbnailRenderedListener(container, draw)) {\n container.src = url;\n }\n\n return draw;\n }\n\n qq.extend(this, {\n /**\n * Generate a thumbnail. Depending on the arguments, this may either result in\n * a client-side rendering of an image (if a `Blob` is supplied) or a server-generated\n * image that may optionally be scaled client-side using or CSS/styles (as a fallback).\n *\n * @param fileBlobOrUrl a `File`, `Blob`, or a URL pointing to the image\n * @param container or to contain the preview\n * @param options possible properties include `maxSize` (int), `orient` (bool - default true), resize` (bool - default true), and `customResizeFunction`.\n * @returns qq.Promise fulfilled when the preview has been drawn, or the attempt has failed\n */\n generate: function(fileBlobOrUrl, container, options) {\n if (qq.isString(fileBlobOrUrl)) {\n log(\"Attempting to update thumbnail based on server response.\");\n return drawFromUrl(fileBlobOrUrl, container, options || {});\n }\n else {\n log(\"Attempting to draw client-side image preview.\");\n return draw(fileBlobOrUrl, container, options || {});\n }\n }\n });\n\n /**/\n this._testing = {};\n this._testing.isImg = isImg;\n this._testing.isCanvas = isCanvas;\n this._testing.isCrossOrigin = isCrossOrigin;\n this._testing.determineMimeOfFileName = determineMimeOfFileName;\n /**/\n};\n","/*globals qq */\n/**\n * EXIF image data parser. Currently only parses the Orientation tag value,\n * but this may be expanded to other tags in the future.\n *\n * @param fileOrBlob Attempt to parse EXIF data in this `Blob`\n * @constructor\n */\nqq.Exif = function(fileOrBlob, log) {\n \"use strict\";\n\n // Orientation is the only tag parsed here at this time.\n var TAG_IDS = [274],\n TAG_INFO = {\n 274: {\n name: \"Orientation\",\n bytes: 2\n }\n };\n\n // Convert a little endian (hex string) to big endian (decimal).\n function parseLittleEndian(hex) {\n var result = 0,\n pow = 0;\n\n while (hex.length > 0) {\n result += parseInt(hex.substring(0, 2), 16) * Math.pow(2, pow);\n hex = hex.substring(2, hex.length);\n pow += 8;\n }\n\n return result;\n }\n\n // Find the byte offset, of Application Segment 1 (EXIF).\n // External callers need not supply any arguments.\n function seekToApp1(offset, promise) {\n var theOffset = offset,\n thePromise = promise;\n if (theOffset === undefined) {\n theOffset = 2;\n thePromise = new qq.Promise();\n }\n\n qq.readBlobToHex(fileOrBlob, theOffset, 4).then(function(hex) {\n var match = /^ffe([0-9])/.exec(hex),\n segmentLength;\n\n if (match) {\n if (match[1] !== \"1\") {\n segmentLength = parseInt(hex.slice(4, 8), 16);\n seekToApp1(theOffset + segmentLength + 2, thePromise);\n }\n else {\n thePromise.success(theOffset);\n }\n }\n else {\n thePromise.failure(\"No EXIF header to be found!\");\n }\n });\n\n return thePromise;\n }\n\n // Find the byte offset of Application Segment 1 (EXIF) for valid JPEGs only.\n function getApp1Offset() {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, 0, 6).then(function(hex) {\n if (hex.indexOf(\"ffd8\") !== 0) {\n promise.failure(\"Not a valid JPEG!\");\n }\n else {\n seekToApp1().then(function(offset) {\n promise.success(offset);\n },\n function(error) {\n promise.failure(error);\n });\n }\n });\n\n return promise;\n }\n\n // Determine the byte ordering of the EXIF header.\n function isLittleEndian(app1Start) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 10, 2).then(function(hex) {\n promise.success(hex === \"4949\");\n });\n\n return promise;\n }\n\n // Determine the number of directory entries in the EXIF header.\n function getDirEntryCount(app1Start, littleEndian) {\n var promise = new qq.Promise();\n\n qq.readBlobToHex(fileOrBlob, app1Start + 18, 2).then(function(hex) {\n if (littleEndian) {\n return promise.success(parseLittleEndian(hex));\n }\n else {\n promise.success(parseInt(hex, 16));\n }\n });\n\n return promise;\n }\n\n // Get the IFD portion of the EXIF header as a hex string.\n function getIfd(app1Start, dirEntries) {\n var offset = app1Start + 20,\n bytes = dirEntries * 12;\n\n return qq.readBlobToHex(fileOrBlob, offset, bytes);\n }\n\n // Obtain an array of all directory entries (as hex strings) in the EXIF header.\n function getDirEntries(ifdHex) {\n var entries = [],\n offset = 0;\n\n while (offset + 24 <= ifdHex.length) {\n entries.push(ifdHex.slice(offset, offset + 24));\n offset += 24;\n }\n\n return entries;\n }\n\n // Obtain values for all relevant tags and return them.\n function getTagValues(littleEndian, dirEntries) {\n var TAG_VAL_OFFSET = 16,\n tagsToFind = qq.extend([], TAG_IDS),\n vals = {};\n\n qq.each(dirEntries, function(idx, entry) {\n var idHex = entry.slice(0, 4),\n id = littleEndian ? parseLittleEndian(idHex) : parseInt(idHex, 16),\n tagsToFindIdx = tagsToFind.indexOf(id),\n tagValHex, tagName, tagValLength;\n\n if (tagsToFindIdx >= 0) {\n tagName = TAG_INFO[id].name;\n tagValLength = TAG_INFO[id].bytes;\n tagValHex = entry.slice(TAG_VAL_OFFSET, TAG_VAL_OFFSET + (tagValLength * 2));\n vals[tagName] = littleEndian ? parseLittleEndian(tagValHex) : parseInt(tagValHex, 16);\n\n tagsToFind.splice(tagsToFindIdx, 1);\n }\n\n if (tagsToFind.length === 0) {\n return false;\n }\n });\n\n return vals;\n }\n\n qq.extend(this, {\n /**\n * Attempt to parse the EXIF header for the `Blob` associated with this instance.\n *\n * @returns {qq.Promise} To be fulfilled when the parsing is complete.\n * If successful, the parsed EXIF header as an object will be included.\n */\n parse: function() {\n var parser = new qq.Promise(),\n onParseFailure = function(message) {\n log(qq.format(\"EXIF header parse failed: '{}' \", message));\n parser.failure(message);\n };\n\n getApp1Offset().then(function(app1Offset) {\n log(qq.format(\"Moving forward with EXIF header parsing for '{}'\", fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name));\n\n isLittleEndian(app1Offset).then(function(littleEndian) {\n\n log(qq.format(\"EXIF Byte order is {} endian\", littleEndian ? \"little\" : \"big\"));\n\n getDirEntryCount(app1Offset, littleEndian).then(function(dirEntryCount) {\n\n log(qq.format(\"Found {} APP1 directory entries\", dirEntryCount));\n\n getIfd(app1Offset, dirEntryCount).then(function(ifdHex) {\n var dirEntries = getDirEntries(ifdHex),\n tagValues = getTagValues(littleEndian, dirEntries);\n\n log(\"Successfully parsed some EXIF tags\");\n\n parser.success(tagValues);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n }, onParseFailure);\n\n return parser;\n }\n });\n\n /**/\n this._testing = {};\n this._testing.parseLittleEndian = parseLittleEndian;\n /**/\n};\n","/*globals qq */\nqq.Identify = function(fileOrBlob, log) {\n \"use strict\";\n\n function isIdentifiable(magicBytes, questionableBytes) {\n var identifiable = false,\n magicBytesEntries = [].concat(magicBytes);\n\n qq.each(magicBytesEntries, function(idx, magicBytesArrayEntry) {\n if (questionableBytes.indexOf(magicBytesArrayEntry) === 0) {\n identifiable = true;\n return false;\n }\n });\n\n return identifiable;\n }\n\n qq.extend(this, {\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by reading magic\n * bytes in the beginning of the file, so this is an asynchronous operation. Before we attempt to read the\n * file, we will examine the blob's type attribute to save CPU cycles.\n *\n * @returns {qq.Promise} Promise that is fulfilled when identification is complete.\n * If successful, the MIME string is passed to the success handler.\n */\n isPreviewable: function() {\n var self = this,\n identifier = new qq.Promise(),\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n log(qq.format(\"Attempting to determine if {} can be rendered in this browser\", name));\n\n log(\"First pass: check type attribute of blob object.\");\n\n if (this.isPreviewableSync()) {\n log(\"Second pass: check for magic bytes in file header.\");\n\n qq.readBlobToHex(fileOrBlob, 0, 4).then(function(hex) {\n qq.each(self.PREVIEWABLE_MIME_TYPES, function(mime, bytes) {\n if (isIdentifiable(bytes, hex)) {\n // Safari is the only supported browser that can deal with TIFFs natively,\n // so, if this is a TIFF and the UA isn't Safari, declare this file \"non-previewable\".\n if (mime !== \"image/tiff\" || qq.supportedFeatures.tiffPreviews) {\n previewable = true;\n identifier.success(mime);\n }\n\n return false;\n }\n });\n\n log(qq.format(\"'{}' is {} able to be rendered in this browser\", name, previewable ? \"\" : \"NOT\"));\n\n if (!previewable) {\n identifier.failure();\n }\n },\n function() {\n log(\"Error reading file w/ name '\" + name + \"'. Not able to be rendered in this browser.\");\n identifier.failure();\n });\n }\n else {\n identifier.failure();\n }\n\n return identifier;\n },\n\n /**\n * Determines if a Blob can be displayed natively in the current browser. This is done by checking the\n * blob's type attribute. This is a synchronous operation, useful for situations where an asynchronous operation\n * would be challenging to support. Note that the blob's type property is not as accurate as reading the\n * file's magic bytes.\n *\n * @returns {Boolean} true if the blob can be rendered in the current browser\n */\n isPreviewableSync: function() {\n var fileMime = fileOrBlob.type,\n // Assumption: This will only ever be executed in browsers that support `Object.keys`.\n isRecognizedImage = qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES), fileMime) >= 0,\n previewable = false,\n name = fileOrBlob.name === undefined ? \"blob\" : fileOrBlob.name;\n\n if (isRecognizedImage) {\n if (fileMime === \"image/tiff\") {\n previewable = qq.supportedFeatures.tiffPreviews;\n }\n else {\n previewable = true;\n }\n }\n\n !previewable && log(name + \" is not previewable in this browser per the blob's type attr\");\n\n return previewable;\n }\n });\n};\n\nqq.Identify.prototype.PREVIEWABLE_MIME_TYPES = {\n \"image/jpeg\": \"ffd8ff\",\n \"image/gif\": \"474946\",\n \"image/png\": \"89504e\",\n \"image/bmp\": \"424d\",\n \"image/tiff\": [\"49492a00\", \"4d4d002a\"]\n};\n","/*globals qq*/\n/**\n * Attempts to validate an image, wherever possible.\n *\n * @param blob File or Blob representing a user-selecting image.\n * @param log Uses this to post log messages to the console.\n * @constructor\n */\nqq.ImageValidation = function(blob, log) {\n \"use strict\";\n\n /**\n * @param limits Object with possible image-related limits to enforce.\n * @returns {boolean} true if at least one of the limits has a non-zero value\n */\n function hasNonZeroLimits(limits) {\n var atLeastOne = false;\n\n qq.each(limits, function(limit, value) {\n if (value > 0) {\n atLeastOne = true;\n return false;\n }\n });\n\n return atLeastOne;\n }\n\n /**\n * @returns {qq.Promise} The promise is a failure if we can't obtain the width & height.\n * Otherwise, `success` is called on the returned promise with an object containing\n * `width` and `height` properties.\n */\n function getWidthHeight() {\n var sizeDetermination = new qq.Promise();\n\n new qq.Identify(blob, log).isPreviewable().then(function() {\n var image = new Image(),\n url = window.URL && window.URL.createObjectURL ? window.URL :\n window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :\n null;\n\n if (url) {\n image.onerror = function() {\n log(\"Cannot determine dimensions for image. May be too large.\", \"error\");\n sizeDetermination.failure();\n };\n\n image.onload = function() {\n sizeDetermination.success({\n width: this.width,\n height: this.height\n });\n };\n\n image.src = url.createObjectURL(blob);\n }\n else {\n log(\"No createObjectURL function available to generate image URL!\", \"error\");\n sizeDetermination.failure();\n }\n }, sizeDetermination.failure);\n\n return sizeDetermination;\n }\n\n /**\n *\n * @param limits Object with possible image-related limits to enforce.\n * @param dimensions Object containing `width` & `height` properties for the image to test.\n * @returns {String || undefined} The name of the failing limit. Undefined if no failing limits.\n */\n function getFailingLimit(limits, dimensions) {\n var failingLimit;\n\n qq.each(limits, function(limitName, limitValue) {\n if (limitValue > 0) {\n var limitMatcher = /(max|min)(Width|Height)/.exec(limitName),\n dimensionPropName = limitMatcher[2].charAt(0).toLowerCase() + limitMatcher[2].slice(1),\n actualValue = dimensions[dimensionPropName];\n\n /*jshint -W015*/\n switch (limitMatcher[1]) {\n case \"min\":\n if (actualValue < limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n case \"max\":\n if (actualValue > limitValue) {\n failingLimit = limitName;\n return false;\n }\n break;\n }\n }\n });\n\n return failingLimit;\n }\n\n /**\n * Validate the associated blob.\n *\n * @param limits\n * @returns {qq.Promise} `success` is called on the promise is the image is valid or\n * if the blob is not an image, or if the image is not verifiable.\n * Otherwise, `failure` with the name of the failing limit.\n */\n this.validate = function(limits) {\n var validationEffort = new qq.Promise();\n\n log(\"Attempting to validate image.\");\n\n if (hasNonZeroLimits(limits)) {\n getWidthHeight().then(function(dimensions) {\n var failingLimit = getFailingLimit(limits, dimensions);\n\n if (failingLimit) {\n validationEffort.failure(failingLimit);\n }\n else {\n validationEffort.success();\n }\n }, validationEffort.success);\n }\n else {\n validationEffort.success();\n }\n\n return validationEffort;\n };\n};\n","/* globals qq */\n/**\n * Module used to control populating the initial list of files.\n *\n * @constructor\n */\nqq.Session = function(spec) {\n \"use strict\";\n\n var options = {\n endpoint: null,\n params: {},\n customHeaders: {},\n cors: {},\n addFileRecord: function(sessionData) {},\n log: function(message, level) {}\n };\n\n qq.extend(options, spec, true);\n\n function isJsonResponseValid(response) {\n if (qq.isArray(response)) {\n return true;\n }\n\n options.log(\"Session response is not an array.\", \"error\");\n }\n\n function handleFileItems(fileItems, success, xhrOrXdr, promise) {\n var someItemsIgnored = false;\n\n success = success && isJsonResponseValid(fileItems);\n\n if (success) {\n qq.each(fileItems, function(idx, fileItem) {\n /* jshint eqnull:true */\n if (fileItem.uuid == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid UUID - ignoring.\", idx), \"error\");\n }\n else if (fileItem.name == null) {\n someItemsIgnored = true;\n options.log(qq.format(\"Session response item {} did not include a valid name - ignoring.\", idx), \"error\");\n }\n else {\n try {\n options.addFileRecord(fileItem);\n return true;\n }\n catch (err) {\n someItemsIgnored = true;\n options.log(err.message, \"error\");\n }\n }\n\n return false;\n });\n }\n\n promise[success && !someItemsIgnored ? \"success\" : \"failure\"](fileItems, xhrOrXdr);\n }\n\n // Initiate a call to the server that will be used to populate the initial file list.\n // Returns a `qq.Promise`.\n this.refresh = function() {\n /*jshint indent:false */\n var refreshEffort = new qq.Promise(),\n refreshCompleteCallback = function(response, success, xhrOrXdr) {\n handleFileItems(response, success, xhrOrXdr, refreshEffort);\n },\n requesterOptions = qq.extend({}, options),\n requester = new qq.SessionAjaxRequester(\n qq.extend(requesterOptions, {onComplete: refreshCompleteCallback})\n );\n\n requester.queryServer();\n\n return refreshEffort;\n };\n};\n","/*globals qq, XMLHttpRequest*/\n/**\n * Thin module used to send GET requests to the server, expecting information about session\n * data used to initialize an uploader instance.\n *\n * @param spec Various options used to influence the associated request.\n * @constructor\n */\nqq.SessionAjaxRequester = function(spec) {\n \"use strict\";\n\n var requester,\n options = {\n endpoint: null,\n customHeaders: {},\n params: {},\n cors: {\n expected: false,\n sendCredentials: false\n },\n onComplete: function(response, success, xhrOrXdr) {},\n log: function(str, level) {}\n };\n\n qq.extend(options, spec);\n\n function onComplete(id, xhrOrXdr, isError) {\n var response = null;\n\n /* jshint eqnull:true */\n if (xhrOrXdr.responseText != null) {\n try {\n response = qq.parseJson(xhrOrXdr.responseText);\n }\n catch (err) {\n options.log(\"Problem parsing session response: \" + err.message, \"error\");\n isError = true;\n }\n }\n\n options.onComplete(response, !isError, xhrOrXdr);\n }\n\n requester = qq.extend(this, new qq.AjaxRequester({\n acceptHeader: \"application/json\",\n validMethods: [\"GET\"],\n method: \"GET\",\n endpointStore: {\n get: function() {\n return options.endpoint;\n }\n },\n customHeaders: options.customHeaders,\n log: options.log,\n onComplete: onComplete,\n cors: options.cors\n }));\n\n qq.extend(this, {\n queryServer: function() {\n var params = qq.extend({}, options.params);\n\n options.log(\"Session query request.\");\n\n requester.initTransport(\"sessionRefresh\")\n .withParams(params)\n .withCacheBuster()\n .send();\n }\n });\n};\n","/* globals qq, ExifRestorer */\n/**\n * Controls generation of scaled images based on a reference image encapsulated in a `File` or `Blob`.\n * Scaled images are generated and converted to blobs on-demand.\n * Multiple scaled images per reference image with varying sizes and other properties are supported.\n *\n * @param spec Information about the scaled images to generate.\n * @param log Logger instance\n * @constructor\n */\nqq.Scaler = function(spec, log) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizer,\n includeOriginal = spec.sendOriginal,\n orient = spec.orient,\n defaultType = spec.defaultType,\n defaultQuality = spec.defaultQuality / 100,\n failedToScaleText = spec.failureText,\n includeExif = spec.includeExif,\n sizes = this._getSortedSizes(spec.sizes);\n\n // Revealed API for instances of this module\n qq.extend(this, {\n // If no targeted sizes have been declared or if this browser doesn't support\n // client-side image preview generation, there is no scaling to do.\n enabled: qq.supportedFeatures.scaling && sizes.length > 0,\n\n getFileRecords: function(originalFileUuid, originalFileName, originalBlobOrBlobData) {\n var self = this,\n records = [],\n originalBlob = originalBlobOrBlobData.blob ? originalBlobOrBlobData.blob : originalBlobOrBlobData,\n identifier = new qq.Identify(originalBlob, log);\n\n // If the reference file cannot be rendered natively, we can't create scaled versions.\n if (identifier.isPreviewableSync()) {\n // Create records for each scaled version & add them to the records array, smallest first.\n qq.each(sizes, function(idx, sizeRecord) {\n var outputType = self._determineOutputType({\n defaultType: defaultType,\n requestedType: sizeRecord.type,\n refType: originalBlob.type\n });\n\n records.push({\n uuid: qq.getUniqueId(),\n name: self._getName(originalFileName, {\n name: sizeRecord.name,\n type: outputType,\n refType: originalBlob.type\n }),\n blob: new qq.BlobProxy(originalBlob,\n qq.bind(self._generateScaledImage, self, {\n customResizeFunction: customResizeFunction,\n maxSize: sizeRecord.maxSize,\n orient: orient,\n type: outputType,\n quality: defaultQuality,\n failedText: failedToScaleText,\n includeExif: includeExif,\n log: log\n }))\n });\n });\n\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: includeOriginal ? originalBlob : null\n });\n }\n else {\n records.push({\n uuid: originalFileUuid,\n name: originalFileName,\n size: originalBlob.size,\n blob: originalBlob\n });\n }\n\n return records;\n },\n\n handleNewFile: function(file, name, uuid, size, fileList, batchId, uuidParamName, api) {\n var self = this,\n buttonId = file.qqButtonId || (file.blob && file.blob.qqButtonId),\n scaledIds = [],\n originalId = null,\n addFileToHandler = api.addFileToHandler,\n uploadData = api.uploadData,\n paramsStore = api.paramsStore,\n proxyGroupId = qq.getUniqueId();\n\n qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {\n var blobSize = record.size,\n id;\n\n if (record.blob instanceof qq.BlobProxy) {\n blobSize = -1;\n }\n\n id = uploadData.addFile({\n uuid: record.uuid,\n name: record.name,\n size: blobSize,\n batchId: batchId,\n proxyGroupId: proxyGroupId\n });\n\n if (record.blob instanceof qq.BlobProxy) {\n scaledIds.push(id);\n }\n else {\n originalId = id;\n }\n\n if (record.blob) {\n addFileToHandler(id, record.blob);\n fileList.push({id: id, file: record.blob});\n }\n else {\n uploadData.setStatus(id, qq.status.REJECTED);\n }\n });\n\n // If we are potentially uploading an original file and some scaled versions,\n // ensure the scaled versions include reference's to the parent's UUID and size\n // in their associated upload requests.\n if (originalId !== null) {\n qq.each(scaledIds, function(idx, scaledId) {\n var params = {\n qqparentuuid: uploadData.retrieve({id: originalId}).uuid,\n qqparentsize: uploadData.retrieve({id: originalId}).size\n };\n\n // Make sure the UUID for each scaled image is sent with the upload request,\n // to be consistent (since we may need to ensure it is sent for the original file as well).\n params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;\n\n uploadData.setParentId(scaledId, originalId);\n paramsStore.addReadOnly(scaledId, params);\n });\n\n // If any scaled images are tied to this parent image, be SURE we send its UUID as an upload request\n // parameter as well.\n if (scaledIds.length) {\n (function() {\n var param = {};\n param[uuidParamName] = uploadData.retrieve({id: originalId}).uuid;\n paramsStore.addReadOnly(originalId, param);\n }());\n }\n }\n }\n });\n};\n\nqq.extend(qq.Scaler.prototype, {\n scaleImage: function(id, specs, api) {\n \"use strict\";\n\n if (!qq.supportedFeatures.scaling) {\n throw new qq.Error(\"Scaling is not supported in this browser!\");\n }\n\n var scalingEffort = new qq.Promise(),\n log = api.log,\n file = api.getFile(id),\n uploadData = api.uploadData.retrieve({id: id}),\n name = uploadData && uploadData.name,\n uuid = uploadData && uploadData.uuid,\n scalingOptions = {\n customResizer: specs.customResizer,\n sendOriginal: false,\n orient: specs.orient,\n defaultType: specs.type || null,\n defaultQuality: specs.quality,\n failedToScaleText: \"Unable to scale\",\n sizes: [{name: \"\", maxSize: specs.maxSize}]\n },\n scaler = new qq.Scaler(scalingOptions, log);\n\n if (!qq.Scaler || !qq.supportedFeatures.imagePreviews || !file) {\n scalingEffort.failure();\n\n log(\"Could not generate requested scaled image for \" + id + \". \" +\n \"Scaling is either not possible in this browser, or the file could not be located.\", \"error\");\n }\n else {\n (qq.bind(function() {\n // Assumption: There will never be more than one record\n var record = scaler.getFileRecords(uuid, name, file)[0];\n\n if (record && record.blob instanceof qq.BlobProxy) {\n record.blob.create().then(scalingEffort.success, scalingEffort.failure);\n }\n else {\n log(id + \" is not a scalable image!\", \"error\");\n scalingEffort.failure();\n }\n }, this)());\n }\n\n return scalingEffort;\n },\n\n // NOTE: We cannot reliably determine at this time if the UA supports a specific MIME type for the target format.\n // image/jpeg and image/png are the only safe choices at this time.\n _determineOutputType: function(spec) {\n \"use strict\";\n\n var requestedType = spec.requestedType,\n defaultType = spec.defaultType,\n referenceType = spec.refType;\n\n // If a default type and requested type have not been specified, this should be a\n // JPEG if the original type is a JPEG, otherwise, a PNG.\n if (!defaultType && !requestedType) {\n if (referenceType !== \"image/jpeg\") {\n return \"image/png\";\n }\n return referenceType;\n }\n\n // A specified default type is used when a requested type is not specified.\n if (!requestedType) {\n return defaultType;\n }\n\n // If requested type is specified, use it, as long as this recognized type is supported by the current UA\n if (qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES), requestedType) >= 0) {\n if (requestedType === \"image/tiff\") {\n return qq.supportedFeatures.tiffPreviews ? requestedType : defaultType;\n }\n\n return requestedType;\n }\n\n return defaultType;\n },\n\n // Get a file name for a generated scaled file record, based on the provided scaled image description\n _getName: function(originalName, scaledVersionProperties) {\n \"use strict\";\n\n var startOfExt = originalName.lastIndexOf(\".\"),\n versionType = scaledVersionProperties.type || \"image/png\",\n referenceType = scaledVersionProperties.refType,\n scaledName = \"\",\n scaledExt = qq.getExtension(originalName),\n nameAppendage = \"\";\n\n if (scaledVersionProperties.name && scaledVersionProperties.name.trim().length) {\n nameAppendage = \" (\" + scaledVersionProperties.name + \")\";\n }\n\n if (startOfExt >= 0) {\n scaledName = originalName.substr(0, startOfExt);\n\n if (referenceType !== versionType) {\n scaledExt = versionType.split(\"/\")[1];\n }\n\n scaledName += nameAppendage + \".\" + scaledExt;\n }\n else {\n scaledName = originalName + nameAppendage;\n }\n\n return scaledName;\n },\n\n // We want the smallest scaled file to be uploaded first\n _getSortedSizes: function(sizes) {\n \"use strict\";\n\n sizes = qq.extend([], sizes);\n\n return sizes.sort(function(a, b) {\n if (a.maxSize > b.maxSize) {\n return 1;\n }\n if (a.maxSize < b.maxSize) {\n return -1;\n }\n return 0;\n });\n },\n\n _generateScaledImage: function(spec, sourceFile) {\n \"use strict\";\n\n var self = this,\n customResizeFunction = spec.customResizeFunction,\n log = spec.log,\n maxSize = spec.maxSize,\n orient = spec.orient,\n type = spec.type,\n quality = spec.quality,\n failedText = spec.failedText,\n includeExif = spec.includeExif && sourceFile.type === \"image/jpeg\" && type === \"image/jpeg\",\n scalingEffort = new qq.Promise(),\n imageGenerator = new qq.ImageGenerator(log),\n canvas = document.createElement(\"canvas\");\n\n log(\"Attempting to generate scaled version for \" + sourceFile.name);\n\n imageGenerator.generate(sourceFile, canvas, {maxSize: maxSize, orient: orient, customResizeFunction: customResizeFunction}).then(function() {\n var scaledImageDataUri = canvas.toDataURL(type, quality),\n signalSuccess = function() {\n log(\"Success generating scaled version for \" + sourceFile.name);\n var blob = qq.dataUriToBlob(scaledImageDataUri);\n scalingEffort.success(blob);\n };\n\n if (includeExif) {\n self._insertExifHeader(sourceFile, scaledImageDataUri, log).then(function(scaledImageDataUriWithExif) {\n scaledImageDataUri = scaledImageDataUriWithExif;\n signalSuccess();\n },\n function() {\n log(\"Problem inserting EXIF header into scaled image. Using scaled image w/out EXIF data.\", \"error\");\n signalSuccess();\n });\n }\n else {\n signalSuccess();\n }\n }, function() {\n log(\"Failed attempt to generate scaled version for \" + sourceFile.name, \"error\");\n scalingEffort.failure(failedText);\n });\n\n return scalingEffort;\n },\n\n // Attempt to insert the original image's EXIF header into a scaled version.\n _insertExifHeader: function(originalImage, scaledImageDataUri, log) {\n \"use strict\";\n\n var reader = new FileReader(),\n insertionEffort = new qq.Promise(),\n originalImageDataUri = \"\";\n\n reader.onload = function() {\n originalImageDataUri = reader.result;\n insertionEffort.success(qq.ExifRestorer.restore(originalImageDataUri, scaledImageDataUri));\n };\n\n reader.onerror = function() {\n log(\"Problem reading \" + originalImage.name + \" during attempt to transfer EXIF data to scaled version.\", \"error\");\n insertionEffort.failure();\n };\n\n reader.readAsDataURL(originalImage);\n\n return insertionEffort;\n },\n\n _dataUriToBlob: function(dataUri) {\n \"use strict\";\n\n var byteString, mimeString, arrayBuffer, intArray;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return this._createBlob(arrayBuffer, mimeString);\n },\n\n _createBlob: function(data, mime) {\n \"use strict\";\n\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n }\n});\n","//Based on MinifyJpeg\n//http://elicon.blog57.fc2.com/blog-entry-206.html\n\nqq.ExifRestorer = (function()\n{\n \n\tvar ExifRestorer = {};\n\t \n ExifRestorer.KEY_STR = \"ABCDEFGHIJKLMNOP\" +\n \"QRSTUVWXYZabcdef\" +\n \"ghijklmnopqrstuv\" +\n \"wxyz0123456789+/\" +\n \"=\";\n\n ExifRestorer.encode64 = function(input)\n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0;\n\n do {\n chr1 = input[i++];\n chr2 = input[i++];\n chr3 = input[i++];\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n\n output = output +\n this.KEY_STR.charAt(enc1) +\n this.KEY_STR.charAt(enc2) +\n this.KEY_STR.charAt(enc3) +\n this.KEY_STR.charAt(enc4);\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n } while (i < input.length);\n\n return output;\n };\n \n ExifRestorer.restore = function(origFileBase64, resizedFileBase64)\n {\n var expectedBase64Header = \"data:image/jpeg;base64,\";\n\n if (!origFileBase64.match(expectedBase64Header))\n {\n \treturn resizedFileBase64;\n } \n \n var rawImage = this.decode64(origFileBase64.replace(expectedBase64Header, \"\"));\n var segments = this.slice2Segments(rawImage);\n \n var image = this.exifManipulation(resizedFileBase64, segments);\n \n return expectedBase64Header + this.encode64(image);\n \n };\n\n\n ExifRestorer.exifManipulation = function(resizedFileBase64, segments)\n {\n var exifArray = this.getExifArray(segments),\n newImageArray = this.insertExif(resizedFileBase64, exifArray),\n aBuffer = new Uint8Array(newImageArray);\n\n return aBuffer;\n };\n\n\n ExifRestorer.getExifArray = function(segments)\n {\n var seg;\n for (var x = 0; x < segments.length; x++)\n {\n seg = segments[x];\n if (seg[0] == 255 & seg[1] == 225) //(ff e1)\n {\n return seg;\n }\n }\n return [];\n };\n\n\n ExifRestorer.insertExif = function(resizedFileBase64, exifArray)\n {\n var imageData = resizedFileBase64.replace(\"data:image/jpeg;base64,\", \"\"),\n buf = this.decode64(imageData),\n separatePoint = buf.indexOf(255,3),\n mae = buf.slice(0, separatePoint),\n ato = buf.slice(separatePoint),\n array = mae;\n\n array = array.concat(exifArray);\n array = array.concat(ato);\n return array;\n };\n\n\n \n ExifRestorer.slice2Segments = function(rawImageArray)\n {\n var head = 0,\n segments = [];\n\n while (1)\n {\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}\n if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)\n {\n head += 2;\n }\n else\n {\n var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],\n endPoint = head + length + 2,\n seg = rawImageArray.slice(head, endPoint);\n segments.push(seg);\n head = endPoint;\n }\n if (head > rawImageArray.length){break;}\n }\n\n return segments;\n };\n\n\n \n ExifRestorer.decode64 = function(input) \n {\n var output = \"\",\n chr1, chr2, chr3 = \"\",\n enc1, enc2, enc3, enc4 = \"\",\n i = 0,\n buf = [];\n\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n var base64test = /[^A-Za-z0-9\\+\\/\\=]/g;\n if (base64test.exec(input)) {\n throw new Error(\"There were invalid base64 characters in the input text. \" +\n \"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\");\n }\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\n do {\n enc1 = this.KEY_STR.indexOf(input.charAt(i++));\n enc2 = this.KEY_STR.indexOf(input.charAt(i++));\n enc3 = this.KEY_STR.indexOf(input.charAt(i++));\n enc4 = this.KEY_STR.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n buf.push(chr1);\n\n if (enc3 != 64) {\n buf.push(chr2);\n }\n if (enc4 != 64) {\n buf.push(chr3);\n }\n\n chr1 = chr2 = chr3 = \"\";\n enc1 = enc2 = enc3 = enc4 = \"\";\n\n } while (i < input.length);\n\n return buf;\n };\n\n \n return ExifRestorer;\n})();\n","/* globals qq */\n/**\n * Keeps a running tally of total upload progress for a batch of files.\n *\n * @param callback Invoked when total progress changes, passing calculated total loaded & total size values.\n * @param getSize Function that returns the size of a file given its ID\n * @constructor\n */\nqq.TotalProgress = function(callback, getSize) {\n \"use strict\";\n\n var perFileProgress = {},\n totalLoaded = 0,\n totalSize = 0,\n\n lastLoadedSent = -1,\n lastTotalSent = -1,\n callbackProxy = function(loaded, total) {\n if (loaded !== lastLoadedSent || total !== lastTotalSent) {\n callback(loaded, total);\n }\n\n lastLoadedSent = loaded;\n lastTotalSent = total;\n },\n\n /**\n * @param failed Array of file IDs that have failed\n * @param retryable Array of file IDs that are retryable\n * @returns true if none of the failed files are eligible for retry\n */\n noRetryableFiles = function(failed, retryable) {\n var none = true;\n\n qq.each(failed, function(idx, failedId) {\n if (qq.indexOf(retryable, failedId) >= 0) {\n none = false;\n return false;\n }\n });\n\n return none;\n },\n\n onCancel = function(id) {\n updateTotalProgress(id, -1, -1);\n delete perFileProgress[id];\n },\n\n onAllComplete = function(successful, failed, retryable) {\n if (failed.length === 0 || noRetryableFiles(failed, retryable)) {\n callbackProxy(totalSize, totalSize);\n this.reset();\n }\n },\n\n onNew = function(id) {\n var size = getSize(id);\n\n // We might not know the size yet, such as for blob proxies\n if (size > 0) {\n updateTotalProgress(id, 0, size);\n perFileProgress[id] = {loaded: 0, total: size};\n }\n },\n\n /**\n * Invokes the callback with the current total progress of all files in the batch. Called whenever it may\n * be appropriate to re-calculate and disseminate this data.\n *\n * @param id ID of a file that has changed in some important way\n * @param newLoaded New loaded value for this file. -1 if this value should no longer be part of calculations\n * @param newTotal New total size of the file. -1 if this value should no longer be part of calculations\n */\n updateTotalProgress = function(id, newLoaded, newTotal) {\n var oldLoaded = perFileProgress[id] ? perFileProgress[id].loaded : 0,\n oldTotal = perFileProgress[id] ? perFileProgress[id].total : 0;\n\n if (newLoaded === -1 && newTotal === -1) {\n totalLoaded -= oldLoaded;\n totalSize -= oldTotal;\n }\n else {\n if (newLoaded) {\n totalLoaded += newLoaded - oldLoaded;\n }\n if (newTotal) {\n totalSize += newTotal - oldTotal;\n }\n }\n\n callbackProxy(totalLoaded, totalSize);\n };\n\n qq.extend(this, {\n // Called when a batch of files has completed uploading.\n onAllComplete: onAllComplete,\n\n // Called when the status of a file has changed.\n onStatusChange: function(id, oldStatus, newStatus) {\n if (newStatus === qq.status.CANCELED || newStatus === qq.status.REJECTED) {\n onCancel(id);\n }\n else if (newStatus === qq.status.SUBMITTING) {\n onNew(id);\n }\n },\n\n // Called whenever the upload progress of an individual file has changed.\n onIndividualProgress: function(id, loaded, total) {\n updateTotalProgress(id, loaded, total);\n perFileProgress[id] = {loaded: loaded, total: total};\n },\n\n // Called whenever the total size of a file has changed, such as when the size of a generated blob is known.\n onNewSize: function(id) {\n onNew(id);\n },\n\n reset: function() {\n perFileProgress = {};\n totalLoaded = 0;\n totalSize = 0;\n }\n });\n};\n","/*globals qq*/\nqq.PasteSupport = function(o) {\n \"use strict\";\n\n var options, detachPasteHandler;\n\n options = {\n targetElement: null,\n callbacks: {\n log: function(message, level) {},\n pasteReceived: function(blob) {}\n }\n };\n\n function isImage(item) {\n return item.type &&\n item.type.indexOf(\"image/\") === 0;\n }\n\n function registerPasteHandler() {\n detachPasteHandler = qq(options.targetElement).attach(\"paste\", function(event) {\n var clipboardData = event.clipboardData;\n\n if (clipboardData) {\n qq.each(clipboardData.items, function(idx, item) {\n if (isImage(item)) {\n var blob = item.getAsFile();\n options.callbacks.pasteReceived(blob);\n }\n });\n }\n });\n }\n\n function unregisterPasteHandler() {\n if (detachPasteHandler) {\n detachPasteHandler();\n }\n }\n\n qq.extend(options, o);\n registerPasteHandler();\n\n qq.extend(this, {\n reset: function() {\n unregisterPasteHandler();\n }\n });\n};\n","/* globals qq */\n/**\n * Module that handles support for existing forms.\n *\n * @param options Options passed from the integrator-supplied options related to form support.\n * @param startUpload Callback to invoke when files \"stored\" should be uploaded.\n * @param log Proxy for the logger\n * @constructor\n */\nqq.FormSupport = function(options, startUpload, log) {\n \"use strict\";\n var self = this,\n interceptSubmit = options.interceptSubmit,\n formEl = options.element,\n autoUpload = options.autoUpload;\n\n // Available on the public API associated with this module.\n qq.extend(this, {\n // To be used by the caller to determine if the endpoint will be determined by some processing\n // that occurs in this module, such as if the form has an action attribute.\n // Ignore if `attachToForm === false`.\n newEndpoint: null,\n\n // To be used by the caller to determine if auto uploading should be allowed.\n // Ignore if `attachToForm === false`.\n newAutoUpload: autoUpload,\n\n // true if a form was detected and is being tracked by this module\n attachedToForm: false,\n\n // Returns an object with names and values for all valid form elements associated with the attached form.\n getFormInputsAsObject: function() {\n /* jshint eqnull:true */\n if (formEl == null) {\n return null;\n }\n\n return self._form2Obj(formEl);\n }\n });\n\n // If the form contains an action attribute, this should be the new upload endpoint.\n function determineNewEndpoint(formEl) {\n if (formEl.getAttribute(\"action\")) {\n self.newEndpoint = formEl.getAttribute(\"action\");\n }\n }\n\n // Return true only if the form is valid, or if we cannot make this determination.\n // If the form is invalid, ensure invalid field(s) are highlighted in the UI.\n function validateForm(formEl, nativeSubmit) {\n if (formEl.checkValidity && !formEl.checkValidity()) {\n log(\"Form did not pass validation checks - will not upload.\", \"error\");\n nativeSubmit();\n }\n else {\n return true;\n }\n }\n\n // Intercept form submit attempts, unless the integrator has told us not to do this.\n function maybeUploadOnSubmit(formEl) {\n var nativeSubmit = formEl.submit;\n\n // Intercept and squelch submit events.\n qq(formEl).attach(\"submit\", function(event) {\n event = event || window.event;\n\n if (event.preventDefault) {\n event.preventDefault();\n }\n else {\n event.returnValue = false;\n }\n\n validateForm(formEl, nativeSubmit) && startUpload();\n });\n\n // The form's `submit()` function may be called instead (i.e. via jQuery.submit()).\n // Intercept that too.\n formEl.submit = function() {\n validateForm(formEl, nativeSubmit) && startUpload();\n };\n }\n\n // If the element value passed from the uploader is a string, assume it is an element ID - select it.\n // The rest of the code in this module depends on this being an HTMLElement.\n function determineFormEl(formEl) {\n if (formEl) {\n if (qq.isString(formEl)) {\n formEl = document.getElementById(formEl);\n }\n\n if (formEl) {\n log(\"Attaching to form element.\");\n determineNewEndpoint(formEl);\n interceptSubmit && maybeUploadOnSubmit(formEl);\n }\n }\n\n return formEl;\n }\n\n formEl = determineFormEl(formEl);\n this.attachedToForm = !!formEl;\n};\n\nqq.extend(qq.FormSupport.prototype, {\n // Converts all relevant form fields to key/value pairs. This is meant to mimic the data a browser will\n // construct from a given form when the form is submitted.\n _form2Obj: function(form) {\n \"use strict\";\n var obj = {},\n notIrrelevantType = function(type) {\n var irrelevantTypes = [\n \"button\",\n \"image\",\n \"reset\",\n \"submit\"\n ];\n\n return qq.indexOf(irrelevantTypes, type.toLowerCase()) < 0;\n },\n radioOrCheckbox = function(type) {\n return qq.indexOf([\"checkbox\", \"radio\"], type.toLowerCase()) >= 0;\n },\n ignoreValue = function(el) {\n if (radioOrCheckbox(el.type) && !el.checked) {\n return true;\n }\n\n return el.disabled && el.type.toLowerCase() !== \"hidden\";\n },\n selectValue = function(select) {\n var value = null;\n\n qq.each(qq(select).children(), function(idx, child) {\n if (child.tagName.toLowerCase() === \"option\" && child.selected) {\n value = child.value;\n return false;\n }\n });\n\n return value;\n };\n\n qq.each(form.elements, function(idx, el) {\n if ((qq.isInput(el, true) || el.tagName.toLowerCase() === \"textarea\") &&\n notIrrelevantType(el.type) &&\n !ignoreValue(el)) {\n\n obj[el.name] = el.value;\n }\n else if (el.tagName.toLowerCase() === \"select\" && !ignoreValue(el)) {\n var value = selectValue(el);\n\n if (value !== null) {\n obj[el.name] = value;\n }\n }\n });\n\n return obj;\n }\n});\n","/*globals qq*/\n/**\n * Upload handler used that assumes the current user agent does not have any support for the\n * File API, and, therefore, makes use of iframes and forms to submit the files directly to\n * a generic server.\n *\n * @param options Options passed from the base handler\n * @param proxy Callbacks & methods used to query for or push out data/changes\n */\nqq.traditional = qq.traditional || {};\nqq.traditional.FormUploadHandler = function(options, proxy) {\n \"use strict\";\n\n var handler = this,\n getName = proxy.getName,\n getUuid = proxy.getUuid,\n log = proxy.log;\n\n /**\n * Returns json object received by iframe from server.\n */\n function getIframeContentJson(id, iframe) {\n /*jshint evil: true*/\n\n var response, doc, innerHtml;\n\n //IE may throw an \"access is denied\" error when attempting to access contentDocument on the iframe in some cases\n try {\n // iframe.contentWindow.document - for IE<7\n doc = iframe.contentDocument || iframe.contentWindow.document;\n innerHtml = doc.body.innerHTML;\n\n log(\"converting iframe's innerHTML to JSON\");\n log(\"innerHTML = \" + innerHtml);\n //plain text response may be wrapped in tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
tag\n if (innerHtml && innerHtml.match(/^ 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n if (isFileDrag(e)) {\n e.preventDefault();\n maybeHideDropZones();\n }\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n\n this._testing = {};\n this._testing.extractDirectoryPath = extractDirectoryPath;\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest &&\n (\n (dt.files && dt.files.length) || // Valid for drop events with files\n (!isSafari && dt.types.contains && dt.types.contains(\"Files\")) || // Valid in Chrome/Firefox\n (dt.types.includes && dt.types.includes(\"Files\")) // Valid in IE\n );\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n\n this._testing = {};\n this._testing.isValidFileDrag = isValidFileDrag;\n};\n","/*globals qq */\n/**\n * Defines the public API for FineUploader mode.\n */\n(function() {\n \"use strict\";\n\n qq.uiPublicApi = {\n addInitialFiles: function(cannedFileList) {\n this._parent.prototype.addInitialFiles.apply(this, arguments);\n this._templating.addCacheToDom();\n },\n\n clearStoredFiles: function() {\n this._parent.prototype.clearStoredFiles.apply(this, arguments);\n this._templating.clearFiles();\n },\n\n addExtraDropzone: function(element) {\n this._dnd && this._dnd.setupExtraDropzone(element);\n },\n\n removeExtraDropzone: function(element) {\n if (this._dnd) {\n return this._dnd.removeDropzone(element);\n }\n },\n\n getItemByFileId: function(id) {\n if (!this._templating.isHiddenForever(id)) {\n return this._templating.getFileContainer(id);\n }\n },\n\n reset: function() {\n this._parent.prototype.reset.apply(this, arguments);\n this._templating.reset();\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n if (this._dnd) {\n this._dnd.dispose();\n this._dnd = this._setupDragAndDrop();\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n\n this._setupClickAndEditEventHandlers();\n },\n\n setName: function(id, newName) {\n var formattedFilename = this._options.formatFileName(newName);\n\n this._parent.prototype.setName.apply(this, arguments);\n this._templating.updateFilename(id, formattedFilename);\n },\n\n pauseUpload: function(id) {\n var paused = this._parent.prototype.pauseUpload.apply(this, arguments);\n\n paused && this._templating.uploadPaused(id);\n return paused;\n },\n\n continueUpload: function(id) {\n var continued = this._parent.prototype.continueUpload.apply(this, arguments);\n\n continued && this._templating.uploadContinued(id);\n return continued;\n },\n\n getId: function(fileContainerOrChildEl) {\n return this._templating.getFileId(fileContainerOrChildEl);\n },\n\n getDropTarget: function(fileId) {\n var file = this.getFile(fileId);\n\n return file.qqDropTarget;\n }\n };\n\n /**\n * Defines the private (internal) API for FineUploader mode.\n */\n qq.uiPrivateApi = {\n _getButton: function(buttonId) {\n var button = this._parent.prototype._getButton.apply(this, arguments);\n\n if (!button) {\n if (buttonId === this._defaultButtonId) {\n button = this._templating.getButton();\n }\n }\n\n return button;\n },\n\n _removeFileItem: function(fileId) {\n this._templating.removeFile(fileId);\n },\n\n _setupClickAndEditEventHandlers: function() {\n this._fileButtonsClickHandler = qq.FileButtonsClickHandler && this._bindFileButtonsClickEvent();\n\n // A better approach would be to check specifically for focusin event support by querying the DOM API,\n // but the DOMFocusIn event is not exposed as a property, so we have to resort to UA string sniffing.\n this._focusinEventSupported = !qq.firefox();\n\n if (this._isEditFilenameEnabled())\n {\n this._filenameClickHandler = this._bindFilenameClickEvent();\n this._filenameInputFocusInHandler = this._bindFilenameInputFocusInEvent();\n this._filenameInputFocusHandler = this._bindFilenameInputFocusEvent();\n }\n },\n\n _setupDragAndDrop: function() {\n var self = this,\n dropZoneElements = this._options.dragAndDrop.extraDropzones,\n templating = this._templating,\n defaultDropZone = templating.getDropZone();\n\n defaultDropZone && dropZoneElements.push(defaultDropZone);\n\n return new qq.DragAndDrop({\n dropZoneElements: dropZoneElements,\n allowMultipleItems: this._options.multiple,\n classes: {\n dropActive: this._options.classes.dropActive\n },\n callbacks: {\n processingDroppedFiles: function() {\n templating.showDropProcessing();\n },\n processingDroppedFilesComplete: function(files, targetEl) {\n templating.hideDropProcessing();\n\n qq.each(files, function(idx, file) {\n file.qqDropTarget = targetEl;\n });\n\n if (files.length) {\n self.addFiles(files, null, null);\n }\n },\n dropError: function(code, errorData) {\n self._itemError(code, errorData);\n },\n dropLog: function(message, level) {\n self.log(message, level);\n }\n }\n });\n },\n\n _bindFileButtonsClickEvent: function() {\n var self = this;\n\n return new qq.FileButtonsClickHandler({\n templating: this._templating,\n\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n\n onDeleteFile: function(fileId) {\n self.deleteFile(fileId);\n },\n\n onCancel: function(fileId) {\n self.cancel(fileId);\n },\n\n onRetry: function(fileId) {\n self.retry(fileId);\n },\n\n onPause: function(fileId) {\n self.pauseUpload(fileId);\n },\n\n onContinue: function(fileId) {\n self.continueUpload(fileId);\n },\n\n onGetName: function(fileId) {\n return self.getName(fileId);\n }\n });\n },\n\n _isEditFilenameEnabled: function() {\n /*jshint -W014 */\n return this._templating.isEditFilenamePossible()\n && !this._options.autoUpload\n && qq.FilenameClickHandler\n && qq.FilenameInputFocusHandler\n && qq.FilenameInputFocusHandler;\n },\n\n _filenameEditHandler: function() {\n var self = this,\n templating = this._templating;\n\n return {\n templating: templating,\n log: function(message, lvl) {\n self.log(message, lvl);\n },\n onGetUploadStatus: function(fileId) {\n return self.getUploads({id: fileId}).status;\n },\n onGetName: function(fileId) {\n return self.getName(fileId);\n },\n onSetName: function(id, newName) {\n self.setName(id, newName);\n },\n onEditingStatusChange: function(id, isEditing) {\n var qqInput = qq(templating.getEditInput(id)),\n qqFileContainer = qq(templating.getFileContainer(id));\n\n if (isEditing) {\n qqInput.addClass(\"qq-editing\");\n templating.hideFilename(id);\n templating.hideEditIcon(id);\n }\n else {\n qqInput.removeClass(\"qq-editing\");\n templating.showFilename(id);\n templating.showEditIcon(id);\n }\n\n // Force IE8 and older to repaint\n qqFileContainer.addClass(\"qq-temp\").removeClass(\"qq-temp\");\n }\n };\n },\n\n _onUploadStatusChange: function(id, oldStatus, newStatus) {\n this._parent.prototype._onUploadStatusChange.apply(this, arguments);\n\n if (this._isEditFilenameEnabled()) {\n // Status for a file exists before it has been added to the DOM, so we must be careful here.\n if (this._templating.getFileContainer(id) && newStatus !== qq.status.SUBMITTED) {\n this._templating.markFilenameEditable(id);\n this._templating.hideEditIcon(id);\n }\n }\n\n if (oldStatus === qq.status.UPLOAD_RETRYING && newStatus === qq.status.UPLOADING) {\n this._templating.hideRetry(id);\n this._templating.setStatusText(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.retrying);\n }\n else if (newStatus === qq.status.UPLOAD_FAILED) {\n this._templating.hidePause(id);\n }\n },\n\n _bindFilenameInputFocusInEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusInHandler(spec);\n },\n\n _bindFilenameInputFocusEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameInputFocusHandler(spec);\n },\n\n _bindFilenameClickEvent: function() {\n var spec = qq.extend({}, this._filenameEditHandler());\n\n return new qq.FilenameClickHandler(spec);\n },\n\n _storeForLater: function(id) {\n this._parent.prototype._storeForLater.apply(this, arguments);\n this._templating.hideSpinner(id);\n },\n\n _onAllComplete: function(successful, failed) {\n this._parent.prototype._onAllComplete.apply(this, arguments);\n this._templating.resetTotalProgress();\n },\n\n _onSubmit: function(id, name) {\n var file = this.getFile(id);\n\n if (file && file.qqPath && this._options.dragAndDrop.reportDirectoryPaths) {\n this._paramsStore.addReadOnly(id, {\n qqpath: file.qqPath\n });\n }\n\n this._parent.prototype._onSubmit.apply(this, arguments);\n this._addToList(id, name);\n },\n\n // The file item has been added to the DOM.\n _onSubmitted: function(id) {\n // If the edit filename feature is enabled, mark the filename element as \"editable\" and the associated edit icon\n if (this._isEditFilenameEnabled()) {\n this._templating.markFilenameEditable(id);\n this._templating.showEditIcon(id);\n\n // If the focusin event is not supported, we must add a focus handler to the newly create edit filename text input\n if (!this._focusinEventSupported) {\n this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(id));\n }\n }\n },\n\n // Update the progress bar & percentage as the file is uploaded\n _onProgress: function(id, name, loaded, total) {\n this._parent.prototype._onProgress.apply(this, arguments);\n\n this._templating.updateProgress(id, loaded, total);\n\n if (total === 0 || Math.round(loaded / total * 100) === 100) {\n this._templating.hideCancel(id);\n this._templating.hidePause(id);\n this._templating.hideProgress(id);\n this._templating.setStatusText(id, this._options.text.waitingForResponse);\n\n // If ~last byte was sent, display total file size\n this._displayFileSize(id);\n }\n else {\n // If still uploading, display percentage - total size is actually the total request(s) size\n this._displayFileSize(id, loaded, total);\n }\n },\n\n _onTotalProgress: function(loaded, total) {\n this._parent.prototype._onTotalProgress.apply(this, arguments);\n this._templating.updateTotalProgress(loaded, total);\n },\n\n _onComplete: function(id, name, result, xhr) {\n var parentRetVal = this._parent.prototype._onComplete.apply(this, arguments),\n templating = this._templating,\n fileContainer = templating.getFileContainer(id),\n self = this;\n\n function completeUpload(result) {\n // If this file is not represented in the templating module, perhaps it was hidden intentionally.\n // If so, don't perform any UI-related tasks related to this file.\n if (!fileContainer) {\n return;\n }\n\n templating.setStatusText(id);\n\n qq(fileContainer).removeClass(self._classes.retrying);\n templating.hideProgress(id);\n\n if (self.getUploads({id: id}).status !== qq.status.UPLOAD_FAILED) {\n templating.hideCancel(id);\n }\n templating.hideSpinner(id);\n\n if (result.success) {\n self._markFileAsSuccessful(id);\n }\n else {\n qq(fileContainer).addClass(self._classes.fail);\n templating.showCancel(id);\n\n if (templating.isRetryPossible() && !self._preventRetries[id]) {\n qq(fileContainer).addClass(self._classes.retryable);\n templating.showRetry(id);\n }\n self._controlFailureTextDisplay(id, result);\n }\n }\n\n // The parent may need to perform some async operation before we can accurately determine the status of the upload.\n if (parentRetVal instanceof qq.Promise) {\n parentRetVal.done(function(newResult) {\n completeUpload(newResult);\n });\n\n }\n else {\n completeUpload(result);\n }\n\n return parentRetVal;\n },\n\n _markFileAsSuccessful: function(id) {\n var templating = this._templating;\n\n if (this._isDeletePossible()) {\n templating.showDeleteButton(id);\n }\n\n qq(templating.getFileContainer(id)).addClass(this._classes.success);\n\n this._maybeUpdateThumbnail(id);\n },\n\n _onUploadPrep: function(id) {\n this._parent.prototype._onUploadPrep.apply(this, arguments);\n this._templating.showSpinner(id);\n },\n\n _onUpload: function(id, name) {\n var parentRetVal = this._parent.prototype._onUpload.apply(this, arguments);\n\n this._templating.showSpinner(id);\n\n return parentRetVal;\n },\n\n _onUploadChunk: function(id, chunkData) {\n this._parent.prototype._onUploadChunk.apply(this, arguments);\n\n // Only display the pause button if we have finished uploading at least one chunk\n // & this file can be resumed\n if (chunkData.partIndex > 0 && this._handler.isResumable(id)) {\n this._templating.allowPause(id);\n }\n },\n\n _onCancel: function(id, name) {\n this._parent.prototype._onCancel.apply(this, arguments);\n this._removeFileItem(id);\n\n if (this._getNotFinished() === 0) {\n this._templating.resetTotalProgress();\n }\n },\n\n _onBeforeAutoRetry: function(id) {\n var retryNumForDisplay, maxAuto, retryNote;\n\n this._parent.prototype._onBeforeAutoRetry.apply(this, arguments);\n\n this._showCancelLink(id);\n\n if (this._options.retry.showAutoRetryNote) {\n retryNumForDisplay = this._autoRetries[id];\n maxAuto = this._options.retry.maxAutoAttempts;\n\n retryNote = this._options.retry.autoRetryNote.replace(/\\{retryNum\\}/g, retryNumForDisplay);\n retryNote = retryNote.replace(/\\{maxAuto\\}/g, maxAuto);\n\n this._templating.setStatusText(id, retryNote);\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retrying);\n }\n },\n\n //return false if we should not attempt the requested retry\n _onBeforeManualRetry: function(id) {\n if (this._parent.prototype._onBeforeManualRetry.apply(this, arguments)) {\n this._templating.resetProgress(id);\n qq(this._templating.getFileContainer(id)).removeClass(this._classes.fail);\n this._templating.setStatusText(id);\n this._templating.showSpinner(id);\n this._showCancelLink(id);\n return true;\n }\n else {\n qq(this._templating.getFileContainer(id)).addClass(this._classes.retryable);\n this._templating.showRetry(id);\n return false;\n }\n },\n\n _onSubmitDelete: function(id) {\n var onSuccessCallback = qq.bind(this._onSubmitDeleteSuccess, this);\n\n this._parent.prototype._onSubmitDelete.call(this, id, onSuccessCallback);\n },\n\n _onSubmitDeleteSuccess: function(id, uuid, additionalMandatedParams) {\n if (this._options.deleteFile.forceConfirm) {\n this._showDeleteConfirm.apply(this, arguments);\n }\n else {\n this._sendDeleteRequest.apply(this, arguments);\n }\n },\n\n _onDeleteComplete: function(id, xhr, isError) {\n this._parent.prototype._onDeleteComplete.apply(this, arguments);\n\n this._templating.hideSpinner(id);\n\n if (isError) {\n this._templating.setStatusText(id, this._options.deleteFile.deletingFailedText);\n this._templating.showDeleteButton(id);\n }\n else {\n this._removeFileItem(id);\n }\n },\n\n _sendDeleteRequest: function(id, uuid, additionalMandatedParams) {\n this._templating.hideDeleteButton(id);\n this._templating.showSpinner(id);\n this._templating.setStatusText(id, this._options.deleteFile.deletingStatusText);\n this._deleteHandler.sendDelete.apply(this, arguments);\n },\n\n _showDeleteConfirm: function(id, uuid, mandatedParams) {\n /*jshint -W004 */\n var fileName = this.getName(id),\n confirmMessage = this._options.deleteFile.confirmMessage.replace(/\\{filename\\}/g, fileName),\n uuid = this.getUuid(id),\n deleteRequestArgs = arguments,\n self = this,\n retVal;\n\n retVal = this._options.showConfirm(confirmMessage);\n\n if (qq.isGenericPromise(retVal)) {\n retVal.then(function() {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n });\n }\n else if (retVal !== false) {\n self._sendDeleteRequest.apply(self, deleteRequestArgs);\n }\n },\n\n _addToList: function(id, name, canned) {\n var prependData,\n prependIndex = 0,\n dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,\n record;\n\n if (this._options.display.prependFiles) {\n if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {\n prependIndex = this._filesInBatchAddedToUi - 1;\n }\n\n prependData = {\n index: prependIndex\n };\n }\n\n if (!canned) {\n if (this._options.disableCancelForFormUploads && !qq.supportedFeatures.ajaxUploading) {\n this._templating.disableCancel();\n }\n\n // Cancel all existing (previous) files and clear the list if this file is not part of\n // a scaled file group that has already been accepted, or if this file is not part of\n // a scaled file group at all.\n if (!this._options.multiple) {\n record = this.getUploads({id: id});\n\n this._handledProxyGroup = this._handledProxyGroup || record.proxyGroupId;\n\n if (record.proxyGroupId !== this._handledProxyGroup || !record.proxyGroupId) {\n this._handler.cancelAll();\n this._clearList();\n this._handledProxyGroup = null;\n }\n }\n }\n\n if (canned) {\n this._templating.addFileToCache(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.updateThumbnail(id, this._thumbnailUrls[id], true, this._options.thumbnails.customResizer);\n }\n else {\n this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);\n this._templating.generatePreview(id, this.getFile(id), this._options.thumbnails.customResizer);\n }\n\n this._filesInBatchAddedToUi += 1;\n\n if (canned ||\n (this._options.display.fileSizeOnSubmit && qq.supportedFeatures.ajaxUploading)) {\n\n this._displayFileSize(id);\n }\n },\n\n _clearList: function() {\n this._templating.clearFiles();\n this.clearStoredFiles();\n },\n\n _displayFileSize: function(id, loadedSize, totalSize) {\n var size = this.getSize(id),\n sizeForDisplay = this._formatSize(size);\n\n if (size >= 0) {\n if (loadedSize !== undefined && totalSize !== undefined) {\n sizeForDisplay = this._formatProgress(loadedSize, totalSize);\n }\n\n this._templating.updateSize(id, sizeForDisplay);\n }\n },\n\n _formatProgress: function(uploadedSize, totalSize) {\n var message = this._options.text.formatProgress;\n function r(name, replacement) { message = message.replace(name, replacement); }\n\n r(\"{percent}\", Math.round(uploadedSize / totalSize * 100));\n r(\"{total_size}\", this._formatSize(totalSize));\n return message;\n },\n\n _controlFailureTextDisplay: function(id, response) {\n var mode, responseProperty, failureReason;\n\n mode = this._options.failedUploadTextDisplay.mode;\n responseProperty = this._options.failedUploadTextDisplay.responseProperty;\n\n if (mode === \"custom\") {\n failureReason = response[responseProperty];\n if (!failureReason) {\n failureReason = this._options.text.failUpload;\n }\n\n this._templating.setStatusText(id, failureReason);\n\n if (this._options.failedUploadTextDisplay.enableTooltip) {\n this._showTooltip(id, failureReason);\n }\n }\n else if (mode === \"default\") {\n this._templating.setStatusText(id, this._options.text.failUpload);\n }\n else if (mode !== \"none\") {\n this.log(\"failedUploadTextDisplay.mode value of '\" + mode + \"' is not valid\", \"warn\");\n }\n },\n\n _showTooltip: function(id, text) {\n this._templating.getFileContainer(id).title = text;\n },\n\n _showCancelLink: function(id) {\n if (!this._options.disableCancelForFormUploads || qq.supportedFeatures.ajaxUploading) {\n this._templating.showCancel(id);\n }\n },\n\n _itemError: function(code, name, item) {\n var message = this._parent.prototype._itemError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _batchError: function(message) {\n this._parent.prototype._batchError.apply(this, arguments);\n this._options.showMessage(message);\n },\n\n _setupPastePrompt: function() {\n var self = this;\n\n this._options.callbacks.onPasteReceived = function() {\n var message = self._options.paste.namePromptMessage,\n defaultVal = self._options.paste.defaultName;\n\n return self._options.showPrompt(message, defaultVal);\n };\n },\n\n _fileOrBlobRejected: function(id, name) {\n this._totalFilesInBatch -= 1;\n this._parent.prototype._fileOrBlobRejected.apply(this, arguments);\n },\n\n _prepareItemsForUpload: function(items, params, endpoint) {\n this._totalFilesInBatch = items.length;\n this._filesInBatchAddedToUi = 0;\n this._parent.prototype._prepareItemsForUpload.apply(this, arguments);\n },\n\n _maybeUpdateThumbnail: function(fileId) {\n var thumbnailUrl = this._thumbnailUrls[fileId],\n fileStatus = this.getUploads({id: fileId}).status;\n\n if (fileStatus !== qq.status.DELETED &&\n (thumbnailUrl ||\n this._options.thumbnails.placeholders.waitUntilResponse ||\n !qq.supportedFeatures.imagePreviews)) {\n\n // This will replace the \"waiting\" placeholder with a \"preview not available\" placeholder\n // if called with a null thumbnailUrl.\n this._templating.updateThumbnail(fileId, thumbnailUrl, this._options.thumbnails.customResizer);\n }\n },\n\n _addCannedFile: function(sessionData) {\n var id = this._parent.prototype._addCannedFile.apply(this, arguments);\n\n this._addToList(id, this.getName(id), true);\n this._templating.hideSpinner(id);\n this._templating.hideCancel(id);\n this._markFileAsSuccessful(id);\n\n return id;\n },\n\n _setSize: function(id, newSize) {\n this._parent.prototype._setSize.apply(this, arguments);\n\n this._templating.updateSize(id, this._formatSize(newSize));\n },\n\n _sessionRequestComplete: function() {\n this._templating.addCacheToDom();\n this._parent.prototype._sessionRequestComplete.apply(this, arguments);\n }\n };\n}());\n","/*globals qq */\n/**\n * This defines FineUploader mode, which is a default UI w/ drag & drop uploading.\n */\nqq.FineUploader = function(o, namespace) {\n \"use strict\";\n\n var self = this;\n\n // By default this should inherit instance data from FineUploaderBasic, but this can be overridden\n // if the (internal) caller defines a different parent. The parent is also used by\n // the private and public API functions that need to delegate to a parent function.\n this._parent = namespace ? qq[namespace].FineUploaderBasic : qq.FineUploaderBasic;\n this._parent.apply(this, arguments);\n\n // Options provided by FineUploader mode\n qq.extend(this._options, {\n element: null,\n\n button: null,\n\n listElement: null,\n\n dragAndDrop: {\n extraDropzones: [],\n reportDirectoryPaths: false\n },\n\n text: {\n formatProgress: \"{percent}% of {total_size}\",\n failUpload: \"Upload failed\",\n waitingForResponse: \"Processing...\",\n paused: \"Paused\"\n },\n\n template: \"qq-template\",\n\n classes: {\n retrying: \"qq-upload-retrying\",\n retryable: \"qq-upload-retryable\",\n success: \"qq-upload-success\",\n fail: \"qq-upload-fail\",\n editable: \"qq-editable\",\n hide: \"qq-hide\",\n dropActive: \"qq-upload-drop-area-active\"\n },\n\n failedUploadTextDisplay: {\n mode: \"default\", //default, custom, or none\n responseProperty: \"error\",\n enableTooltip: true\n },\n\n messages: {\n tooManyFilesError: \"You may only drop one file\",\n unsupportedBrowser: \"Unrecoverable error - this browser does not permit file uploading of any kind.\"\n },\n\n retry: {\n showAutoRetryNote: true,\n autoRetryNote: \"Retrying {retryNum}/{maxAuto}...\"\n },\n\n deleteFile: {\n forceConfirm: false,\n confirmMessage: \"Are you sure you want to delete {filename}?\",\n deletingStatusText: \"Deleting...\",\n deletingFailedText: \"Delete failed\"\n\n },\n\n display: {\n fileSizeOnSubmit: false,\n prependFiles: false\n },\n\n paste: {\n promptForName: false,\n namePromptMessage: \"Please name this image\"\n },\n\n thumbnails: {\n customResizer: null,\n maxCount: 0,\n placeholders: {\n waitUntilResponse: false,\n notAvailablePath: null,\n waitingPath: null\n },\n timeBetweenThumbs: 750\n },\n\n scaling: {\n hideScaled: false\n },\n\n showMessage: function(message) {\n if (self._templating.hasDialog(\"alert\")) {\n return self._templating.showDialog(\"alert\", message);\n }\n else {\n setTimeout(function() {\n window.alert(message);\n }, 0);\n }\n },\n\n showConfirm: function(message) {\n if (self._templating.hasDialog(\"confirm\")) {\n return self._templating.showDialog(\"confirm\", message);\n }\n else {\n return window.confirm(message);\n }\n },\n\n showPrompt: function(message, defaultValue) {\n if (self._templating.hasDialog(\"prompt\")) {\n return self._templating.showDialog(\"prompt\", message, defaultValue);\n }\n else {\n return window.prompt(message, defaultValue);\n }\n }\n }, true);\n\n // Replace any default options with user defined ones\n qq.extend(this._options, o, true);\n\n this._templating = new qq.Templating({\n log: qq.bind(this.log, this),\n templateIdOrEl: this._options.template,\n containerEl: this._options.element,\n fileContainerEl: this._options.listElement,\n button: this._options.button,\n imageGenerator: this._imageGenerator,\n classes: {\n hide: this._options.classes.hide,\n editable: this._options.classes.editable\n },\n limits: {\n maxThumbs: this._options.thumbnails.maxCount,\n timeBetweenThumbs: this._options.thumbnails.timeBetweenThumbs\n },\n placeholders: {\n waitUntilUpdate: this._options.thumbnails.placeholders.waitUntilResponse,\n thumbnailNotAvailable: this._options.thumbnails.placeholders.notAvailablePath,\n waitingForThumbnail: this._options.thumbnails.placeholders.waitingPath\n },\n text: this._options.text\n });\n\n if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowserIos8Safari);\n }\n else if (!qq.supportedFeatures.uploading || (this._options.cors.expected && !qq.supportedFeatures.uploadCors)) {\n this._templating.renderFailure(this._options.messages.unsupportedBrowser);\n }\n else {\n this._wrapCallbacks();\n\n this._templating.render();\n\n this._classes = this._options.classes;\n\n if (!this._options.button && this._templating.getButton()) {\n this._defaultButtonId = this._createUploadButton({\n element: this._templating.getButton(),\n title: this._options.text.fileInputTitle\n }).getButtonId();\n }\n\n this._setupClickAndEditEventHandlers();\n\n if (qq.DragAndDrop && qq.supportedFeatures.fileDrop) {\n this._dnd = this._setupDragAndDrop();\n }\n\n if (this._options.paste.targetElement && this._options.paste.promptForName) {\n if (qq.PasteSupport) {\n this._setupPastePrompt();\n }\n else {\n this.log(\"Paste support module not found.\", \"error\");\n }\n }\n\n this._totalFilesInBatch = 0;\n this._filesInBatchAddedToUi = 0;\n }\n};\n\n// Inherit the base public & private API methods\nqq.extend(qq.FineUploader.prototype, qq.basePublicApi);\nqq.extend(qq.FineUploader.prototype, qq.basePrivateApi);\n\n// Add the FineUploader/default UI public & private UI methods, which may override some base methods.\nqq.extend(qq.FineUploader.prototype, qq.uiPublicApi);\nqq.extend(qq.FineUploader.prototype, qq.uiPrivateApi);\n","/* globals qq */\n/* jshint -W065 */\n/**\n * Module responsible for rendering all Fine Uploader UI templates. This module also asserts at least\n * a limited amount of control over the template elements after they are added to the DOM.\n * Wherever possible, this module asserts total control over template elements present in the DOM.\n *\n * @param spec Specification object used to control various templating behaviors\n * @constructor\n */\nqq.Templating = function(spec) {\n \"use strict\";\n\n var FILE_ID_ATTR = \"qq-file-id\",\n FILE_CLASS_PREFIX = \"qq-file-id-\",\n THUMBNAIL_MAX_SIZE_ATTR = \"qq-max-size\",\n THUMBNAIL_SERVER_SCALE_ATTR = \"qq-server-scale\",\n // This variable is duplicated in the DnD module since it can function as a standalone as well\n HIDE_DROPZONE_ATTR = \"qq-hide-dropzone\",\n DROPZPONE_TEXT_ATTR = \"qq-drop-area-text\",\n IN_PROGRESS_CLASS = \"qq-in-progress\",\n HIDDEN_FOREVER_CLASS = \"qq-hidden-forever\",\n fileBatch = {\n content: document.createDocumentFragment(),\n map: {}\n },\n isCancelDisabled = false,\n generatedThumbnails = 0,\n thumbnailQueueMonitorRunning = false,\n thumbGenerationQueue = [],\n thumbnailMaxSize = -1,\n options = {\n log: null,\n limits: {\n maxThumbs: 0,\n timeBetweenThumbs: 750\n },\n templateIdOrEl: \"qq-template\",\n containerEl: null,\n fileContainerEl: null,\n button: null,\n imageGenerator: null,\n classes: {\n hide: \"qq-hide\",\n editable: \"qq-editable\"\n },\n placeholders: {\n waitUntilUpdate: false,\n thumbnailNotAvailable: null,\n waitingForThumbnail: null\n },\n text: {\n paused: \"Paused\"\n }\n },\n selectorClasses = {\n button: \"qq-upload-button-selector\",\n alertDialog: \"qq-alert-dialog-selector\",\n dialogCancelButton: \"qq-cancel-button-selector\",\n confirmDialog: \"qq-confirm-dialog-selector\",\n dialogMessage: \"qq-dialog-message-selector\",\n dialogOkButton: \"qq-ok-button-selector\",\n promptDialog: \"qq-prompt-dialog-selector\",\n uploader: \"qq-uploader-selector\",\n drop: \"qq-upload-drop-area-selector\",\n list: \"qq-upload-list-selector\",\n progressBarContainer: \"qq-progress-bar-container-selector\",\n progressBar: \"qq-progress-bar-selector\",\n totalProgressBarContainer: \"qq-total-progress-bar-container-selector\",\n totalProgressBar: \"qq-total-progress-bar-selector\",\n file: \"qq-upload-file-selector\",\n spinner: \"qq-upload-spinner-selector\",\n size: \"qq-upload-size-selector\",\n cancel: \"qq-upload-cancel-selector\",\n pause: \"qq-upload-pause-selector\",\n continueButton: \"qq-upload-continue-selector\",\n deleteButton: \"qq-upload-delete-selector\",\n retry: \"qq-upload-retry-selector\",\n statusText: \"qq-upload-status-text-selector\",\n editFilenameInput: \"qq-edit-filename-selector\",\n editNameIcon: \"qq-edit-filename-icon-selector\",\n dropText: \"qq-upload-drop-area-text-selector\",\n dropProcessing: \"qq-drop-processing-selector\",\n dropProcessingSpinner: \"qq-drop-processing-spinner-selector\",\n thumbnail: \"qq-thumbnail-selector\"\n },\n previewGeneration = {},\n cachedThumbnailNotAvailableImg = new qq.Promise(),\n cachedWaitingForThumbnailImg = new qq.Promise(),\n log,\n isEditElementsExist,\n isRetryElementExist,\n templateDom,\n container,\n fileList,\n showThumbnails,\n serverScale,\n\n // During initialization of the templating module we should cache any\n // placeholder images so we can quickly swap them into the file list on demand.\n // Any placeholder images that cannot be loaded/found are simply ignored.\n cacheThumbnailPlaceholders = function() {\n var notAvailableUrl = options.placeholders.thumbnailNotAvailable,\n waitingUrl = options.placeholders.waitingForThumbnail,\n spec = {\n maxSize: thumbnailMaxSize,\n scale: serverScale\n };\n\n if (showThumbnails) {\n if (notAvailableUrl) {\n options.imageGenerator.generate(notAvailableUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedThumbnailNotAvailableImg.success(updatedImg);\n },\n function() {\n cachedThumbnailNotAvailableImg.failure();\n log(\"Problem loading 'not available' placeholder image at \" + notAvailableUrl, \"error\");\n }\n );\n }\n else {\n cachedThumbnailNotAvailableImg.failure();\n }\n\n if (waitingUrl) {\n options.imageGenerator.generate(waitingUrl, new Image(), spec).then(\n function(updatedImg) {\n cachedWaitingForThumbnailImg.success(updatedImg);\n },\n function() {\n cachedWaitingForThumbnailImg.failure();\n log(\"Problem loading 'waiting for thumbnail' placeholder image at \" + waitingUrl, \"error\");\n }\n );\n }\n else {\n cachedWaitingForThumbnailImg.failure();\n }\n }\n },\n\n // Displays a \"waiting for thumbnail\" type placeholder image\n // iff we were able to load it during initialization of the templating module.\n displayWaitingImg = function(thumbnail) {\n var waitingImgPlacement = new qq.Promise();\n\n cachedWaitingForThumbnailImg.then(function(img) {\n maybeScalePlaceholderViaCss(img, thumbnail);\n /* jshint eqnull:true */\n if (!thumbnail.src) {\n thumbnail.src = img.src;\n thumbnail.onload = function() {\n thumbnail.onload = null;\n show(thumbnail);\n waitingImgPlacement.success();\n };\n }\n else {\n waitingImgPlacement.success();\n }\n }, function() {\n // In some browsers (such as IE9 and older) an img w/out a src attribute\n // are displayed as \"broken\" images, so we should just hide the img tag\n // if we aren't going to display the \"waiting\" placeholder.\n hide(thumbnail);\n waitingImgPlacement.success();\n });\n\n return waitingImgPlacement;\n },\n\n generateNewPreview = function(id, blob, spec) {\n var thumbnail = getThumbnail(id);\n\n log(\"Generating new thumbnail for \" + id);\n blob.qqThumbnailId = id;\n\n return options.imageGenerator.generate(blob, thumbnail, spec).then(\n function() {\n generatedThumbnails++;\n show(thumbnail);\n previewGeneration[id].success();\n },\n function() {\n previewGeneration[id].failure();\n\n // Display the \"not available\" placeholder img only if we are\n // not expecting a thumbnail at a later point, such as in a server response.\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n }\n });\n },\n\n generateNextQueuedPreview = function() {\n if (thumbGenerationQueue.length) {\n thumbnailQueueMonitorRunning = true;\n\n var queuedThumbRequest = thumbGenerationQueue.shift();\n\n if (queuedThumbRequest.update) {\n processUpdateQueuedPreviewRequest(queuedThumbRequest);\n }\n else {\n processNewQueuedPreviewRequest(queuedThumbRequest);\n }\n }\n else {\n thumbnailQueueMonitorRunning = false;\n }\n },\n\n getCancel = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.cancel);\n },\n\n getContinue = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.continueButton);\n },\n\n getDialog = function(type) {\n return getTemplateEl(container, selectorClasses[type + \"Dialog\"]);\n },\n\n getDelete = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.deleteButton);\n },\n\n getDropProcessing = function() {\n return getTemplateEl(container, selectorClasses.dropProcessing);\n },\n\n getEditIcon = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editNameIcon);\n },\n\n getFile = function(id) {\n return fileBatch.map[id] || qq(fileList).getFirstByClass(FILE_CLASS_PREFIX + id);\n },\n\n getFilename = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.file);\n },\n\n getPause = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.pause);\n },\n\n getProgress = function(id) {\n /* jshint eqnull:true */\n // Total progress bar\n if (id == null) {\n return getTemplateEl(container, selectorClasses.totalProgressBarContainer) ||\n getTemplateEl(container, selectorClasses.totalProgressBar);\n }\n\n // Per-file progress bar\n return getTemplateEl(getFile(id), selectorClasses.progressBarContainer) ||\n getTemplateEl(getFile(id), selectorClasses.progressBar);\n },\n\n getRetry = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.retry);\n },\n\n getSize = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.size);\n },\n\n getSpinner = function(id) {\n return getTemplateEl(getFile(id), selectorClasses.spinner);\n },\n\n getTemplateEl = function(context, cssClass) {\n return context && qq(context).getFirstByClass(cssClass);\n },\n\n getThumbnail = function(id) {\n return showThumbnails && getTemplateEl(getFile(id), selectorClasses.thumbnail);\n },\n\n hide = function(el) {\n el && qq(el).addClass(options.classes.hide);\n },\n\n // Ensures a placeholder image does not exceed any max size specified\n // via `style` attribute properties iff was not used to scale\n // the placeholder AND the target doesn't already have these `style` attribute properties set.\n maybeScalePlaceholderViaCss = function(placeholder, thumbnail) {\n var maxWidth = placeholder.style.maxWidth,\n maxHeight = placeholder.style.maxHeight;\n\n if (maxHeight && maxWidth && !thumbnail.style.maxWidth && !thumbnail.style.maxHeight) {\n qq(thumbnail).css({\n maxWidth: maxWidth,\n maxHeight: maxHeight\n });\n }\n },\n\n // Displays a \"thumbnail not available\" type placeholder image\n // iff we were able to load this placeholder during initialization\n // of the templating module or after preview generation has failed.\n maybeSetDisplayNotAvailableImg = function(id, thumbnail) {\n var previewing = previewGeneration[id] || new qq.Promise().failure(),\n notAvailableImgPlacement = new qq.Promise();\n\n cachedThumbnailNotAvailableImg.then(function(img) {\n previewing.then(\n function() {\n notAvailableImgPlacement.success();\n },\n function() {\n maybeScalePlaceholderViaCss(img, thumbnail);\n\n thumbnail.onload = function() {\n thumbnail.onload = null;\n notAvailableImgPlacement.success();\n };\n\n thumbnail.src = img.src;\n show(thumbnail);\n }\n );\n });\n\n return notAvailableImgPlacement;\n },\n\n /**\n * Grabs the HTML from the script tag holding the template markup. This function will also adjust\n * some internally-tracked state variables based on the contents of the template.\n * The template is filtered so that irrelevant elements (such as the drop zone if DnD is not supported)\n * are omitted from the DOM. Useful errors will be thrown if the template cannot be parsed.\n *\n * @returns {{template: *, fileTemplate: *}} HTML for the top-level file items templates\n */\n parseAndGetTemplate = function() {\n var scriptEl,\n scriptHtml,\n fileListNode,\n tempTemplateEl,\n fileListEl,\n defaultButton,\n dropArea,\n thumbnail,\n dropProcessing,\n dropTextEl,\n uploaderEl;\n\n log(\"Parsing template\");\n\n /*jshint -W116*/\n if (options.templateIdOrEl == null) {\n throw new Error(\"You MUST specify either a template element or ID!\");\n }\n\n // Grab the contents of the script tag holding the template.\n if (qq.isString(options.templateIdOrEl)) {\n scriptEl = document.getElementById(options.templateIdOrEl);\n\n if (scriptEl === null) {\n throw new Error(qq.format(\"Cannot find template script at ID '{}'!\", options.templateIdOrEl));\n }\n\n scriptHtml = scriptEl.innerHTML;\n }\n else {\n if (options.templateIdOrEl.innerHTML === undefined) {\n throw new Error(\"You have specified an invalid value for the template option! \" +\n \"It must be an ID or an Element.\");\n }\n\n scriptHtml = options.templateIdOrEl.innerHTML;\n }\n\n scriptHtml = qq.trimStr(scriptHtml);\n tempTemplateEl = document.createElement(\"div\");\n tempTemplateEl.appendChild(qq.toElement(scriptHtml));\n uploaderEl = qq(tempTemplateEl).getFirstByClass(selectorClasses.uploader);\n\n // Don't include the default template button in the DOM\n // if an alternate button container has been specified.\n if (options.button) {\n defaultButton = qq(tempTemplateEl).getFirstByClass(selectorClasses.button);\n if (defaultButton) {\n qq(defaultButton).remove();\n }\n }\n\n // Omit the drop processing element from the DOM if DnD is not supported by the UA,\n // or the drag and drop module is not found.\n // NOTE: We are consciously not removing the drop zone if the UA doesn't support DnD\n // to support layouts where the drop zone is also a container for visible elements,\n // such as the file list.\n if (!qq.DragAndDrop || !qq.supportedFeatures.fileDrop) {\n dropProcessing = qq(tempTemplateEl).getFirstByClass(selectorClasses.dropProcessing);\n if (dropProcessing) {\n qq(dropProcessing).remove();\n }\n }\n\n dropArea = qq(tempTemplateEl).getFirstByClass(selectorClasses.drop);\n\n // If DnD is not available then remove\n // it from the DOM as well.\n if (dropArea && !qq.DragAndDrop) {\n log(\"DnD module unavailable.\", \"info\");\n qq(dropArea).remove();\n }\n\n if (!qq.supportedFeatures.fileDrop) {\n // don't display any \"drop files to upload\" background text\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (dropArea && qq(dropArea).hasAttribute(HIDE_DROPZONE_ATTR)) {\n // If there is a drop area defined in the template, and the current UA doesn't support DnD,\n // and the drop area is marked as \"hide before enter\", ensure it is hidden as the DnD module\n // will not do this (since we will not be loading the DnD module)\n qq(dropArea).css({\n display: \"none\"\n });\n }\n }\n else if (qq(uploaderEl).hasAttribute(DROPZPONE_TEXT_ATTR) && dropArea) {\n dropTextEl = qq(dropArea).getFirstByClass(selectorClasses.dropText);\n dropTextEl && qq(dropTextEl).remove();\n }\n\n // Ensure the `showThumbnails` flag is only set if the thumbnail element\n // is present in the template AND the current UA is capable of generating client-side previews.\n thumbnail = qq(tempTemplateEl).getFirstByClass(selectorClasses.thumbnail);\n if (!showThumbnails) {\n thumbnail && qq(thumbnail).remove();\n }\n else if (thumbnail) {\n thumbnailMaxSize = parseInt(thumbnail.getAttribute(THUMBNAIL_MAX_SIZE_ATTR));\n // Only enforce max size if the attr value is non-zero\n thumbnailMaxSize = thumbnailMaxSize > 0 ? thumbnailMaxSize : null;\n\n serverScale = qq(thumbnail).hasAttribute(THUMBNAIL_SERVER_SCALE_ATTR);\n }\n showThumbnails = showThumbnails && thumbnail;\n\n isEditElementsExist = qq(tempTemplateEl).getByClass(selectorClasses.editFilenameInput).length > 0;\n isRetryElementExist = qq(tempTemplateEl).getByClass(selectorClasses.retry).length > 0;\n\n fileListNode = qq(tempTemplateEl).getFirstByClass(selectorClasses.list);\n /*jshint -W116*/\n if (fileListNode == null) {\n throw new Error(\"Could not find the file list container in the template!\");\n }\n\n fileListEl = fileListNode.children[0].cloneNode(true);\n fileListNode.innerHTML = \"\";\n\n // We must call `createElement` in IE8 in order to target and hide any via CSS\n if (tempTemplateEl.getElementsByTagName(\"DIALOG\").length) {\n document.createElement(\"dialog\");\n }\n\n log(\"Template parsing complete\");\n\n return {\n template: tempTemplateEl,\n fileTemplate: fileListEl\n };\n },\n\n prependFile = function(el, index, fileList) {\n var parentEl = fileList,\n beforeEl = parentEl.firstChild;\n\n if (index > 0) {\n beforeEl = qq(parentEl).children()[index].nextSibling;\n\n }\n\n parentEl.insertBefore(el, beforeEl);\n },\n\n processNewQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n optFileOrBlob = queuedThumbRequest.optFileOrBlob,\n relatedThumbnailId = optFileOrBlob && optFileOrBlob.qqThumbnailId,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n maxSize: thumbnailMaxSize,\n orient: true,\n scale: true\n };\n\n if (qq.supportedFeatures.imagePreviews) {\n if (thumbnail) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n displayWaitingImg(thumbnail).done(function() {\n previewGeneration[id] = new qq.Promise();\n\n previewGeneration[id].done(function() {\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n });\n\n /* jshint eqnull: true */\n // If we've already generated an for this file, use the one that exists,\n // don't waste resources generating a new one.\n if (relatedThumbnailId != null) {\n useCachedPreview(id, relatedThumbnailId);\n }\n else {\n generateNewPreview(id, optFileOrBlob, spec);\n }\n });\n }\n }\n // File element in template may have been removed, so move on to next item in queue\n else {\n generateNextQueuedPreview();\n }\n }\n else if (thumbnail) {\n displayWaitingImg(thumbnail);\n generateNextQueuedPreview();\n }\n },\n\n processUpdateQueuedPreviewRequest = function(queuedThumbRequest) {\n var id = queuedThumbRequest.id,\n thumbnailUrl = queuedThumbRequest.thumbnailUrl,\n showWaitingImg = queuedThumbRequest.showWaitingImg,\n thumbnail = getThumbnail(id),\n spec = {\n customResizeFunction: queuedThumbRequest.customResizeFunction,\n scale: serverScale,\n maxSize: thumbnailMaxSize\n };\n\n if (thumbnail) {\n if (thumbnailUrl) {\n if (options.limits.maxThumbs && options.limits.maxThumbs <= generatedThumbnails) {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n else {\n if (showWaitingImg) {\n displayWaitingImg(thumbnail);\n }\n\n return options.imageGenerator.generate(thumbnailUrl, thumbnail, spec).then(\n function() {\n show(thumbnail);\n generatedThumbnails++;\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n },\n\n function() {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n setTimeout(generateNextQueuedPreview, options.limits.timeBetweenThumbs);\n }\n );\n }\n }\n else {\n maybeSetDisplayNotAvailableImg(id, thumbnail);\n generateNextQueuedPreview();\n }\n }\n },\n\n setProgressBarWidth = function(id, percent) {\n var bar = getProgress(id),\n /* jshint eqnull:true */\n progressBarSelector = id == null ? selectorClasses.totalProgressBar : selectorClasses.progressBar;\n\n if (bar && !qq(bar).hasClass(progressBarSelector)) {\n bar = qq(bar).getFirstByClass(progressBarSelector);\n }\n\n if (bar) {\n qq(bar).css({width: percent + \"%\"});\n bar.setAttribute(\"aria-valuenow\", percent);\n }\n },\n\n show = function(el) {\n el && qq(el).removeClass(options.classes.hide);\n },\n\n useCachedPreview = function(targetThumbnailId, cachedThumbnailId) {\n var targetThumbnail = getThumbnail(targetThumbnailId),\n cachedThumbnail = getThumbnail(cachedThumbnailId);\n\n log(qq.format(\"ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.\", targetThumbnailId, cachedThumbnailId, cachedThumbnailId));\n\n // Generation of the related thumbnail may still be in progress, so, wait until it is done.\n previewGeneration[cachedThumbnailId].then(function() {\n generatedThumbnails++;\n previewGeneration[targetThumbnailId].success();\n log(qq.format(\"Now using previously generated thumbnail created for ID {} on ID {}.\", cachedThumbnailId, targetThumbnailId));\n targetThumbnail.src = cachedThumbnail.src;\n show(targetThumbnail);\n },\n function() {\n previewGeneration[targetThumbnailId].failure();\n if (!options.placeholders.waitUntilUpdate) {\n maybeSetDisplayNotAvailableImg(targetThumbnailId, targetThumbnail);\n }\n });\n };\n\n qq.extend(options, spec);\n log = options.log;\n\n // No need to worry about conserving CPU or memory on older browsers,\n // since there is no ability to preview, and thumbnail display is primitive and quick.\n if (!qq.supportedFeatures.imagePreviews) {\n options.limits.timeBetweenThumbs = 0;\n options.limits.maxThumbs = 0;\n }\n\n container = options.containerEl;\n showThumbnails = options.imageGenerator !== undefined;\n templateDom = parseAndGetTemplate();\n\n cacheThumbnailPlaceholders();\n\n qq.extend(this, {\n render: function() {\n log(\"Rendering template in DOM.\");\n\n generatedThumbnails = 0;\n\n container.appendChild(templateDom.template.cloneNode(true));\n hide(getDropProcessing());\n this.hideTotalProgress();\n fileList = options.fileContainerEl || getTemplateEl(container, selectorClasses.list);\n\n log(\"Template rendering complete\");\n },\n\n renderFailure: function(message) {\n var cantRenderEl = qq.toElement(message);\n container.innerHTML = \"\";\n container.appendChild(cantRenderEl);\n },\n\n reset: function() {\n container.innerHTML = \"\";\n this.render();\n },\n\n clearFiles: function() {\n fileList.innerHTML = \"\";\n },\n\n disableCancel: function() {\n isCancelDisabled = true;\n },\n\n addFile: function(id, name, prependInfo, hideForever, batch) {\n var fileEl = templateDom.fileTemplate.cloneNode(true),\n fileNameEl = getTemplateEl(fileEl, selectorClasses.file),\n uploaderEl = getTemplateEl(container, selectorClasses.uploader),\n fileContainer = batch ? fileBatch.content : fileList,\n thumb;\n\n if (batch) {\n fileBatch.map[id] = fileEl;\n }\n\n qq(fileEl).addClass(FILE_CLASS_PREFIX + id);\n uploaderEl.removeAttribute(DROPZPONE_TEXT_ATTR);\n\n if (fileNameEl) {\n qq(fileNameEl).setText(name);\n fileNameEl.setAttribute(\"title\", name);\n }\n\n fileEl.setAttribute(FILE_ID_ATTR, id);\n\n if (prependInfo) {\n prependFile(fileEl, prependInfo.index, fileContainer);\n }\n else {\n fileContainer.appendChild(fileEl);\n }\n\n if (hideForever) {\n fileEl.style.display = \"none\";\n qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);\n }\n else {\n hide(getProgress(id));\n hide(getSize(id));\n hide(getDelete(id));\n hide(getRetry(id));\n hide(getPause(id));\n hide(getContinue(id));\n\n if (isCancelDisabled) {\n this.hideCancel(id);\n }\n\n thumb = getThumbnail(id);\n if (thumb && !thumb.src) {\n cachedWaitingForThumbnailImg.then(function(waitingImg) {\n thumb.src = waitingImg.src;\n if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {\n qq(thumb).css({\n maxHeight: waitingImg.style.maxHeight,\n maxWidth: waitingImg.style.maxWidth\n });\n }\n\n show(thumb);\n });\n }\n }\n },\n\n addFileToCache: function(id, name, prependInfo, hideForever) {\n this.addFile(id, name, prependInfo, hideForever, true);\n },\n\n addCacheToDom: function() {\n fileList.appendChild(fileBatch.content);\n fileBatch.content = document.createDocumentFragment();\n fileBatch.map = {};\n },\n\n removeFile: function(id) {\n qq(getFile(id)).remove();\n },\n\n getFileId: function(el) {\n var currentNode = el;\n\n if (currentNode) {\n /*jshint -W116*/\n while (currentNode.getAttribute(FILE_ID_ATTR) == null) {\n currentNode = currentNode.parentNode;\n }\n\n return parseInt(currentNode.getAttribute(FILE_ID_ATTR));\n }\n },\n\n getFileList: function() {\n return fileList;\n },\n\n markFilenameEditable: function(id) {\n var filename = getFilename(id);\n\n filename && qq(filename).addClass(options.classes.editable);\n },\n\n updateFilename: function(id, name) {\n var filenameEl = getFilename(id);\n\n if (filenameEl) {\n qq(filenameEl).setText(name);\n filenameEl.setAttribute(\"title\", name);\n }\n },\n\n hideFilename: function(id) {\n hide(getFilename(id));\n },\n\n showFilename: function(id) {\n show(getFilename(id));\n },\n\n isFileName: function(el) {\n return qq(el).hasClass(selectorClasses.file);\n },\n\n getButton: function() {\n return options.button || getTemplateEl(container, selectorClasses.button);\n },\n\n hideDropProcessing: function() {\n hide(getDropProcessing());\n },\n\n showDropProcessing: function() {\n show(getDropProcessing());\n },\n\n getDropZone: function() {\n return getTemplateEl(container, selectorClasses.drop);\n },\n\n isEditFilenamePossible: function() {\n return isEditElementsExist;\n },\n\n hideRetry: function(id) {\n hide(getRetry(id));\n },\n\n isRetryPossible: function() {\n return isRetryElementExist;\n },\n\n showRetry: function(id) {\n show(getRetry(id));\n },\n\n getFileContainer: function(id) {\n return getFile(id);\n },\n\n showEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).addClass(options.classes.editable);\n },\n\n isHiddenForever: function(id) {\n return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);\n },\n\n hideEditIcon: function(id) {\n var icon = getEditIcon(id);\n\n icon && qq(icon).removeClass(options.classes.editable);\n },\n\n isEditIcon: function(el) {\n return qq(el).hasClass(selectorClasses.editNameIcon, true);\n },\n\n getEditInput: function(id) {\n return getTemplateEl(getFile(id), selectorClasses.editFilenameInput);\n },\n\n isEditInput: function(el) {\n return qq(el).hasClass(selectorClasses.editFilenameInput, true);\n },\n\n updateProgress: function(id, loaded, total) {\n var bar = getProgress(id),\n percent;\n\n if (bar && total > 0) {\n percent = Math.round(loaded / total * 100);\n\n if (percent === 100) {\n hide(bar);\n }\n else {\n show(bar);\n }\n\n setProgressBarWidth(id, percent);\n }\n },\n\n updateTotalProgress: function(loaded, total) {\n this.updateProgress(null, loaded, total);\n },\n\n hideProgress: function(id) {\n var bar = getProgress(id);\n\n bar && hide(bar);\n },\n\n hideTotalProgress: function() {\n this.hideProgress();\n },\n\n resetProgress: function(id) {\n setProgressBarWidth(id, 0);\n this.hideTotalProgress(id);\n },\n\n resetTotalProgress: function() {\n this.resetProgress();\n },\n\n showCancel: function(id) {\n if (!isCancelDisabled) {\n var cancel = getCancel(id);\n\n cancel && qq(cancel).removeClass(options.classes.hide);\n }\n },\n\n hideCancel: function(id) {\n hide(getCancel(id));\n },\n\n isCancel: function(el) {\n return qq(el).hasClass(selectorClasses.cancel, true);\n },\n\n allowPause: function(id) {\n show(getPause(id));\n hide(getContinue(id));\n },\n\n uploadPaused: function(id) {\n this.setStatusText(id, options.text.paused);\n this.allowContinueButton(id);\n hide(getSpinner(id));\n },\n\n hidePause: function(id) {\n hide(getPause(id));\n },\n\n isPause: function(el) {\n return qq(el).hasClass(selectorClasses.pause, true);\n },\n\n isContinueButton: function(el) {\n return qq(el).hasClass(selectorClasses.continueButton, true);\n },\n\n allowContinueButton: function(id) {\n show(getContinue(id));\n hide(getPause(id));\n },\n\n uploadContinued: function(id) {\n this.setStatusText(id, \"\");\n this.allowPause(id);\n show(getSpinner(id));\n },\n\n showDeleteButton: function(id) {\n show(getDelete(id));\n },\n\n hideDeleteButton: function(id) {\n hide(getDelete(id));\n },\n\n isDeleteButton: function(el) {\n return qq(el).hasClass(selectorClasses.deleteButton, true);\n },\n\n isRetry: function(el) {\n return qq(el).hasClass(selectorClasses.retry, true);\n },\n\n updateSize: function(id, text) {\n var size = getSize(id);\n\n if (size) {\n show(size);\n qq(size).setText(text);\n }\n },\n\n setStatusText: function(id, text) {\n var textEl = getTemplateEl(getFile(id), selectorClasses.statusText);\n\n if (textEl) {\n /*jshint -W116*/\n if (text == null) {\n qq(textEl).clearText();\n }\n else {\n qq(textEl).setText(text);\n }\n }\n },\n\n hideSpinner: function(id) {\n qq(getFile(id)).removeClass(IN_PROGRESS_CLASS);\n hide(getSpinner(id));\n },\n\n showSpinner: function(id) {\n qq(getFile(id)).addClass(IN_PROGRESS_CLASS);\n show(getSpinner(id));\n },\n\n generatePreview: function(id, optFileOrBlob, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({id: id, customResizeFunction: customResizeFunction, optFileOrBlob: optFileOrBlob});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n updateThumbnail: function(id, thumbnailUrl, showWaitingImg, customResizeFunction) {\n if (!this.isHiddenForever(id)) {\n thumbGenerationQueue.push({customResizeFunction: customResizeFunction, update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});\n !thumbnailQueueMonitorRunning && generateNextQueuedPreview();\n }\n },\n\n hasDialog: function(type) {\n return qq.supportedFeatures.dialogElement && !!getDialog(type);\n },\n\n showDialog: function(type, message, defaultValue) {\n var dialog = getDialog(type),\n messageEl = getTemplateEl(dialog, selectorClasses.dialogMessage),\n inputEl = dialog.getElementsByTagName(\"INPUT\")[0],\n cancelBtn = getTemplateEl(dialog, selectorClasses.dialogCancelButton),\n okBtn = getTemplateEl(dialog, selectorClasses.dialogOkButton),\n promise = new qq.Promise(),\n\n closeHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.removeEventListener(\"click\", okClickHandler);\n promise.failure();\n },\n\n cancelClickHandler = function() {\n cancelBtn.removeEventListener(\"click\", cancelClickHandler);\n dialog.close();\n },\n\n okClickHandler = function() {\n dialog.removeEventListener(\"close\", closeHandler);\n okBtn.removeEventListener(\"click\", okClickHandler);\n dialog.close();\n\n promise.success(inputEl && inputEl.value);\n };\n\n dialog.addEventListener(\"close\", closeHandler);\n cancelBtn.addEventListener(\"click\", cancelClickHandler);\n okBtn && okBtn.addEventListener(\"click\", okClickHandler);\n\n if (inputEl) {\n inputEl.value = defaultValue;\n }\n messageEl.textContent = message;\n\n dialog.showModal();\n\n return promise;\n }\n });\n};\n","/*globals qq */\n// Base handler for UI (FineUploader mode) events.\n// Some more specific handlers inherit from this one.\nqq.UiEventHandler = function(s, protectedApi) {\n \"use strict\";\n\n var disposer = new qq.DisposeSupport(),\n spec = {\n eventType: \"click\",\n attachTo: null,\n onHandled: function(target, event) {}\n };\n\n // This makes up the \"public\" API methods that will be accessible\n // to instances constructing a base or child handler\n qq.extend(this, {\n addHandler: function(element) {\n addHandler(element);\n },\n\n dispose: function() {\n disposer.dispose();\n }\n });\n\n function addHandler(element) {\n disposer.attach(element, spec.eventType, function(event) {\n // Only in IE: the `event` is a property of the `window`.\n event = event || window.event;\n\n // On older browsers, we must check the `srcElement` instead of the `target`.\n var target = event.target || event.srcElement;\n\n spec.onHandled(target, event);\n });\n }\n\n // These make up the \"protected\" API methods that children of this base handler will utilize.\n qq.extend(protectedApi, {\n getFileIdFromItem: function(item) {\n return item.qqFileId;\n },\n\n getDisposeSupport: function() {\n return disposer;\n }\n });\n\n qq.extend(spec, s);\n\n if (spec.attachTo) {\n addHandler(spec.attachTo);\n }\n};\n","/* global qq */\nqq.FileButtonsClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n onDeleteFile: function(fileId) {},\n onCancel: function(fileId) {},\n onRetry: function(fileId) {},\n onPause: function(fileId) {},\n onContinue: function(fileId) {},\n onGetName: function(fileId) {}\n },\n buttonHandlers = {\n cancel: function(id) { spec.onCancel(id); },\n retry: function(id) { spec.onRetry(id); },\n deleteButton: function(id) { spec.onDeleteFile(id); },\n pause: function(id) { spec.onPause(id); },\n continueButton: function(id) { spec.onContinue(id); }\n };\n\n function examineEvent(target, event) {\n qq.each(buttonHandlers, function(buttonType, handler) {\n var firstLetterCapButtonType = buttonType.charAt(0).toUpperCase() + buttonType.slice(1),\n fileId;\n\n if (spec.templating[\"is\" + firstLetterCapButtonType](target)) {\n fileId = spec.templating.getFileId(target);\n qq.preventDefault(event);\n spec.log(qq.format(\"Detected valid file button click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n handler(fileId);\n return false;\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect click events on filename display elements.\nqq.FilenameClickHandler = function(s) {\n \"use strict\";\n\n var inheritedInternalApi = {},\n spec = {\n templating: null,\n log: function(message, lvl) {},\n classes: {\n file: \"qq-upload-file\",\n editNameIcon: \"qq-edit-filename-icon\"\n },\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {}\n };\n\n qq.extend(spec, s);\n\n // This will be called by the parent handler when a `click` event is received on the list element.\n function examineEvent(target, event) {\n if (spec.templating.isFileName(target) || spec.templating.isEditIcon(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n // We only allow users to change filenames of files that have been submitted but not yet uploaded.\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename click event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n qq.preventDefault(event);\n\n inheritedInternalApi.handleFilenameEdit(fileId, target, true);\n }\n }\n }\n\n spec.eventType = \"click\";\n spec.onHandled = examineEvent;\n\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n// Child of FilenameEditHandler. Used to detect focusin events on file edit input elements.\nqq.FilenameInputFocusInHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n onGetUploadStatus: function(fileId) {},\n log: function(message, lvl) {}\n };\n\n if (!inheritedInternalApi) {\n inheritedInternalApi = {};\n }\n\n // This will be called by the parent handler when a `focusin` event is received on the list element.\n function handleInputFocus(target, event) {\n if (spec.templating.isEditInput(target)) {\n var fileId = spec.templating.getFileId(target),\n status = spec.onGetUploadStatus(fileId);\n\n if (status === qq.status.SUBMITTED) {\n spec.log(qq.format(\"Detected valid filename input focus event on file '{}', ID: {}.\", spec.onGetName(fileId), fileId));\n inheritedInternalApi.handleFilenameEdit(fileId, target);\n }\n }\n }\n\n spec.eventType = \"focusin\";\n spec.onHandled = handleInputFocus;\n\n qq.extend(spec, s);\n qq.extend(this, new qq.FilenameEditHandler(spec, inheritedInternalApi));\n};\n","/*globals qq */\n/**\n * Child of FilenameInputFocusInHandler. Used to detect focus events on file edit input elements. This child module is only\n * needed for UAs that do not support the focusin event. Currently, only Firefox lacks this event.\n *\n * @param spec Overrides for default specifications\n */\nqq.FilenameInputFocusHandler = function(spec) {\n \"use strict\";\n\n spec.eventType = \"focus\";\n spec.attachTo = null;\n\n qq.extend(this, new qq.FilenameInputFocusInHandler(spec, {}));\n};\n","/*globals qq */\n// Handles edit-related events on a file item (FineUploader mode). This is meant to be a parent handler.\n// Children will delegate to this handler when specific edit-related actions are detected.\nqq.FilenameEditHandler = function(s, inheritedInternalApi) {\n \"use strict\";\n\n var spec = {\n templating: null,\n log: function(message, lvl) {},\n onGetUploadStatus: function(fileId) {},\n onGetName: function(fileId) {},\n onSetName: function(fileId, newName) {},\n onEditingStatusChange: function(fileId, isEditing) {}\n };\n\n function getFilenameSansExtension(fileId) {\n var filenameSansExt = spec.onGetName(fileId),\n extIdx = filenameSansExt.lastIndexOf(\".\");\n\n if (extIdx > 0) {\n filenameSansExt = filenameSansExt.substr(0, extIdx);\n }\n\n return filenameSansExt;\n }\n\n function getOriginalExtension(fileId) {\n var origName = spec.onGetName(fileId);\n return qq.getExtension(origName);\n }\n\n // Callback iff the name has been changed\n function handleNameUpdate(newFilenameInputEl, fileId) {\n var newName = newFilenameInputEl.value,\n origExtension;\n\n if (newName !== undefined && qq.trimStr(newName).length > 0) {\n origExtension = getOriginalExtension(fileId);\n\n if (origExtension !== undefined) {\n newName = newName + \".\" + origExtension;\n }\n\n spec.onSetName(fileId, newName);\n }\n\n spec.onEditingStatusChange(fileId, false);\n }\n\n // The name has been updated if the filename edit input loses focus.\n function registerInputBlurHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"blur\", function() {\n handleNameUpdate(inputEl, fileId);\n });\n }\n\n // The name has been updated if the user presses enter.\n function registerInputEnterKeyHandler(inputEl, fileId) {\n inheritedInternalApi.getDisposeSupport().attach(inputEl, \"keyup\", function(event) {\n\n var code = event.keyCode || event.which;\n\n if (code === 13) {\n handleNameUpdate(inputEl, fileId);\n }\n });\n }\n\n qq.extend(spec, s);\n\n spec.attachTo = spec.templating.getFileList();\n\n qq.extend(this, new qq.UiEventHandler(spec, inheritedInternalApi));\n\n qq.extend(inheritedInternalApi, {\n handleFilenameEdit: function(id, target, focusInput) {\n var newFilenameInputEl = spec.templating.getEditInput(id);\n\n spec.onEditingStatusChange(id, true);\n\n newFilenameInputEl.value = getFilenameSansExtension(id);\n\n if (focusInput) {\n newFilenameInputEl.focus();\n }\n\n registerInputBlurHandler(newFilenameInputEl, id);\n registerInputEnterKeyHandler(newFilenameInputEl, id);\n }\n });\n};\n"]} \ No newline at end of file diff --git a/utils/schedulercli.php b/utils/schedulercli.php index 1a548d172..ca7711842 100644 --- a/utils/schedulercli.php +++ b/utils/schedulercli.php @@ -68,16 +68,21 @@ $scheduler = new SeedDMS_Scheduler($db); $tasks = $scheduler->getTasks(); foreach($tasks as $task) { - if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { switch($mode) { case "run": if(method_exists($taskobj, 'execute')) { if(!$task->getDisabled()) { - if($taskobj->execute($task, $dms)) { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); - $task->updateLastNextRun(); + if($user = $dms->getUserByLogin('cli_scheduler')) { + if($taskobj->execute($task, $dms, $user)) { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful."); + $task->updateLastNextRun(); + } else { + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + $task->setDisabled(1); + } } else { - add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR); + add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed because of missing user 'cli_scheduler'. Task has been disabled.", PEAR_LOG_ERR); $task->setDisabled(1); } } diff --git a/views/bootstrap/class.AddDocument.php b/views/bootstrap/class.AddDocument.php index c0857ba27..cae6d1c3b 100644 --- a/views/bootstrap/class.AddDocument.php +++ b/views/bootstrap/class.AddDocument.php @@ -41,7 +41,7 @@ class SeedDMS_View_AddDocument extends SeedDMS_Bootstrap_Style { header('Content-Type: application/javascript; charset=UTF-8'); if($enablelargefileupload) { - $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload); + $this->printFineUploaderJs('../op/op.UploadChunks.php', $partitionsize, $maxuploadsize, $enablemultiupload, 'userfile', 'adddocform'); } ?> $(document).ready(function() { @@ -158,6 +158,7 @@ $(document).ready(function() { $folder = $this->params['folder']; $enablelargefileupload = $this->params['enablelargefileupload']; $enablemultiupload = $this->params['enablemultiupload']; + $maxuploadsize = $this->params['maxuploadsize']; $enableadminrevapp = $this->params['enableadminrevapp']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableselfrevapp = $this->params['enableselfrevapp']; @@ -188,7 +189,11 @@ $(document).ready(function() { $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true), "view_folder", $folder); - $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); $this->warningMsg($msg); $this->contentHeading(getMLText("add_document")); diff --git a/views/bootstrap/class.AddFile.php b/views/bootstrap/class.AddFile.php index 8797bdbf4..114c2aa7b 100644 --- a/views/bootstrap/class.AddFile.php +++ b/views/bootstrap/class.AddFile.php @@ -126,6 +126,7 @@ $(document).ready( function() { $document = $this->params['document']; $strictformcheck = $this->params['strictformcheck']; $enablelargefileupload = $this->params['enablelargefileupload']; + $maxuploadsize = $this->params['maxuploadsize']; $this->htmlAddHeader(''."\n", 'js'); if($enablelargefileupload) { @@ -139,16 +140,13 @@ $(document).ready( function() { $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); $this->contentHeading(getMLText("linked_files")); -?> - - -'.getMLText('link_alt_updatedocument').'', "out.AddFile2.php?documentid=".$document->getId()); - } -?> - -warningMsg($msg); + $this->contentContainerStart(); ?> diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a52ea338..8353b281c 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -39,6 +39,7 @@ class SeedDMS_View_AttributeMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selattrdef = $this->params['selattrdef']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index bac5b7237..e058627c8 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -464,7 +464,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if($this->params['enableclipboard']) { echo " "; - echo " "; + echo " getID() : 0)."\">"; echo " "; } @@ -2092,12 +2092,14 @@ $(function() { * @param array clipboard */ function printClipboard($clipboard, $previewer){ /* {{{ */ - $this->contentHeading(getMLText("clipboard"), true); + echo "\n"; + $this->contentHeading(getMLText("clipboard").'', true); echo "\n"; ?> \n"; + echo "\n"; } /* }}} */ /** @@ -3047,7 +3049,7 @@ $('body').on('click', '[id^=\"table-row-folder\"] td:nth-child(2)', function(ev) * @param integer $maxfiles maximum number of files allowed to upload * @param array $fields list of post fields */ - function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile') { /* {{{ */ + function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */ ?> $(document).ready(function() { uploader = new qq.FineUploader({ @@ -3086,7 +3088,7 @@ $(document).ready(function() { $('#-fine-uploader-names').val(names.join(';')); /* Run upload only if all files could be uploaded */ if(succeeded.length > 0 && failed.length == 0) - document.getElementById('form1').submit(); + document.getElementById('= $formname ?>').submit(); }, onError: function(id, name, reason, xhr) { noty({ diff --git a/views/bootstrap/class.Categories.php b/views/bootstrap/class.Categories.php index c563fa74f..d6553ba45 100644 --- a/views/bootstrap/class.Categories.php +++ b/views/bootstrap/class.Categories.php @@ -39,6 +39,7 @@ class SeedDMS_View_Categories extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ $selcat = $this->params['selcategory']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready( function() { $( "#selector" ).change(function() { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 136431e21..053b3df1e 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -57,15 +57,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $content .= " \n"; foreach($clipboard['folders'] as $folderid) { if($folder = $this->params['dms']->getFolder($folderid)) - $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; + $content .= " getID()."\" class=\"table-row-folder droptarget\" data-droptarget=\"folder_".$folder->getID()."\" rel=\"folder_".$folder->getID()."\" data-name=\"".htmlspecialchars($folder->getName(), ENT_QUOTES)."\" data-uploadformtoken=\"".createFormKey('')."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($folder->getName())."\n"; } foreach($clipboard['docs'] as $docid) { if($document = $this->params['dms']->getDocument($docid)) - $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\"> ".htmlspecialchars($document->getName())."\n"; + $content .= " getID()."\" class=\"table-row-document droptarget\" data-droptarget=\"document_".$document->getID()."\" rel=\"document_".$document->getID()."\" data-name=\"".htmlspecialchars($document->getName(), ENT_QUOTES)."\" formtoken=\"".createFormKey('')."\"> ".htmlspecialchars($document->getName())."\n"; } $content .= " \n"; if(isset($this->params['folder']) && $this->params['folder']->getAccessMode($this->params['user']) >= M_READWRITE) { - $content .= " params['folder']->getID()."&refferer=".urlencode($this->params['refferer'])."\">".getMLText("move_clipboard")."\n"; + $content .= " params['folder']->getID()."&refferer=".urlencode('../out/out.ViewFolder.php?folderid='.$this->params['folder']->getID())."\">".getMLText("move_clipboard")."\n"; } // $content .= " params['refferer'])."\">".getMLText("clear_clipboard")."kkk \n"; // $content .= " ".getMLText("clear_clipboard")."\n"; @@ -181,6 +181,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $content = ''; + $txt = $this->callHook('preClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; $foldercount = $doccount = 0; if($clipboard['folders']) { foreach($clipboard['folders'] as $folderid) { @@ -223,6 +226,9 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { } else { } $content .= "".getMLText("drag_icon_here").""; + $txt = $this->callHook('postClipboard', $clipboard); + if(is_string($txt)) + $content .= $txt; echo $content; } /* }}} */ diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index 66bd63507..a58366fc5 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -37,6 +37,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $pagetitle = $this->params['pagetitle']; $errormsg = $this->params['errormsg']; $plain = $this->params['plain']; + $showbutton = $this->hasParam('nobackbutton') === false || $this->getParam('nobackbutton') === false; $settings = $this->params['settings']; if(!$plain) { @@ -49,7 +50,8 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { print "".getMLText('error')."!"; print htmlspecialchars($errormsg); print ""; - print "".getMLText('back').""; + if($showbutton) + print "".getMLText('back').""; $this->contentEnd(); $this->htmlEndPage(); diff --git a/views/bootstrap/class.MyDocuments.php b/views/bootstrap/class.MyDocuments.php index a5cc83e5c..1bd5a13b9 100644 --- a/views/bootstrap/class.MyDocuments.php +++ b/views/bootstrap/class.MyDocuments.php @@ -38,6 +38,7 @@ class SeedDMS_View_MyDocuments extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printClickDocumentJs(); ?> $(document).ready( function() { @@ -116,6 +117,7 @@ $(document).ready( function() { $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; + $db = $dms->getDB(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); @@ -709,6 +711,8 @@ $(document).ready( function() { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.ReceiptSummary.php b/views/bootstrap/class.ReceiptSummary.php index 0176d30fe..5d8fc68ab 100644 --- a/views/bootstrap/class.ReceiptSummary.php +++ b/views/bootstrap/class.ReceiptSummary.php @@ -55,6 +55,8 @@ class SeedDMS_View_ReceiptSummary extends SeedDMS_Bootstrap_Style { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout); $previewer->setConverters($previewconverters); + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("my_documents")); $this->globalNavigation(); $this->contentStart(); diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php index c68f55abf..8cb227173 100644 --- a/views/bootstrap/class.SchedulerTaskMgr.php +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -44,6 +44,52 @@ $(document).ready( function() { $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); }); $('#listtasks.ajax').trigger('update', {}); + + $('body').on('click', '.removetask', function(ev){ + ev.preventDefault(); + ev.stopPropagation(); + id = $(ev.currentTarget).attr('rel'); + confirmmsg = $(ev.currentTarget).attr('confirmmsg'); + msg = $(ev.currentTarget).attr('msg'); + formtoken = '= createFormKey('removetask') ?>'; + bootbox.dialog(confirmmsg, [{ + "label" : " = getMLText("rm_task") ?>", + "class" : "btn-danger", + "callback": function() { + $.post('../op/op.SchedulerTaskMgr.php', + { action: 'removetask', taskid: id, formtoken: formtoken }, + function(data) { + if(data.success) { + $('#table-row-task-'+id).hide('slow'); + noty({ + text: msg, + type: 'success', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 1500, + }); + } else { + noty({ + text: data.message, + type: 'error', + dismissQueue: true, + layout: 'topRight', + theme: 'defaultTheme', + timeout: 3500, + }); + } + }, + 'json' + ); + } + }, { + "label" : "= getMLText("cancel") ?>", + "class" : "btn-cancel", + "callback": function() { + } + }]); + }); }); formField( + getMLText("task_".$extname."_".$taskname."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>false, + ) + ); + break; default: ?> @@ -125,6 +184,11 @@ $(document).ready( function() { $taskid = $this->params['taskid']; $task = $scheduler->getTask($taskid); + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + $this->errorMsg(getMLText('scheduler_extension_not_available')); + return; + } + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; ?> @@ -168,6 +232,19 @@ $(document).ready( function() { if($additionalparams = $taskobj->getAdditionalParams()) { foreach($additionalparams as $param) { switch($param['type']) { + case 'boolean': + $this->formField( + getMLText("task_".$task->getExtension()."_".$task->getTask()."_".$param['name']), + array( + 'element'=>'input', + 'type'=>'checkbox', + 'id'=>'params_'.$param['name'], + 'name'=>'params['.$param['name'].']', + 'value'=>'1', + 'checked'=>$task->getParameter($param['name']) == 1, + ) + ); + break; default: ?> @@ -218,7 +295,11 @@ $(document).ready( function() { print "\n"; print "\n"; foreach($tasks as $task) { - echo "getDisabled() ? " class=\"success\"" : "").">"; + if(!isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) + $class = 'error'; + else + $class = 'success'; + echo "getID()."\" class=\"".(!$task->getDisabled() ? " ".$class : "")."\">"; echo ""; echo $task->getExtension()."::".$task->getTask(); echo ""; @@ -237,9 +318,12 @@ $(document).ready( function() { echo ""; echo $task->getLastRun(); echo ""; - echo ""; + echo ""; print ""; - print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + print "getID()."\" msg=\"".getMLText('remove_task')."\" confirmmsg=\"".htmlspecialchars(getMLText("confirm_rm_task"), ENT_QUOTES)."\" title=\"".getMLText("remove_task")."\">"; + if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()])) { + print "getID()."\" href=\"../out/out.SchedulerTaskMgr.php?action=edittask\" title=\"".getMLText("edit_task")."\">"; + } print ""; echo ""; echo ""; @@ -254,6 +338,8 @@ $(document).ready( function() { $taskname = $this->params['taskname']; $scheduler = $this->params['scheduler']; + $this->htmlAddHeader(''."\n", 'js'); + $this->htmlStartPage(getMLText("admin_tools")); $this->globalNavigation(); $this->contentStart(); @@ -283,6 +369,7 @@ $(document).ready( function() { echo ""; echo ""; $params = $task->getAdditionalParams(); + $k = array(); foreach($params as $param) $k[] = $param['name']; echo implode(', ', $k); diff --git a/views/bootstrap/class.Timeline.php b/views/bootstrap/class.Timeline.php index b76de7b3c..29adc197b 100644 --- a/views/bootstrap/class.Timeline.php +++ b/views/bootstrap/class.Timeline.php @@ -144,6 +144,7 @@ class SeedDMS_View_Timeline extends SeedDMS_Bootstrap_Style { } header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); ?> $(document).ready(function () { $('#update').click(function(ev){ diff --git a/views/bootstrap/class.TransmittalMgr.php b/views/bootstrap/class.TransmittalMgr.php index d966a2f62..467566d28 100644 --- a/views/bootstrap/class.TransmittalMgr.php +++ b/views/bootstrap/class.TransmittalMgr.php @@ -32,15 +32,22 @@ require_once("class.Bootstrap.php"); class SeedDMS_View_TransmittalMgr extends SeedDMS_Bootstrap_Style { function js() { /* {{{ */ + $showtree = $this->params['showtree']; + $onepage = $this->params['onepage']; + header('Content-Type: application/javascript; charset=UTF-8'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); $this->printDeleteDocumentButtonJs(); $this->printDeleteItemButtonJs(); $this->printUpdateItemButtonJs(); + if($onepage) + $this->printClickDocumentJs(); ?> $(document).ready( function() { $('body').on('click', '.selecttransmittal', function(ev){ ev.preventDefault(); $('div.ajax').trigger('update', {transmittalid: $(ev.currentTarget).data('transmittalid')}); + window.history.pushState({"html":"","pageTitle":""},"", '../out/out.TransmittalMgr.php?transmittalid=' + $(ev.currentTarget).data('transmittalid')); }); }); getDocument(); $latestcontent = $document->getLatestContent(); if ($document->getAccessMode($user) >= M_READ) { - echo "getID()."\">"; +// echo "getID()."\">"; + echo $this->documentListRowStart($document); echo $this->documentListRow($document, $previewer, true, $content->getVersion()); echo ""; $this->printDeleteItemButton($item, getMLText('transmittalitem_removed')); if($latestcontent->getVersion() != $content->getVersion()) $this->printUpdateItemButton($item, getMLText('transmittalitem_updated', array('prevversion'=>$content->getVersion(), 'newversion'=>$latestcontent->getVersion()))); echo ""; - echo ""; + echo $this->documentListRowEnd($document); } } else { echo "getID()."\">"; diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 2446e3015..bee2baa79 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -212,6 +212,12 @@ console.log(element); } else { $msg = getMLText("max_upload_size").": ".ini_get( "upload_max_filesize"); } + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($maxuploadsize); + else + $msg = getMLText("max_upload_size").": ".SeedDMS_Core_File::format_filesize($mus2); + if(0 && $enablelargefileupload) { $msg .= "".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree()).""; } diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 124499bdd..2eb842405 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -192,6 +192,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $document = $this->params['document']; header('Content-Type: application/javascript'); + parent::jsTranslations(array('cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) @@ -1179,7 +1180,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { echo ""; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); - print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), $action->getName())."\" />"; + print "getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />"; $allowedtransitions[] = $transition; } echo ""; @@ -1731,7 +1732,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $targetDoc = $link->getTarget(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$targetDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($targetDoc); $targetDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $targetDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1746,7 +1747,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) print "".createHiddenFieldWithKey('removedocumentlink')."getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($targetDoc); } print "\n\n"; } @@ -1796,7 +1797,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { $responsibleUser = $link->getUser(); $sourceDoc = $link->getDocument(); - echo "getId()."\" class=\"table-row-document\" rel=\"document_".$sourceDoc->getId()."\" formtoken=\"".createFormKey('movedocument')."\" draggable=\"true\">"; + echo $this->documentListRowStart($sourceDoc); $sourceDoc->verifyLastestContentExpriry(); $txt = $this->callHook('documentListItem', $sourceDoc, $previewer, false, 'reverselinks'); if(is_string($txt)) @@ -1811,7 +1812,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { print "".getMLText("document_link_public").": ".(($link->isPublic()) ? getMLText("yes") : getMLText("no")); print "".createHiddenFieldWithKey('removedocumentlink')."getId()."\" />getID()."\" /> ".getMLText("delete").""; print ""; - print ""; + echo $this->documentListRowEnd($sourceDoc); } print "\n\n"; // $this->contentContainerEnd(); diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 2725ced0f..ce3f90b5c 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -109,6 +109,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { $expandFolderTree = $this->params['expandFolderTree']; $enableDropUpload = $this->params['enableDropUpload']; $maxItemsPerPage = $this->params['maxItemsPerPage']; + $maxuploadsize = $this->params['maxuploadsize']; $showtree = $this->params['showtree']; $onepage = $this->params['onepage']; $sitename = trim(strip_tags($this->params['sitename'])); @@ -214,7 +215,11 @@ $('body').on('click', '.order-btn', function(ev) { echo "SeedDMSUpload.setUrl('../op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('".getMLText("edit_document_props")."');"; - echo "SeedDMSUpload.setMaxFileSize(".SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")).");"; + $mus2 = SeedDMS_Core_File::parse_filesize(ini_get("upload_max_filesize")); + if($maxuploadsize && $maxuploadsize < $mus2) + echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);"; + else + echo "SeedDMSUpload.setMaxFileSize($mus2);"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; }
".sprintf(getMLText('link_alt_updatedocument'), "out.AddMultiDocument.php?folderid=".$folder->getID()."&showtree=".showtree())."